Java 编程UI时的布局管理器问题

Java 编程UI时的布局管理器问题,java,swing,jpanel,layout-manager,Java,Swing,Jpanel,Layout Manager,我正试图为Java程序创建一个特定的UI,但在选择合适的布局管理器时遇到了困难。我希望我的程序有一个包含三个元素的顶部面板,两个JTextFields和一个JButton,还有一个较低的JPanel,其中有一个JPanel。内板应始终为方形,根据其容器居中,并适应其容器的最大高度或宽度。我曾尝试使用ComponentAdapter来实现始终保持正方形的效果,但程序似乎没有按照我希望的方式运行,而且顶部面板似乎被挤压到顶部 JPanel maincontainer = new JPanel();

我正试图为Java程序创建一个特定的UI,但在选择合适的布局管理器时遇到了困难。我希望我的程序有一个包含三个元素的顶部面板,两个JTextFields和一个JButton,还有一个较低的JPanel,其中有一个JPanel。内板应始终为方形,根据其容器居中,并适应其容器的最大高度或宽度。我曾尝试使用ComponentAdapter来实现始终保持正方形的效果,但程序似乎没有按照我希望的方式运行,而且顶部面板似乎被挤压到顶部

JPanel maincontainer = new JPanel();
    maincontainer.setLayout(new BoxLayout(maincontainer, BoxLayout.PAGE_AXIS));

    JPanel jpanel2 = new JPanel();
    jpanel2.setLayout(new GridLayout(0, 3));
    JTextField txt = new JTextField();
    txt.setFocusable(false);
    JButton btn = new JButton();
    btn.setFocusable(false);
    JTextField txt2 = new JTextField();
    txt2.setFocusable(false);
    jpanel2.add(txt);
    jpanel2.add(btn);
    jpanel2.add(txt2);
    maincontainer.add(jpanel2);


    JPanel masterPane = new JPanel(new GridBagLayout());

    JPanel centerPane = new JPanel();
    masterPane.add(centerPane);
    masterPane.addComponentListener(new ComponentAdapter() {

        @Override
        public void componentResized(ComponentEvent e) {
            if(masterPane.getHeight()<masterPane.getWidth())
                centerPane.setSize(masterPane.getHeight(), masterPane.getHeight());
            else
                centerPane.setSize(masterPane.getWidth(), masterPane.getWidth());
        }

    });
    centerPane.setBackground(Color.blue);

    masterPane.add(centerPane);
    maincontainer.add(masterPane);


    JFrame frame = new JFrame("");
    frame.getContentPane().add(maincontainer);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(true);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setMinimumSize(new Dimension(300,300));
    frame.setSize(500, 500);

我希望我的程序有一个包含三个元素的顶部面板,两个JTextFields和一个JButton,还有一个较低的JPanel,其中有一个JPanel

最简单的方法是继续使用框架的默认布局管理器,即BorderLayout。将带有文本字段和按钮的面板添加到BorderLayout.PAGE_START。然后将动态更改的面板添加到BorderLayout.CENTER

内板应始终为正方形,根据其容器居中,并适应其容器的最大高度或宽度

在配电盘上居中放置元件的最简单方法是在配电盘上使用GridBagLayout。默认的GridBagConstraints将使零部件以其首选大小显示,并在垂直和水平方向居中。因此,您需要一个使用GridBagLayout的包装器面板来包含您的中心面板

然后,您可能希望覆盖中心面板的getPreferredSize方法,以便随着父面板大小的更改而动态更改。这是一种比使用ComponentListener更好的方法

比如:

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

public class SSCCE extends JPanel
{

    SSCCE()
    {
        setLayout( new BorderLayout() );

        JPanel top = new JPanel( new GridLayout(0, 3) );
        top.add( new JTextField(10) );
        top.add( new JButton("Button") );
        top.add( new JTextField(10) );
        add(top, BorderLayout.PAGE_START);

        JPanel center = new JPanel()
        {
            @Override
            public Dimension getPreferredSize()
            {
                Dimension parent = getParent().getSize();

                if (parent.width < parent.height)
                    return new Dimension(parent.width, parent.width);
                else
                    return new Dimension(parent.height, parent.height);

            }
        };
        center.setBackground( Color.BLUE );

        JPanel wrapper = new JPanel( new GridBagLayout() );
        wrapper.add(center, new GridBagConstraints());

        add(wrapper, BorderLayout.CENTER);
    }

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

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


static class DragListener extends MouseInputAdapter
{
    Point location;
    MouseEvent pressed;

    public void mousePressed(MouseEvent me)
    {
        pressed = me;
    }

    public void mouseDragged(MouseEvent me)
    {
        Component component = me.getComponent();
        location = component.getLocation(location);
        int x = location.x - pressed.getX() + me.getX();
        int y = location.y - pressed.getY() + me.getY();
        component.setLocation(x, y);
     }
}

}