11

在下面的 GridBagLayout 代码中,我期望 JButton btn2 的指定最小大小在将 JFrame 调整为更小时得到遵守。但是当我使 JFrame 更小时,btn2 变得小于其最小尺寸然后消失。

有人可以指出我做错了什么的正确方向吗?也许我必须设置包含按钮的 JPanel 的最小尺寸?

任何帮助表示赞赏,谢谢!

    JFrame frame = new JFrame();
    frame.setSize(400,300);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    panel.setMinimumSize(new Dimension(400,300));
    panel.setBackground(Color.RED);

    panel.setLayout(new GridBagLayout());
    GridBagConstraints gbc = null;

    JButton btn1 = new JButton("btn1");
    btn1.setPreferredSize(new Dimension(150,50));
    btn1.setMinimumSize(new Dimension(150,50));
    gbc = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, 
            GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
            new Insets(0,0,0,0), 0, 0);
    panel.add(btn1, gbc);

    JButton btn2 = new JButton("btn2");
    btn2.setPreferredSize(new Dimension(150,150));
    btn2.setMinimumSize(new Dimension(150,150));
    gbc = new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, 
            GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
            new Insets(0,0,100,100), 0, 0);
    panel.add(btn2, gbc);

    frame.getContentPane().add(panel);
    frame.setVisible(true);
4

2 回答 2

8

除了安德鲁汤普森的回答:

  • 如果组件的首选尺寸能够并且将得到尊重,则 GBL 不会尊重组件上设置的最小尺寸。
  • 当组件的首选尺寸不能被尊重时,GBL 确实尊重组件上设置的最小尺寸,即:组件更喜欢尺寸为 (w,h) 但 GBL 认为这是不可能的,因为空间不足,因此它依赖于组件的广告最小尺寸。

因此,当您缩小包含框架的尺寸时,很有可能使您的组件突然变得比以前更大。您只需在其上设置大于首选尺寸的最小尺寸。所以你正在使框架更小,突然你的组件变得更大。那是......奇怪但可能:) 大家都欢呼GBL。

下面是一个实现此行为的面板示例(GBC 是一个比原始 GridBagConstraints 更易于使用的类):

private static JPanel getPanel() {

    JPanel panel = new JPanel(new GridBagLayout());

    final JTextField textField = new JTextField("test");
    final String text = "text";
    final JLabel label = new JLabel(text);
    final JButton button = new JButton(new AbstractAction("Enlarge label!") {
        private String actText = text; 
        @Override
        public void actionPerformed(ActionEvent arg0) {
            actText = actText + text;
            label.setText(actText);
        }
    });

    GBC g;

    g = new GBC().locate(0, 0).weight(0.0, 0.0).align(GBC.WEST, GBC.HORIZONTAL, null);
    textField.setMinimumSize(new Dimension(200,20));
    panel.add(textField, g);

    g = new GBC().locate(1, 0).weight(1.0, 0.0);
    panel.add(label, g);

    g = new GBC().locate(0, 1).weight(1.0, 1.0).span(2, 1);
    panel.add(button, g);


    return panel;
}

一般来说,我会说不要使用必须在 GBL 中固定大小的组件。用不同的布局管理器将它包裹在其他面板中。

如果您真的想在 GBL 中使用固定大小的组件,请覆盖其 getPreferredSize() 方法并返回您想要的大小。但我更愿意忽略这些方法。

于 2013-04-30T11:23:12.550 回答
4

也许我必须设置包含按钮的 JPanel 的最小尺寸?

AFAIR GBL 因忽略尺寸提示而臭名昭著。不,对此进行更正。要在 GBL 中合理调整组件大小,请使用GridBagConstraints具有适当值的 。但请注意,布局的行为不会显示任何将被强制小于其最小尺寸的组件。

我将pack()框架然后设置框架上的最小尺寸。这是它的外观,将最后一行更改为..

frame.pack();
frame.setVisible(true);
frame.setMinimumSize(frame.getSize());

不过,考虑到布局,我倾向于将其放入btn1面板的 中,然后将其添加到PAGE_START另一个BL 的中。 会进入外层BL的。BorderLayoutLINE_STARTbtn2CENTER

于 2012-08-21T03:36:57.100 回答