简体   繁体   English

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

[英]GridBagLayout elements behaviour when resizing window

I'm new to Java Swing and was trying to make a simple layout (I thought), but I have a lot of problems reaching the behavior I want. 我是Java Swing的新手,正在尝试制作一个简单的布局(我认为),但是在实现所需的行为时遇到了很多问题。 Here's my code : 这是我的代码:

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

Screen of my laptop is a good result of what I want. 我的笔记本电脑的屏幕是我想要的一个很好的结果。

  1. equipementPanel = green equipementPanel =绿色
  2. grillePanel = gray grillePanel =灰色

在此处输入图片说明

But on my bigger screen...it is the gray one that should stretch. 但是在我的大屏幕上……应该是灰色的。 Red it's okay. 红色,可以。

在此处输入图片说明

And a total disaster when I size it down . 当我缩小规模时,彻底灾难了。

在此处输入图片说明

What I want it to do is 我要它做的是
The Gray should not have fixed height and width. 灰色不应具有固定的高度和宽度。
The Yellow should always have the fixed height but not width. 黄色应始终具有固定的高度,而不应具有宽度。
The Red should always have fixed width but not height. 红色应始终具有固定的宽度,而不应具有高度。 The Green should always have both fixed. 绿色应始终固定。

The smallest the window could become would be set to the height of the Green + Yellow one. 窗口可能变为的最小尺寸将设置为绿色+黄色的高度。 and width of Green + whatever nice to display. 和绿色+的宽度,无论显示效果如何。

I know that the weird behavior with the small window is because I go under 300 + 600 of my preferred size...but I need to fix some size somewhere!?!? 我知道小窗口的怪异行为是因为我的首选尺寸小于300 + 600 ...但是我需要在某个地方固定一些尺寸!?!?

If I can reach the same behavior with another layout, I'd be glad to try it. 如果我可以在其他布局下达到相同的行为,我很乐意尝试一下。 If I change and use some ScrollPanel, does that change anything? 如果我更改并使用了某些ScrollPanel,是否会有所改变?

I added a mcve : MCVE.JAVA 我添加了一个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();
    }    
}

the 4 panel 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);
    }

}

There are two basic issues (as I see it)... 有两个基本问题(如我所见)...

One, you are trying to manage a complex layout within a single layout manager, which is pretty hard at the best of times. 第一,您试图在一个布局管理器中管理一个复杂的布局,这在大多数情况下很难。

Two, you don't seem to understand what the layout manager will do when the available size of the component drops below it's preferred size, which is, in the case of GridBagLayout , revert to it's minimum size... 第二,当组件的可用大小降到其首选大小以下时,您似乎似乎不了解布局管理器将执行什么操作,在GridBagLayout的情况下,恢复到其最小大小...

You can overcome some of this through the use of weights ( weightx / weighty ), but sometimes, you just need to provide a hard value for the minimum size as well... 您可以通过使用权重( weightx / weighty )来克服其中的某些问题,但是有时,您还需要为最小尺寸提供一个硬值...

Without knowing your exact needs (and you're going to need to make decisions about which components are more important), this is a rough example... 在不知道您的确切需求(并且您将需要决定哪些组件更重要)的情况下,这是一个粗糙的示例...

在此处输入图片说明

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

}

Swing layout managers are quite decent, but unfortunetly they can make a lot of troubles. Swing布局管理器相当不错,但是不幸的是,它们会带来很多麻烦。 I think that the only layout managers that are actually usable are BorderLayout , GroupLayout and only in some cases GridBayLayout . 我认为实际上唯一可用的布局管理器是BorderLayoutGroupLayout并且仅在某些情况下是GridBayLayout In most cases I have found they are useless. 在大多数情况下,我发现它们没有用。

Why dont you try to use 3rd party layout managers? 您为什么不尝试使用第三方布局管理器? From my experience I can tell thal MigLayout is more than great. 根据我的经验,我可以告诉thal MigLayout远不止于此 It is very flexible and have decent API. 它非常灵活并且具有不错的API。 You will get desired layout composition in no time. 您将立即获得所需的布局组成。 I am using it in all desktop projects. 我在所有桌面项目中都使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM