调整窗口大小时GridBagLayout元素的行为 [英] GridBagLayout elements behaviour when resizing window

查看:77
本文介绍了调整窗口大小时GridBagLayout元素的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java Swing的新手,正试图制作一个简单的布局(我认为),但是在实现所需的行为方面我有很多问题.这是我的代码:

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. 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 =绿色
  2. 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.

我知道小窗口的怪异行为是因为我的首选尺寸小于300 + 600 ...但是我需要在某个地方固定一些尺寸!?!?

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!?!?

如果我可以在其他布局上达到相同的行为,我很乐意尝试一下.如果我更改并使用了某些ScrollPanel,是否会做出任何更改?

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?

我添加了一个mcve: MCVE.JAVA

I added a 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);
    }

}

推荐答案

有两个基本问题(据我所知)...

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.

二,当组件的可用大小降至其首选大小以下时,您似乎似乎不了解布局管理器将执行什么操作,在GridBagLayout的情况下,该大小恢复为最小大小...

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...

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

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...

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

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

}

这篇关于调整窗口大小时GridBagLayout元素的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆