【问题标题】:Java Swing `GridBagLayout` alignment issueJava Swing`GridBagLayout`对齐问题
【发布时间】:2021-06-21 01:55:46
【问题描述】:

我正在尝试使用 Java Swing 创建登录表单。但我希望布局看起来更紧凑,但仍然响应迅速。

我的项目结构

Project/
└── src
    ├── GUI
    │   ├── Control.java
    │   ├── Main.java
    │   └── pages
    │       ├── LoginPanel.java
    └── Helper
        └── Helpers.java

这是 GUI 的图片,这不是我想要的:

form 面板中的组件的行为与我预期的不同,我希望字段靠近标签,但不水平填充整个空间。

还有我的代码:

登录面板

package GUI.pages;
import javax.swing.*;

public class LoginPanel extends JPanel {

    // Some labels, button, groups and fields
    private static JTextField usernameInputField;
    private static JPasswordField passwordInputField;
    private static JButton submit;
    private static JLabel message;
    private static JButton registerRedirect = new JButton("register");
    private static final int PADDING = 30;



    public LoginPanel() {

        setLayout(new BorderLayout());

        JLabel title = Helpers.generateTitle();
        JPanel titleContainer = new JPanel();
        titleContainer.setLayout(new FlowLayout(FlowLayout.LEFT, PADDING, PADDING));
        titleContainer.add(title);

        // the username row
        JLabel usernameLabel = new JLabel("Username: ");
        usernameInputField = new JTextField(50);

        // The password row
        JLabel passwordLabel = new JLabel("Password: ");
        passwordInputField = new JPasswordField(50);

        JPanel form = new JPanel();
        form.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.gridwidth = 2;
        c.gridx = 0;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = new Insets(0,20,0,0);
        form.add(usernameLabel, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.anchor = GridBagConstraints.WEST;
        c.insets = new Insets(0,20,0,0);
        form.add(passwordLabel, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 0.1;
        c.ipadx = 200;
        JPanel usernameFieldContainer = new JPanel();
        usernameFieldContainer.add(usernameInputField);
        usernameFieldContainer.setSize(new Dimension(usernameInputField.getWidth() + 10, usernameInputField.getHeight() + 10));
        form.add(usernameFieldContainer, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        c.weightx = 0.001;
        c.weightx = 0.001;
        c.ipadx = 50;
        JPanel passwordFieldContainer = new JPanel();
        passwordFieldContainer.add(passwordInputField);
        passwordFieldContainer.setSize(new Dimension(passwordInputField.getWidth() + 10, passwordInputField.getHeight() + 10));
        form.add(passwordFieldContainer, c);

        // Configuring the submit button
        submit = new JButton("Sign in");
        submit.addActionListener(new LoginActionListener());
        submit.setActionCommand("login");

        JPanel submitContainer = new JPanel();
        submitContainer.setLayout(new FlowLayout(FlowLayout.RIGHT, PADDING, PADDING));
        submitContainer.add(submit);


        // adding everything to the layout

        add(titleContainer, BorderLayout.PAGE_START);
        add(form, BorderLayout.LINE_START);
        add(submitContainer, BorderLayout.PAGE_END);
        
    }
}

主要

package GUI;

import javax.swing.*;
import GUI.pages.LoginPanel;

public class Main extends JFrame {

   
    public static void main(String[] args){
        JFrame frame = new Main();
    }

    public Main(){
        JPanel login_panel = new LoginPanel();
        add(login_panel);
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        pack();
    }

}

这就是我想要的样子(更新):

REM(the title)        
________________________________
           __________________
Username: [__________________]
           __________________
Password: [__________________]
                      
                   [Submit button]
                    

【问题讨论】:

  • 如果你想加入这个社区,你必须遵守规则。当你上次问这个问题时,我们都可以看到你是如何对待安德鲁的。 Andrew's answer 有什么问题?哦,顺便说一句,登录面板最好放在 JDialog 上。 Swing 教程,How to Use GridBagLayout 可能会有所帮助。
  • 我是新人,不是回答/提问方面的专家。所以,对不起我的所作所为。 @Abra 它并没有解决我的问题,你可以在更新的图片上看到结果。

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


【解决方案1】:

我希望字段靠近标签,但不水平填充整个空间。

public final static int WINDOW_WIDTH = 750;
public final static int WINDOW_HEIGHT = 550;

不要尝试设置窗口大小。所有 Swing 组件都将确定它们自己的首选尺寸。在调用 setVisible(...) 方法之前,将所有组件添加到框架和 pack() 框架中。然后将根据所有组件的首选大小调整框架的大小。

private static JLabel usernameLabel;
private static JTextField usernameInputField;

不要使用静态变量。这不是 static 关键字的使用方式。

无需为您的标签创建实例变量。当您希望变量在多个方法中被引用时,您通常只创建实例变量。标签仅用于在表单上显示。文本字段将在按钮的 ActionListener 中引用,因此它们应该是实例变量。

setSize(400, 400); 

不要尝试设置大小。额外的垂直高度是因为您只使用 400 作为框架的随机高度。 pack() 方法将确定首选大小。

usernameInputField = new JTextField(50);
...
passwordInputField = new JPasswordField(150);

构造函数中的数字将用于调整文本字段的大小以包含“W”字符。它不是像素。所以你指定的值太大了。

c.fill = GridBagConstraints.HORIZONTAL;

不需要“填充”约束。

form.setMaximumSize(new Dimension(200, passwordInputField.getHeight()));

无需指定最大尺寸。

我还建议您可以使用GridBagLayout 完成整个布局。

对于第一行中的标签,您可以使用gridwidth = 2。最后一行的按钮也是如此。

然后您可以使用anchor 约束来控制行上标签/按钮的对齐方式。那就是你想让标签居中并且按钮右对齐。

【讨论】:

  • 非常感谢您花这么多时间在这上面,我一定会试试看的!
  • 我更新了我的代码和新GUI结果的图片,如果可以的话,你能看看吗?谢谢!
  • 表单对我来说看起来不错。你还在看问题吗?关于代码:1)您仍然在每个地方都使用静态字段。最终的静态变量应该被删除。应从其他变量中删除 static 关键字。 2) pack() 的顺序错误。 3)“表单”面板应输入到BorderLayout.CENTER。 4)不知道为什么每个文本字段都有一个面板。使用 GridBagLayout 的要点是您不需要包装面板。另外,不知道为什么要使用 setSize()。我说过你不应该在代码中的任何地方使用 setSize()。
  • 它工作了,终于,3天后,我终于让它工作了!非常感谢,感谢这个可爱社区中以极大的耐心帮助我的每一个人!
  • setVisible(true); 之前和将登录表单添加到框架之后尝试packing。
猜你喜欢
  • 2015-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多