【问题标题】:Prevent components from spreading apart when resizing using GridBagLayout使用 GridBagLayout 调整大小时防止组件散开
【发布时间】:2014-07-08 05:08:29
【问题描述】:

编辑:每次我尝试添加gui 标签时,它都会切换到user-interface。有人介意解释/解决这个问题吗?

我希望客户端可调整大小。我希望 JSeparator 在调整大小时填充框架的宽度,但我希望 JLabels 留在字段旁边。

开始是这样的,JLabels 与字段的距离太远了:

当我水平调整它的大小时,结果如下:

这显然相距甚远。我用来设置这些组件的代码是:

public class LoginPanel extends JPanel {
    
    private JTextField userfield = new JTextField(10);
    private JPasswordField passfield = new JPasswordField(10);
    private JButton login = new JButton("Login");
    private JButton create = new JButton("Create Account");
    
    public LoginPanel() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.weightx = 1;
        gbc.gridx = 2;
        JLabel label = new JLabel("Username: ");
        add(label, gbc);
        
        gbc.gridx = 3;
        gbc.gridwidth = 2;
        add(userfield, gbc);
        
        gbc.gridy = 1;
        add(passfield, gbc);
        
        gbc.gridx = 2;
        label = new JLabel("Password: ");
        add(label, gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridy = 2;
        gbc.gridx = 1;
        gbc.gridwidth = 5;
        add(new JSeparator(JSeparator.HORIZONTAL), gbc);
    }
}

(不得不删掉一些东西,如果我遗漏了什么,请告诉我) 我已经尝试锚定,但我仍然不是 100% 熟悉 GridBagLayout(和约束),所以我不确定我的尝试是否朝着正确的方向。

如何防止 Username: Password: 标签从我的字段中移开,但仍然可以调整大小?

另外,我想使用 GridBagLayout。我还有很多东西需要添加,我不想使用简单的布局,因为我需要灵活性。

【问题讨论】:

    标签: java swing user-interface layout gridbaglayout


    【解决方案1】:

    利用GridBagConstraints#anchor

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JPasswordField;
    import javax.swing.JSeparator;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class LogInTest {
    
        public static void main(String[] args) {
            new LogInTest();
        }
    
        public LogInTest() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new LoginPanel());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class LoginPanel extends JPanel {
    
            private JTextField userfield = new JTextField(10);
            private JPasswordField passfield = new JPasswordField(10);
            private JButton login = new JButton("Login");
            private JButton create = new JButton("Create Account");
    
            public LoginPanel() {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
    
                gbc.anchor = GridBagConstraints.CENTER;
                gbc.weightx = 1;
                gbc.gridx = 2;
                gbc.anchor = GridBagConstraints.EAST;
                JLabel label = new JLabel("Username: ");
                add(label, gbc);
    
                gbc.anchor = GridBagConstraints.WEST;
                gbc.gridx = 3;
                gbc.gridwidth = 2;
                add(userfield, gbc);
    
                gbc.gridy = 1;
                add(passfield, gbc);
    
                gbc.anchor = GridBagConstraints.EAST;
                gbc.gridx = 2;
                label = new JLabel("Password: ");
                add(label, gbc);
    
                gbc.fill = GridBagConstraints.HORIZONTAL;
                gbc.gridy = 2;
                gbc.gridx = 1;
                gbc.gridwidth = 5;
                add(new JSeparator(JSeparator.HORIZONTAL), gbc);
            }
        }
    
    }
    

    您可能还想考虑使用复合布局,即将每个区域分隔到它自己的容器中,并专注于每个部分的单独布局需求,然后将它们全部构建成一个布局

    【讨论】:

    • 我尝试使用GridBagConstraints.CENTER;,但没有成功。介意解释一下我做错了什么吗?
    • GridBagConstraints.EASTGridBagConstraints.WEST 是您所追求的,请参见示例
    • 好的,所以我需要更具体地锚定我的组件,这是正确的吗?编辑:谢谢!我会记住这一点的。计时器到时(它说 7 分钟)后,我会“接受最佳答案”
    • 是的。锚定将让您定义组件希望将自身定位在单元格内的哪个边缘
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多