Java Swing `GridBagLayout` 对齐问题
Java Swing `GridBagLayout` alignment issue
我正在尝试使用 Java Swing 创建登录表单。但我希望布局看起来更紧凑,但仍然响应迅速。
我的项目结构
Project/
└── src
├── GUI
│ ├── Control.java
│ ├── Main.java
│ └── pages
│ ├── LoginPanel.java
└── Helper
└── Helpers.java
这是GUI的图片,这不是我想要的:
form
面板中的组件没有像我预期的那样运行,我希望字段靠近标签但不水平填充整个 space。
还有我的代码:
登录面板
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]
I want the fields to be close to the labels but not filling the entire space horizontally.
public final static int WINDOW_WIDTH = 750;
public final static int WINDOW_HEIGHT = 550;
不要尝试设置 window 尺寸。所有 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
约束来控制label/button在行上的对齐方式。那就是你想让标签居中,按钮右对齐。
我正在尝试使用 Java Swing 创建登录表单。但我希望布局看起来更紧凑,但仍然响应迅速。
我的项目结构
Project/
└── src
├── GUI
│ ├── Control.java
│ ├── Main.java
│ └── pages
│ ├── LoginPanel.java
└── Helper
└── Helpers.java
这是GUI的图片,这不是我想要的:
form
面板中的组件没有像我预期的那样运行,我希望字段靠近标签但不水平填充整个 space。
还有我的代码:
登录面板
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]
I want the fields to be close to the labels but not filling the entire space horizontally.
public final static int WINDOW_WIDTH = 750;
public final static int WINDOW_HEIGHT = 550;
不要尝试设置 window 尺寸。所有 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
约束来控制label/button在行上的对齐方式。那就是你想让标签居中,按钮右对齐。