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

时间:2014-11-14 05:13:53

标签: java swing layout-manager gridbaglayout

我是Java Swing的新手并试图制作一个简单的布局(我想),但是我遇到了很多问题,达到了我想要的行为。这是我的代码:

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

我的笔记本电脑屏幕是我想要的好结果。

  1. equipementPanel = green
  2. grillePanel =灰色
  3. enter image description here

    但是在我的大屏幕上......它应该是灰色的。红色没关系。

    enter image description here

    当我缩小尺寸时发生了彻底的灾难。

    enter image description here

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

    窗口最小可以设置为绿色+黄色的高度。和绿色的宽度+任何不错的显示。

    我知道小窗口的奇怪行为是因为我的首选尺寸低于300 + 600 ......但我需要在某处修复一些尺寸!?!?

    如果我可以使用其他布局达到相同的行为,我很乐意尝试。如果我改变并使用一些ScrollPanel,那会改变什么吗?

    我添加了一个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);
        }
    
    }
    

2 个答案:

答案 0 :(得分:5)

有两个基本问题(我认为)......

其一,您正在尝试在单个布局管理器中管理复杂的布局,这在最好的时候非常难。

其二,您似乎无法理解当组件的可用大小低于其首选大小时布局管理器将执行的操作,即GridBagLayout的情况,恢复到它的最小尺寸...

您可以通过使用权重(weightx / weighty)来克服其中的一部分,但有时,您只需要为最小尺寸提供硬值...

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

enter image description here

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

}

答案 1 :(得分:-1)

Swing布局经理非常体面,但不幸的是他们会遇到很多麻烦。我认为实际可用的唯一布局管理器是BorderLayoutGroupLayout,并且仅在某些情况下GridBayLayout。在大多数情况下,我发现它们没用。

为什么不尝试使用第三方布局管理器?根据我的经验,我可以说tha MigLayout非常棒。它非常灵活,具有不错的API。您将立即获得所需的布局组合。我在所有桌面项目中都使用它。