【问题标题】:Getting rid of extra spaces between components when the JFrame is resized调整 JFrame 大小时消除组件之间的额外空格
【发布时间】:2018-02-04 22:27:18
【问题描述】:

我正在使用 GridBagLayout 将一些组件排列在一个框架中。
首次创建框架时,组件之间有适当的空间。

但是一旦我调整框架的大小,组件之间就会有很多不需要的空间

我尝试按照一些用户的建议调整权重和插图,但似乎无法解决问题

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JTextArea;

public class Frame1 extends JFrame {

    JLabel one = new JLabel("one");
    JLabel two = new JLabel("two");
    JLabel three = new JLabel("three");

    JTextField oneF = new JTextField(20);
    JTextField twoF = new JTextField(20);
    JTextField threeF = new JTextField(20);

    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("menu");

    GridBagConstraints c = new GridBagConstraints();

    public Frame1() {
        setTitle("GridBagLayout Test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new GridBagLayout());

        menuBar.add(menu);

        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = c.REMAINDER;
        c.fill = c.HORIZONTAL;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(menuBar, c);

        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 1;
        c.fill = c.NONE;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(one, c);

        c.gridx = 1;
        c.gridy = 1;
        c.gridwidth = 1;
        c.fill = c.NONE;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(oneF, c);

        c.gridx = 0;
        c.gridy = 2;
        c.gridwidth = 1;
        c.fill = c.NONE;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(two, c);

        c.gridx = 1;
        c.gridy = 2;
        c.gridwidth = 1;
        c.fill = c.NONE;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(twoF, c);

        c.gridx = 0;
        c.gridy = 3;
        c.gridwidth = 1;
        c.fill = c.NONE;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(three, c);

        c.gridx = 1;
        c.gridy = 3;
        c.gridwidth = 1;
        c.fill = c.NONE;
        c.gridheight = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.anchor = c.NORTH;
        c.insets = new Insets(5,5,5,5);
        add(threeF, c);

       //setResizable(false);
       pack();
       setVisible(true);
    }

}

ps:- 我是 GUI 编程新手,所以请原谅我的任何菜鸟错误。

编辑1:这是我完成后想要的。我知道目前它看起来并不接近我的想法......我仍在努力

谢谢

【问题讨论】:

  • 以最小尺寸提供 ASCII 艺术或 GUI 的预期布局的简单绘图,并具有更大的宽度和高度。

标签: java swing layout-manager gridbaglayout


【解决方案1】:
  • 使用嵌套布局(几个LayoutManagers的组合),你的图跟我说,

  • 您仍然可以将GridBagLayout 用于放置在左侧的组件,

  • 在我的代码中(尽可能简单的想法)JComponents 放置在左侧不能调整大小,因为受到 LayoutManager 的默认值的限制,更多在 Oracle tutorial

.

.

由 SSCCE/MCVE 绘制

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyFrame {

    private static final long serialVersionUID = 1L;
    private JFrame myFrame = new JFrame("Whatever");
    private JPanel parentPanel = new JPanel(new BorderLayout(10, 10)) {

        private static final long serialVersionUID = 1L;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 400);
        }

        @Override
        public Color getBackground() {
            return new Color(255, 000, 000);
        }
    };
    private JPanel leftPanel = new JPanel(/*default is FlowLayout*/) {

                private static final long serialVersionUID = 1L;

                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(300, 400);
                }

                @Override
                public Color getBackground() {
                    return new Color(255, 255, 000);
                }
            };
    private JPanel leftChildPanel = new JPanel() {

        private static final long serialVersionUID = 1L;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 400);
        }

        @Override
        public Color getBackground() {
            return new Color(255, 255, 225);
        }
    };
    private JPanel rightPanel = new JPanel(new BorderLayout(10, 10)) {

        private static final long serialVersionUID = 1L;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 380);
        }

        @Override
        public Color getBackground() {
            return new Color(000, 255, 225);
        }
    };

    public MyFrame() {
        parentPanel.add(leftPanel, BorderLayout.WEST);
        leftPanel.add(leftChildPanel);
        parentPanel.add(rightPanel);
        myFrame.add(parentPanel);
        myFrame.setLocation(150, 150);
        myFrame.pack();
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new MyFrame();
        });
    }
}

【讨论】:

  • 我刚刚尝试了您建议的方式,它修复了所有组件之间的垂直间距。但是,两列之间的间距比以前更宽(在面板中使用 GridBagLayout)。无论如何我可以解决这个问题吗?谢谢
  • JComponents 将其getPreferredSize 返回到容器(例如JPanel)并且LayoutManager 可以以不同的方式重新计算,例如在我的代码示例中,通过力@ 减少JPanels 维度987654335@
  • (对于newbee来说不太舒服)如果您只想使用一个JPanel,您必须使用自定义MigLayout,然后您可以设置各种方法
【解决方案2】:

这个想法是添加空行/列,这些空行/列将会增长以填充可用空间:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JTextField;

public class Frame1 extends JFrame {

    JLabel one = new JLabel("one");
    JLabel two = new JLabel("two");
    JLabel three = new JLabel("three");

    JTextField oneF = new JTextField(20);
    JTextField twoF = new JTextField(20);
    JTextField threeF = new JTextField(20);

    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("menu");

    public Frame1() {

        setTitle("GridBagLayout Test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.rowHeights = new int[]{0, 0, 0, 0}; //this defines 4 rows
        //make 2 last empty row grow 
        gridBagLayout.rowWeights = new double[]{0.0, 0.0, 1.0,1.0};

        //do the same for columns 
        gridBagLayout.columnWidths = new int[]{0, 0, 0, 0};
        gridBagLayout.columnWeights = new double[]{0.0, 0.0, 1.0,1.0};

        getContentPane().setLayout(gridBagLayout);

        menuBar.add(menu);

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 5;
        c.fill = c.HORIZONTAL;
        c.anchor = c.NORTH;
        c.insets = new Insets(5, 5, 5, 0);
        getContentPane().add(menuBar, c);

        //better have a new GridBagConstraints for each component added 
        GridBagConstraints c1 = new GridBagConstraints();
        c1.gridx = 0;
        c1.gridy = 1;
        c1.gridwidth = 1;
        c1.fill = c1.NONE;
        c1.anchor = c1.NORTH;
        c1.insets = new Insets(5, 5, 0, 5);
        getContentPane().add(one, c1);

        GridBagConstraints c2 = new GridBagConstraints();
        c2.gridx = 1;
        c2.gridy = 1;
        c2.fill = c2.NONE;
        c2.anchor = GridBagConstraints.NORTHWEST;
        c2.insets = new Insets(5, 5, 0, 5);
        getContentPane().add(oneF, c2);

        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new Frame1();
    }
}

编辑:回应您的编辑:为“封面艺术”使用额外的“成长”列

【讨论】:

  • 我刚刚运行了你的代码。我想我可以解决这个问题,但是您能否解释一下您在创建 gridBagLayout 后所做的工作。我很难理解你在那里做了什么。谢谢
  • 您是如何使组件无法调整大小并将它们设置在一个位置的?谢谢
  • 我添加了一些 cmets。希望对您有所帮助。
【解决方案3】:

问题在于您对c.weightxc.weighty 的分配。 weightx 和 weighty 确定当容器变得比容纳组件的首选大小所需的更大时,如何为 GridBagLayout 中的网格单元分配额外空间。

对于所有单元格的 weightx 和 weighty 应该为零,除了那些您希望在窗口变大时变大的单元格。

【讨论】:

    【解决方案4】:

    我不知道它应该是什么样子,但您可以尝试为文本字段设置标签 c.anchor=GridBagConstraints.EASTc.anchor=GridBagConstraints.WEST

    尝试同时设置c.fill = GridBadConstraints.BOTH

    【讨论】:

    • 即使调整框架大小,是否可以将所有组件设置在左上角?谢谢
    • 左上角是 c.anchor=GridBagConstraints.EAST
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多