【问题标题】:Layout manager problems while programming UI编程 UI 时的布局管理器问题
【发布时间】:2018-02-16 20:17:16
【问题描述】:

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

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

【问题讨论】:

    标签: java swing jpanel layout-manager


    【解决方案1】:

    我希望我的程序有一个包含三个元素(两个 JTextField 和一个 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);
         }
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-31
      • 2018-06-08
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 2018-06-20
      相关资源
      最近更新 更多