java 如何让 GridBagLayout 遵守按钮或面板的最小尺寸?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12048047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:23:47  来源:igfitidea点击:

How to get GridBagLayout to respect minimum size of a button or panel?

javaswinglayout-managergridbaglayout

提问by

In the following GridBagLayout code, I'm expecting the specified minimum size of JButton btn2 to be respected when the JFrame is resized to be made smaller. But when I make the JFrame smaller, the btn2 gets smaller than its minimum size and then vanishes.

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

Can someone point me in the right direction of what I'm doing wrong? Maybe I have to set the minimum size of the JPanel that contains the buttons?

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

Any help is appreciated, thanks!

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

    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);

采纳答案by Andrew Thompson

Maybe I have to set the minimum size of the JPanel that contains the buttons?

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

AFAIR GBL was notorious for ignoring sizing hints. No, a correction on that. To get sensible resizing of components within GBL, use the GridBagConstraintswith appropriate values. Beware though, the behavior of the layout to not display any component that would be forced to less than its minimum size.

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

I would pack()the frame then set the minimum size on the frame. Here is how it might look, changing the last line to..

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

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

Given the layout though, I would tend to put btn1into the PAGE_STARTof the BorderLayoutof a panel that is then added to the LINE_STARTof another BL. btn2would go in the CENTERof the outer BL.

鉴于布局,虽然,我会倾向于把btn1PAGE_STARTBorderLayout那个,然后添加到面板的LINE_START另一BL的。 btn2将进入CENTER外部 BL。

回答by Timmos

In addition to Andrew Thompson's answer:

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

  • The GBL DOES NOT respect the minimum size set on a component if the component's preferred size can and will be respected.
  • The GBL DOES respect the minimum size set on a component when the component's preferred size cannot be respected, that is: the component prefers to be of size (w,h) but the GBL sees this is impossible due to lack of space, and therefore it falls back on the advertised minimum size of the component.
  • 如果组件的首选大小可以并且将会得到遵守,则 GBL 不遵守在组件上设置的最小大小。
  • 当组件的首选大小无法得到遵守时,GBL 确实遵守在组件上设置的最小大小,即:组件更喜欢大小为 (w,h) 但 GBL 认为这是不可能的,因为空间不足,因此它依赖于宣传的组件最小尺寸。

It is therefore very much possible to make your component suddenly become larger than it was before when you downsize the containing frame. You only have to set a minimum size on it that is larger than the preferred size. So you are making the frame smaller, and suddenly your component becomes larger. That is... weird but possible :) All hail GBL.

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

Here is an example of a panel that implements this behavior (GBC is an easier class to use than the original GridBagConstraints):

这是一个实现此行为的面板示例(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;
}

In general, I would say to not use components that must be fixed in size within a GBL. Wrap it inside other panels with different layout managers.

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

If you really want to use your fixed-sized component within a GBL, override its getPreferredSize() method and return the size you want. But I prefer to ignore these methods.

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