首页 文章

如何让GridBagLayout尊重按钮或面板的最小尺寸?

提问于
浏览
11

在下面的GridBagLayout代码中,我希望在调整JFrame的大小以使其更小时,可以遵守JButton btn2的指定最小大小 . 但是当我使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);

2 回答

  • 5

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

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

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

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

    考虑到布局,我倾向于将 btn1 放入面板 BorderLayoutPAGE_START 中,然后将其添加到另一个BL的 LINE_START 中 . btn2 将进入外部BL的 CENTER .

  • 9

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

    • 如果组件的首选大小能够并且将得到尊重,则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()方法并返回所需的大小 . 但我更愿意忽略这些方法 .

相关问题