Java 调整窗口大小时GridBagLayout元素的行为

Java 调整窗口大小时GridBagLayout元素的行为,java,swing,layout-manager,gridbaglayout,Java,Swing,Layout Manager,Gridbaglayout,我对JavaSwing还不熟悉,并试图制作一个简单的布局(我想),但是我在实现我想要的行为时遇到了很多问题。这是我的密码: setSize(800, 600); setLocationRelativeTo(null); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); equipementPanel.setPrefer

我对JavaSwing还不熟悉,并试图制作一个简单的布局(我想),但是我在实现我想要的行为时遇到了很多问题。这是我的密码:

    setSize(800, 600);       
    setLocationRelativeTo(null);                     
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    equipementPanel.setPreferredSize(new Dimension(275, 300));
    grillePanel.setPreferredSize(new Dimension(300, 600));

    GridBagConstraints c = new GridBagConstraints();

    c.gridx = 0; c.gridy = 0;
    c.anchor = GridBagConstraints.NORTHWEST;
    c.gridwidth = 1; c.gridheight = 1;
    c.weightx = 0.0; c.weighty = 0.0;
    this.add(equipementPanel, c);

    c.fill = GridBagConstraints.BOTH;
    c.gridx = 0; c.gridy = 1;
    c.anchor = GridBagConstraints.SOUTHWEST;
    c.gridwidth = 1; c.gridheight = 2;
    c.weightx = 0.0; c.weighty = 0.0;
    this.add(informationPanel, c);

    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 1; c.gridy = 0;
    c.anchor = GridBagConstraints.NORTHEAST;
    c.weightx = 1.0; c.weighty = 1.0;
    this.add(grillePanel, c);

    c.fill = GridBagConstraints.BOTH;
    c.gridx = 1; c.gridy = 1;
    c.anchor = GridBagConstraints.SOUTHEAST;
    c.weightx = 1.0; c.weighty = 0.0;
    this.add(commandePanel, c);

    this.validate();
我的笔记本电脑的屏幕是我想要的一个很好的结果

  • 设备面板=绿色
  • 格栅板=灰色
  • 但在我更大的屏幕上…灰色的应该可以伸展。红色,没关系

    当我缩小尺寸时,这是一场彻底的灾难

    我想要它做的是
    灰色不应具有固定的高度和宽度。
    黄色应始终具有固定的高度而不是宽度。
    红色应该始终具有固定的宽度,而不是高度。 果岭应该始终都是固定的

    窗口可能变成的最小值将设置为绿色+黄色窗口的高度。和绿色的宽度+任何好的显示

    我知道小窗户的奇怪行为是因为我的首选尺寸低于300+600…但我需要在某个地方调整一些尺寸

    如果我能用另一个布局达到同样的效果,我很乐意尝试。如果我改变并使用一些滚动面板,这会改变什么吗

    我添加了一个mcve: MCVE.JAVA

    package mcve;
    import java.awt.EventQueue;
    public class MCVE {
     /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(() -> {
                mcve.gui.MainWindow mainWindow  = new mcve.gui.MainWindow();
                mainWindow.setVisible(true);
            });
        }
    }
    
    MainWindow.Java

    package mcve.gui;
    
    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JFrame;
    
    public class MainWindow extends JFrame 
    { 
        public MainWindow() 
        {
            this.setExtendedState(JFrame.MAXIMIZED_BOTH);
            this.setLayout(new GridBagLayout()); 
            initComponents();
        }
    
        private void initComponents() 
        {                             
            setSize(800, 600);       
            setLocationRelativeTo(null);                     
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
    
            GrillePanel grillePanel = new GrillePanel();
            CommandePanel commandePanel = new CommandePanel();
            InformationPanel informationPanel = new InformationPanel();
            EquipementPanel equipementPanel = new EquipementPanel();
    
            equipementPanel.setPreferredSize(new Dimension(275, 300));
            grillePanel.setPreferredSize(new Dimension(300, 600));
    
            GridBagConstraints c = new GridBagConstraints();
    
            c.gridx = 0; c.gridy = 0;
            c.anchor = GridBagConstraints.NORTHWEST;
            c.gridwidth = 1; c.gridheight = 1;
            c.weightx = 0.0; c.weighty = 0.0;
            this.add(equipementPanel, c);
    
            c.fill = GridBagConstraints.BOTH;
            c.gridx = 0; c.gridy = 1;
            c.anchor = GridBagConstraints.SOUTHWEST;
            c.gridwidth = 1; c.gridheight = 2;
            c.weightx = 0.0; c.weighty = 0.0;
            this.add(informationPanel, c);
    
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 1; c.gridy = 0;
            c.anchor = GridBagConstraints.NORTHEAST;
            c.weightx = 1.0; c.weighty = 1.0;
            this.add(grillePanel, c);
    
            c.fill = GridBagConstraints.BOTH;
            c.gridx = 1; c.gridy = 1;
            c.anchor = GridBagConstraints.SOUTHEAST;
            c.weightx = 1.0; c.weighty = 0.0;
            this.add(commandePanel, c);
    
            this.validate();
        }    
    }
    
    4面板

    package mcve.gui;
    
    import java.awt.Color;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    
    public class InformationPanel extends JPanel 
    {
        public InformationPanel()
        {
            setBackground(Color.red);
            setBorder(BorderFactory.createLineBorder(Color.black));
            setVisible(true);
        }
    
    }
    
    package mcve.gui;
    
    import java.awt.Color;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    
    public class GrillePanel extends JPanel
    {
        public GrillePanel()
        {
            setBackground(Color.lightGray);
            setBorder(BorderFactory.createLineBorder(Color.black));
            setVisible(true);
        }
    }
    
    package mcve.gui;
    
    import java.awt.Color;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    
    public class EquipementPanel extends JPanel 
    {
        public EquipementPanel()
        {
            setBackground(Color.green);
            setBorder(BorderFactory.createLineBorder(Color.black));
            setVisible(true);
        }
    
    }
    
    package mcve.gui;
    
    import java.awt.Color;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    
    public class CommandePanel extends JPanel 
    {
        public CommandePanel()
        {
            setBackground(Color.yellow);
            setBorder(BorderFactory.createLineBorder(Color.black));
            setVisible(true);
        }
    
    }
    

    Swing布局管理器相当不错,但不幸的是,他们会制造很多麻烦。我认为真正可用的布局管理器只有
    BorderLayout
    GroupLayout
    ,而且只有在某些情况下
    GridBayLayout
    。在大多数情况下,我发现它们是无用的


    为什么不尝试使用第三方布局管理器?从我的经验中,我可以看出塔尔不仅仅是伟大的。它非常灵活,具有良好的API。您将很快获得所需的布局组合。我在所有桌面项目中都使用它。

    Swing布局管理器相当不错,但不幸的是,它们会制造很多麻烦。我认为真正可用的布局管理器只有
    BorderLayout
    GroupLayout
    ,而且只有在某些情况下
    GridBayLayout
    。在大多数情况下,我发现它们是无用的


    为什么不尝试使用第三方布局管理器?从我的经验中,我可以看出塔尔不仅仅是伟大的。它非常灵活,具有良好的API。您将很快获得所需的布局组合。我在所有桌面项目中都使用它。

    有两个基本问题(在我看来)

    首先,您正试图在一个布局管理器中管理一个复杂的布局,这在最好的情况下是相当困难的

    第二,您似乎不明白当组件的可用大小降至首选大小以下时,布局管理器会做什么,也就是说,在
    GridBagLayout
    的情况下,恢复为其最小大小

    通过使用权重(
    weightx
    /
    weighty
    ),您可以克服其中的一些问题,但有时,您也需要为最小大小提供一个硬值

    在不知道确切需求的情况下(您需要决定哪些组件更重要),这是一个粗略的示例

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class LayoutTest {
    
        public static void main(String[] args) {
            new LayoutTest();
        }
    
        public LayoutTest() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JPanel greenPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(275, 300);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.GREEN;
                        }
    
                    };
                    JPanel redPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(300, 600);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.RED;
                        }
    
                    };
    
                    JPanel left = new JPanel(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridx = 0;
                    gbc.gridy = 0;
                    gbc.weightx = 1;
                    gbc.weighty = 0.25;
                    gbc.fill = GridBagConstraints.BOTH;
    
                    left.add(greenPane, gbc);
                    gbc.gridy++;
                    gbc.weighty = 0.75;
                    left.add(redPane, gbc);
    
                    JPanel yellowPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(600, 50);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.YELLOW;
                        }
    
                    };
    
                    JPanel grayPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(400, 600);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.GRAY;
                        }
    
                    };
    
                    JPanel center = new JPanel(new GridBagLayout());
                    gbc = new GridBagConstraints();
                    gbc.gridx = 0;
                    gbc.gridy = 0;
                    gbc.fill = GridBagConstraints.BOTH;
                    gbc.weightx = 1;
                    gbc.weighty = 1;
                    center.add(grayPane, gbc);
    
                    gbc.gridy++;
                    gbc.weighty = 0;
                    center.add(yellowPane, gbc);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(left, BorderLayout.WEST);
                    frame.add(center);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }
    


    有两个基本问题(在我看来)

    首先,您正试图在一个布局管理器中管理一个复杂的布局,这在最好的情况下是相当困难的

    第二,您似乎不明白当组件的可用大小降至首选大小以下时,布局管理器会做什么,也就是说,在
    GridBagLayout
    的情况下,恢复为其最小大小

    通过使用权重(
    weightx
    /
    weighty
    ),您可以克服其中的一些问题,但有时,您也需要为最小大小提供一个硬值

    在不知道确切需求的情况下(您需要决定哪些组件更重要),这是一个粗略的示例

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class LayoutTest {
    
        public static void main(String[] args) {
            new LayoutTest();
        }
    
        public LayoutTest() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JPanel greenPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(275, 300);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.GREEN;
                        }
    
                    };
                    JPanel redPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(300, 600);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.RED;
                        }
    
                    };
    
                    JPanel left = new JPanel(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridx = 0;
                    gbc.gridy = 0;
                    gbc.weightx = 1;
                    gbc.weighty = 0.25;
                    gbc.fill = GridBagConstraints.BOTH;
    
                    left.add(greenPane, gbc);
                    gbc.gridy++;
                    gbc.weighty = 0.75;
                    left.add(redPane, gbc);
    
                    JPanel yellowPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(600, 50);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.YELLOW;
                        }
    
                    };
    
                    JPanel grayPane = new JPanel() {
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(400, 600);
                        }
    
                        @Override
                        public Dimension getMinimumSize() {
                            return getPreferredSize();
                        }
    
                        @Override
                        public Color getBackground() {
                            return Color.GRAY;
                        }
    
                    };
    
                    JPanel center = new JPanel(new GridBagLayout());
                    gbc = new GridBagConstraints();
                    gbc.gridx = 0;
                    gbc.gridy = 0;
                    gbc.fill = GridBagConstraints.BOTH;
                    gbc.weightx = 1;
                    gbc.weighty = 1;
                    center.add(grayPane, gbc);
    
                    gbc.gridy++;
                    gbc.weighty = 0;
                    center.add(yellowPane, gbc);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(left, BorderLayout.WEST);
                    frame.add(center);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }
    


    为了更好的帮助,尽快发布一个(最小的完全可验证的例子)。为了更好地帮助,尽快发布一个(最小的完全可验证的例子)。考虑提供一个可运行的例子来解决MigLayout的OP问题,否则它只是销售间距(我知道MigLayout的强大,但是为什么OP信任你);他不需要。他寻求帮助,我正试图提供一些DIY风格的帮助。你知道这是最好的方法。考虑提供一个可运行的例子来解决MigLayout的OP问题,否则它只是推销(我知道MigLayout很强大,但是为什么OP信任你),他不必这么做。他寻求帮助,我正试图提供一些DIY风格的帮助。你知道这是做某事的最好方法。这真的很有帮助,谢谢!对于那些想知道的人,您可以创建一个单独的.java文件,将JPanel和重写扩展到程序员建议的两个方法,并将它们插入到netbeans GUI生成器中,方法是从项目侧栏拖动并将自定义类放入GUI中。这非常有帮助,谢谢!对于那些想知道的人,您可以创建一个单独的.java文件,将JPanel和重写扩展到程序员建议的两个方法,并通过从项目侧栏拖动并将自定义类拖放到GUI中,将它们插入到netbeans GUI生成器中。