繁体   English   中英

如何在Java Swing中动态控制自动调整大小的组件

[英]How to dynamically control auto-resize components in Java Swing

我正在Java(1.8)Swing中创建新的GUI,我正在寻找一种方法来覆盖我所有组件的调整大小行为。

让我向您解释一些编辑后的照片:

1.全屏GUI

这是我的全屏GUI,带有3个面板和一个JToolBar 绿色的需要固定大小 ,其他的则需要调整大小

目前,我只有2个小的GridLayout来组织它们(一个垂直,绿色和青色面板一个水平)。

全屏GUI

2.较小的水平尺寸

例如,如果我从右侧减小框架尺寸,我希望根据新的框架尺寸调整我的蓝色和青色面板的尺寸。 但是绿色面板必须固定 (这不是我认为最困难的部分。)

一次调整大小的GUI

3.最小水平尺寸

这对我来说是最困难的部分。 一旦青色(或蓝色)面板达到最小尺寸,我希望他将绿色面板“ ”到左侧,即使它从框架中消失了。

当然,将框架向右拉将使绿色面板再次出现。

GUI的最小大小

我该怎么办?

我考虑过使用JSplitPane或特定的侦听器来手动确定调整大小的行为,但我需要一些建议。

抱歉,如果现有帖子可以回答这个问题,我没有找到任何答案为我解释问题。

提前致谢!


如果您需要更多示例,请查看功能相同的“ Evernote”软件

设置Green面板的最大/最小/首选尺寸可以使面板在第一种情况下保持相同的尺寸。 要检查大小,可以在其他JPanel之一上使用ComponentListener如果大小小于特定宽度,则更改“ Green面板的最大/最小/首选大小。

以下是一起执行此操作的示例-当Blue <600时,它将调整Green面板的大小,并且调整大小是加权调整大小(占总宽度的30%)。 要获得真正的L&F,您可能需要尝试布局/尺寸。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;


public class GridTest extends JPanel{

    private boolean changeAllowed = false;
    //keep reference to cyan for the height dimension
    final JPanel cyan = new JPanel();

    public GridTest(){
        cyan.setPreferredSize(new Dimension(600, 300));//provide sizing hint
    }

    private Dimension getCustomDimensions(){
        if ( changeAllowed ){
            return new Dimension((int)(super.getParent().getBounds().width * 0.3), cyan.getBounds().height);
        }else{
            return new Dimension(200, cyan.getBounds().height);
        }
    }
    @Override
    public Dimension getMaximumSize(){
        return getCustomDimensions();
    }
    @Override
    public Dimension getMinimumSize(){
        return getCustomDimensions();
    }
    @Override
    public Dimension getPreferredSize(){
        return getCustomDimensions();
    }

    public static void main(String[] args) throws Exception{
        SwingUtilities.invokeAndWait(new Runnable(){

            @Override
            public void run() {
                final int MINIMUM = 600;
                JFrame frame = new JFrame();
                frame.add(new JToolBar(), BorderLayout.NORTH);
                final JPanel blue = new JPanel();

                final GridTest green = new GridTest();
                green.setBackground(Color.green);
                green.setOpaque(true);

                green.cyan.setBackground(Color.cyan);
                green.cyan.setOpaque(true);
                blue.setOpaque(true);
                blue.setBackground(Color.blue);
                blue.setPreferredSize(new Dimension(900, 300));//hint at size
                blue.setMinimumSize(new Dimension(100, 200));//hint at size
                //Nest Box Layouts
                Box top = Box.createHorizontalBox();
                top.add(blue);
                Box bottom = Box.createHorizontalBox();
                bottom.add(green);
                bottom.add(green.cyan);
                Box vert = Box.createVerticalBox();
                vert.add(top);
                vert.add(bottom);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(vert);
                //listen for resizes
                blue.addComponentListener(new ComponentAdapter(){

                    @Override
                    public void componentResized(ComponentEvent e) {
                        if ( blue.getBounds().width < MINIMUM ){//set flag
                            green.changeAllowed = true;
                        }else{
                            green.changeAllowed = false;
                        }
                    }
                });

                frame.pack();
                frame.setSize(800, 600);
                frame.setVisible(true);

            }

        });
    }
}

这是我的操作方式,我不确定这是否正确:

首先将布局设置为null。

接下来,为框架创建组件调整大小事件:

addComponentListener(new ComponentAdapter(){
            public void componentResized(ComponentEvent e){
            }
        });

在这里,您可以在调整大小后手动更改组件。 我为一些程序执行了此操作,以使框架左右两侧的滚动窗格始终保持相同的宽度,并使其他所有内容的大小都随着调整大小而变大。

如果您为绿色和青色组件设置了适当的最小尺寸,那么使用GridBagLayout应当很容易:

setLayout(new GridBagLayout());
green.setMnimumSize(new Dimension(0, 0));
cyan.setMinimumSize(new Dimension(100, 100)); // whatever fits
add(blue, new GridBagConstraints(0, 0, 2, 1,
        1.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
        new Insets(0, 0, 0, 0), 0, 0);
add(green, new GridBagConstraints(0, 1, 1, 1,
        0.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.NONE,
        new Insets(0, 0, 0, 0), 0, 0);
add(cyan, new GridBagConstraints(1, 1, 1, 1,
        1.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
        new Insets(0, 0, 0, 0), 0, 0);

通过为青色和蓝色分量指定权重x并设置resize = HORIZONTAL,它们将随容器调整大小。

您可以使用BoxLayout包含绿色和青色面板。 BoxLayout遵循组件的最小和最大大小。 因此,对于绿色面板,将最大大小设置为等于首选大小,对于青色面板,将最小大小设置为等于首选大小:

import java.awt.*;
import java.util.*;
import javax.swing.*;

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        JPanel blue = new JPanel();
        blue.setBackground( Color.BLUE );
        blue.setPreferredSize( new Dimension(500, 100) );

        Box box = Box.createHorizontalBox();

        JPanel green = new JPanel();
        green.setBackground( Color.GREEN );
        green.setPreferredSize( new Dimension(200, 100) );
        green.setMaximumSize( green.getPreferredSize() );
        box.add( green );

        JPanel cyan = new JPanel();
        cyan.setBackground( Color.CYAN );
        cyan.setPreferredSize( new Dimension(300, 100) );
        cyan.setMinimumSize( cyan.getPreferredSize() );
        box.add( cyan );

        setLayout( new BorderLayout() );
        add(blue, BorderLayout.NORTH);
        add(box, BorderLayout.CENTER);
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

当然,正确的解决方案是分别重写每个面板的getMaximumSize()getMinimumSize()方法,以仅返回面板的首选大小。

重要的顺序是这样的:

                frame.revalidate();
                frame.pack();
                frame.repaint();
  1. revalidate ():从最近的验证根开始对组件层次结构进行验证之后,使组件失效直至最近的根。
  2. pack ():使窗口的大小适合其子组件的首选大小和布局。 窗口的宽度和高度将自动放大。
  3. repaints ():在所有这些重新计算之后,repaint显示了组件。

在完成每一系列更改之后,请使用此顺序,您已经在代码中完成了操作,并希望看到显示在屏幕上的结果。

我喜欢java.awt.GridBagLayout中java.awt.GridBagConstraints中的结合,我用从内容窗格中启动所有的容器此布局。

如果将一个容器添加到另一个容器中,请在每个容器上使用一个布局,否则由于层次结构中缺少布局,计算将失败。

暂无
暂无

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

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