【问题标题】:Multiple Panels Below Each Other多个面板彼此下方
【发布时间】:2012-11-16 11:26:48
【问题描述】:

我可以有一个用于登录的顶部面板吗?然后是下面的中间和底部面板。 我正在使用 gridbaglayout 并且分配了 2 个面板。一个面板具有链接到它的组件以获取登录详细信息,而另一个面板具有链接到它的其他组件。但是,它不会按计划进行。 我试过使用 Box/Borderlayout 来做到这一点,但是我无法创建我想要的间距。

这是我想要的草图。

public class GUI extends JFrame{

    private JPanel myTopPL, myTopPL2;
    private JTextField myUsernameTF;
    private JTextField myPasswordTF;
    private JTextField myMessageTF;
    private JLabel myUsernameLBL;
    private JLabel myPasswordLBL;
    private JLabel myItemsLBL;
    private JTextArea myMainTA;
    private JButton myLoginBN;
    private JButton myConnectBN;
    private JButton mySendBN;
    private JComboBox myItemsCB;

    public GUI () {

        super("GUI ");

        setLayout(new GridBagLayout());
        myTopPL = new JPanel();
        myTopPL2 = new JPanel();
        myTopPL.setLayout(new GridBagLayout());
        myTopPL2.setLayout(new GridBagLayout());
        GridBagConstraints myTopPLGBC = new GridBagConstraints();
        myTopPLGBC.weightx = 1;
        myTopPLGBC.weighty = 1;
        GridBagConstraints myTopPLGBC2 = new GridBagConstraints();
        myTopPLGBC.weightx = 2;
        myTopPLGBC.weighty = 2;

        myUsernameLBL = new JLabel("Username: ");
        myUsernameLBL.setFont(new Font("Arial", Font.BOLD, 13));
        myTopPLGBC.gridx = 1;
        myTopPLGBC.gridy = 1;
        myTopPLGBC.insets = new Insets(5,5,5,5);
        myTopPL.add(myUsernameLBL, myTopPLGBC);

        myUsernameTF = new JTextField(10);
        myTopPLGBC.gridx = 2;
        myTopPLGBC.gridy = 1;
        myTopPLGBC.insets = new Insets(5,5,5,5);
        myTopPL.add(myUsernameTF,myTopPLGBC);

        myPasswordLBL = new JLabel("Password: ");
        myPasswordLBL.setFont(new Font("Arial", Font.BOLD, 13));
        myTopPLGBC.gridx = 3;
        myTopPLGBC.gridy = 1;
        myTopPLGBC.insets = new Insets(5,5,5,5);
        myTopPL.add(myPasswordLBL, myTopPLGBC);

        myPasswordTF = new JTextField(10);
        myTopPLGBC.gridx = 4;
        myTopPLGBC.gridy = 1;
        myTopPLGBC.insets = new Insets(5,5,5,5);
        myTopPL.add(myPasswordTF,myTopPLGBC);

        myLoginBN = new JButton("Login");
        myTopPLGBC.gridx = 5;
        myTopPLGBC.gridy = 1;
        myTopPLGBC.insets = new Insets(5,5,5,5);
        myTopPL.add(myLoginBN,myTopPLGBC);

        myItemsLBL = new JLabel("Items: ");
        myItemsLBL.setFont(new Font("Arial", Font.BOLD, 13));
        myTopPLGBC2.gridx = 1;
        myTopPLGBC2.gridy = 3;
        myTopPLGBC2.insets = new Insets(5,5,5,5);
        myTopPL2.add(myItemsLBL, myTopPLGBC2);

        myItemsCB = new JComboBox();
        myItemsCB.addItem("     Select an Item     ");
        myTopPLGBC2.gridx = 1;
        myTopPLGBC2.gridy = 4;
        myTopPLGBC2.insets = new Insets(5,5,5,5);
        myTopPL2.add(myItemsCB, myTopPLGBC2);

        myConnectBN = new JButton("Connect");
        myTopPLGBC2.gridx = 2;
        myTopPLGBC2.gridy = 4;
        myTopPLGBC2.insets = new Insets (5,5,5,5);
        myTopPL2.add(myConnectBN, myTopPLGBC2);

        GridBagConstraints GBC = new GridBagConstraints();
        GBC.anchor = GridBagConstraints.NORTHWEST;
        GBC.weightx = 1;
        GBC.weighty = 1; 
        this.add(myTopPL,GBC);  

        GridBagConstraints GBC2 = new GridBagConstraints();
        GBC2.anchor = GridBagConstraints.NORTHWEST;
        GBC2.weightx = 2;
        GBC2.weighty = 2; 
        this.add(myTopPL2,GBC2);    

    }

    public static void main(String[] args) {

        GUI GUI = new GUI ();
        GUI .setDefaultCloseOperation(RMIAuctionHouse.EXIT_ON_CLOSE);
        GUI .setSize(750,500);
        GUI .setVisible(true);
    }
}

【问题讨论】:

    标签: java swing user-interface layout-manager gridbaglayout


    【解决方案1】:

    我会将应用程序分解为各个职责领域,并专注于创建 UI 元素来支持它。这将使您可以专注于应用程序的每个部分的需求,还可以让您有机会根据需要更改布局

    public class TestLayout15 {
    
        public static void main(String[] args) {
            new TestLayout15();
        }
    
        public TestLayout15() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Test");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new MainPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
    
            });
        }
    
        public class MainPane extends JPanel {
    
            private JTextField messageField;
            private JButton sendButton;
    
            public MainPane() {
                setBorder(new EmptyBorder(4, 4, 4, 4));
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.weightx = 1;
                gbc.fill = GridBagConstraints.HORIZONTAL;
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(new LoginPane(), gbc);
                gbc.gridy++;
                add(new ConnectPane(), gbc);
                gbc.gridy++;
                gbc.weighty = 1;
                gbc.fill = GridBagConstraints.BOTH;
                add(new JScrollPane(new JTextArea(5, 20)), gbc);
    
                gbc.gridwidth = 1;
    
                messageField = new JTextField(10);
                sendButton = new JButton("Send");
    
                gbc.gridy++;
                gbc.weighty = 0;
                gbc.fill = GridBagConstraints.HORIZONTAL;
                add(messageField, gbc);
                gbc.gridx++;
                gbc.weightx = 0;
                add(sendButton, gbc);            
            }
    
        }
    
        public class ConnectPane extends JPanel {
    
            private JComboBox comboBox;
            private JButton connectButton;
    
            public ConnectPane() {
                comboBox = new JComboBox();
                connectButton = new JButton("Connect");
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.anchor = GridBagConstraints.WEST;
                add(comboBox, gbc);
    
                gbc.gridx++;
                gbc.weightx = 1;
                add(connectButton, gbc);
            }
    
        }
    
        public class LoginPane extends JPanel {
    
            private JTextField userNameField;
            private JPasswordField passwordField;
            private JButton loginButton;
    
            public LoginPane() {
    
                userNameField = new JTextField(10);
                passwordField = new JPasswordField(10);
                loginButton = new JButton("Login");
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.anchor = GridBagConstraints.WEST;
                add(new JLabel("User name:"), gbc);
    
                gbc.gridx++;
                add(userNameField, gbc);
    
                gbc.gridx++;
                add(new JLabel("Password:"), gbc);
    
                gbc.gridx++;
                add(passwordField, gbc);
    
                gbc.gridx++;
                gbc.weightx = 1;
                add(loginButton, gbc);
    
            }
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      首先,将对GUI.setSize(750,500) 的调用替换为GUI.pack()。这将调整窗口大小以适合您的内容。之后,您会看到第二个面板出现在第一个面板的右侧。这是因为您没有在GBC2 上设置gridx/gridy,所以它默认将myTopPL2 放在myTopPL1 的右侧,而不是在它的下方。

      在使用GridBagLayout 时,我很少显式设置gridx/gridy。对于显示的第一行,我将使用除myLoginBN 之外的所有默认值,我将设置gridwidthGridBagConstraints.REMAINDER。这告诉 GridBagLayout 这一行没有其他内容。使用默认 gbc 添加的下一项将放置在第二行的开头。

      轻微尼特:

      • 使用标准 Java 大写:
        • 类名是驼峰式,前导大写字符。所以,“GUI”,而不是“GUI”。
        • 实例名称为驼峰式,前导小写字符。所以,“gbc1”不是“GBC1”
      • 使用 SwingUtilities.InvokeLater 在 EDT 上启动 Gui

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                GUI GUI = new GUI ();
                GUI .setDefaultCloseOperation(RMIAuctionHouse.EXIT_ON_CLOSE);
                GUI .setSize(750,500);
                GUI .setVisible(true);
            }});
        

      【讨论】:

        【解决方案3】:

        看来你对 Java 布局不太熟悉,建议你试试 null(absolute) Layout:

        setLayout(null);
        ...
        component.setBounds( x, y, width, heigh );
        add(component);
        

        这里是例子

        package gui;
        
        import java.awt.Font;
        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JPanel;
        import javax.swing.JTextField;
        
        
        public class GUI extends JFrame{
        
            private JTextField myUsernameTF;
            private JLabel myUsernameLBL;
        
            public GUI() {
        
                super("GUI ");
                setLayout(null);     
        
                myUsernameLBL = new JLabel("Username: ");
                myUsernameLBL.setFont(new Font("Arial", Font.BOLD, 13));
                myUsernameLBL.setBounds(50,30,80,20);
                add(myUsernameLBL);
        
                myUsernameTF = new JTextField(10);
                myUsernameTF.setBounds(190,30,80,20);
                add(myUsernameTF);
        
                // and so on ...
        
        
        
            }
        
            public static void main(String[] args) {
                GUI frame = new GUI();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(750,500);
                frame.setVisible(true);
            }
        }
        

        祝你在处理java swing的棘手方法上好运=)

        【讨论】:

        • -1 请重新考虑这些令人不安的问题:null 布局、容易混淆的 contentPane、无理由的双括号,以及当您的第一个项目符号显示 替换内容窗格i>不这样做。另请参阅answer
        • 怎么说“看来你对Java布局不熟悉”“我建议你试试null(absolute) Layout”同一句话?他们似乎不熟悉布局的事实是我可能考虑的最大教育机会。空布局只适用于动画之类的东西,绝对不是表单设计-恕我直言
        • @MadProgrammer:没错,尽管肯定有错误的拼写更正。 :-)
        • 如果您有两个帐户,您可以申请merge
        • @trashgod iPad + 哭泣,扭动 6 个月大的孩子打字不好:((此外,我被推荐的空布局激怒了)
        猜你喜欢
        • 2021-02-03
        • 2020-09-12
        • 2018-11-13
        • 1970-01-01
        • 2014-05-18
        • 2021-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多