[英]How to use GridBagLayout and GridLayout for optimum alignment?
I wanted to try out GridBagLayout in my program but sadly I don't clearly understand it, I tried implementing GridLayout also but both give me different problems. 我想在程序中尝试GridBagLayout,但可惜我不清楚,我也尝试实现GridLayout,但都给我带来了不同的问题。 Let me show you the code and the output picture to further clarify it:
让我向您展示代码和输出图片以进一步阐明它:
package iKleen;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class ikleenRegister {
JFrame frame;
JPanel phonePanel, fieldPanel, mainPanel;
JLabel name, email, password, address, mobile, l_register;
JTextField nameField, emailField, passwordField, addressField, mobileField, countryCode;
JButton b_register;
GridBagConstraints c;
public void launchGUI()
{
frame = new JFrame("iKleen - Register / Create Free Account");
//phonePanel and its components
phonePanel = new JPanel();
phonePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
mobileField = new JTextField(8);
countryCode = new JTextField(2);
countryCode.setText("+91");
countryCode.setEnabled(false);
phonePanel.add(countryCode);
phonePanel.add(mobileField);
//fieldPanel and its components
fieldPanel = new JPanel();
fieldPanel.setLayout(new GridBagLayout());
fieldPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
name = new JLabel("Name: ");
email = new JLabel("Email ID: ");
password = new JLabel("Password: ");
address = new JLabel("Address: ");
mobile = new JLabel("Mobile Number: ");
nameField = new JTextField(15);
emailField = new JTextField(15);
passwordField = new JTextField(15);
addressField = new JTextField(20);
c.gridx=0;
c.gridy=0;
fieldPanel.add(name, c);
c.gridx=1;
c.gridy=0;
fieldPanel.add(nameField, c);
c.gridx=0;
c.gridy=1;
fieldPanel.add(email, c);
c.gridx=1;
c.gridy=1;
fieldPanel.add(emailField, c);
c.gridx=0;
c.gridy=2;
fieldPanel.add(password, c);
c.gridx=1;
c.gridy=2;
fieldPanel.add(passwordField, c);
c.gridx=0;
c.gridy=3;
fieldPanel.add(address, c);
c.gridx=1;
c.gridy=3;
fieldPanel.add(addressField, c);
c.gridx=0;
c.gridy=4;
fieldPanel.add(mobile, c);
c.gridx=1;
c.gridy=4;
fieldPanel.add(phonePanel, c);
//mainPanel and its components
mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
Font font = new Font("MS Sans Serif", Font.BOLD, 18);
l_register = new JLabel("Create a free account");
l_register.setFont(font);
l_register.setAlignmentX(Component.CENTER_ALIGNMENT);
b_register = new JButton("Create Account");
b_register.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(l_register);
mainPanel.add(fieldPanel);
mainPanel.add(b_register);
//final frame settings
frame.setContentPane(mainPanel);
frame.pack();
centerFrame();
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void centerFrame() {
Dimension currentScreen = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((currentScreen.getWidth() - frame.getWidth()) / 2);
int y = (int) ((currentScreen.getHeight() - frame.getHeight()) / 2);
frame.setLocation(x, y);
}
}
OUTPUT: gridbaglayout 输出: gridbaglayout
package iKleen;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class ikleenRegister {
JFrame frame;
JPanel phonePanel, fieldPanel, mainPanel;
JLabel name, email, password, address, mobile, l_register;
JTextField nameField, emailField, passwordField, addressField, mobileField, countryCode;
JButton b_register;
public void launchGUI()
{
frame = new JFrame("iKleen - Register / Create Free Account");
//phonePanel and its components
phonePanel = new JPanel();
phonePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
mobileField = new JTextField(15);
countryCode = new JTextField(2);
countryCode.setText("+91");
countryCode.setEnabled(false);
phonePanel.add(countryCode);
phonePanel.add(mobileField);
//fieldPanel and its components
fieldPanel = new JPanel();
fieldPanel.setLayout(new GridLayout(5,2,3,3));
fieldPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
name = new JLabel("Name: ");
email = new JLabel("Email ID: ");
password = new JLabel("Password: ");
address = new JLabel("Address: ");
mobile = new JLabel("Mobile Number: ");
nameField = new JTextField(15);
emailField = new JTextField(15);
passwordField = new JTextField(15);
addressField = new JTextField(15);
fieldPanel.add(name);
fieldPanel.add(nameField);
fieldPanel.add(email);
fieldPanel.add(emailField);
fieldPanel.add(password);
fieldPanel.add(passwordField);
fieldPanel.add(address);
fieldPanel.add(addressField);
fieldPanel.add(mobile);
fieldPanel.add(phonePanel);
//mainPanel and its components
mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
Font font = new Font("MS Sans Serif", Font.BOLD, 18);
l_register = new JLabel("Create a free account");
l_register.setFont(font);
l_register.setAlignmentX(Component.CENTER_ALIGNMENT);
b_register = new JButton("Create Account");
b_register.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(l_register);
mainPanel.add(fieldPanel);
mainPanel.add(b_register);
//final frame settings
frame.setContentPane(mainPanel);
frame.pack();
centerFrame();
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void centerFrame() {
Dimension currentScreen = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((currentScreen.getWidth() - frame.getWidth()) / 2);
int y = (int) ((currentScreen.getHeight() - frame.getHeight()) / 2);
frame.setLocation(x, y);
}
}
OUTPUT: gridlayout 输出: gridlayout
In the gridbaglayout, the number field is not aligned with the rest of the fields, I want them to align at their start point just like the jlabels. 在gridbaglayout中,number字段与其余字段不对齐,我希望它们像jlabels一样在其起点对齐。 And in the gridlayout, their is too much gap between the jfields and the jlabels, I tried many solutions, sadly to no avail.
而且在网格布局中,它们在jfields和jlabels之间的差距太大,我尝试了许多解决方案,可惜没有用。
For the GridLayout: 对于GridLayout:
The "gap" you see between the jlabels and jtextfield is caused by the fact that, in GridLayout, every cell has exactly the same width and height. 您在jlabels和jtextfield之间看到的“间隙”是由于以下事实造成的:在GridLayout中,每个单元格的宽度和高度都完全相同。 Hence, since your jtextfields are wider than the labels, they will become wider to fit their cells.
因此,由于您的jtextfields比标签宽,它们将变得更宽以适合其单元格。
So, if you still want to use a GridLayout without that gap you could: 因此,如果您仍然希望使用GridLayout而不留空隙,则可以:
Of course those are not solutions, they are a sort of compromises, since your panel will change aspect. 当然,这些不是解决方案,它们是一种折衷方案,因为您的面板将改变方面。
I suggest you to use a GridBagLayout, changing your "phonePanel" layout. 我建议您使用GridBagLayout来更改“ phonePanel”布局。 If you don't care your phonePanel to have the same width of the other textfields, you can use a flowlayout with left alignment :
如果您不希望phonePanel具有与其他文本字段相同的宽度,则可以使用左对齐的flowlayout:
phonePanel.setLayout (new FlowLayout(FlowLayout.LEFT, 0, 0));
You will have this result: 您将得到以下结果:
If you prefer to have the same width, you could set a BorderLayout to your phonePanel, adding the country code on BorderLayout.WEST (to give it a fixed size) and adding mobileField at the center (to let it taking all the extra space). 如果您希望具有相同的宽度,则可以在phonePanel上设置BorderLayout,在BorderLayout.WEST上添加国家/地区代码(以提供固定的大小),并在中心添加mobileField(以使其占用所有多余的空间) 。
phonePanel.setLayout(new BorderLayout());
phonePanel.add(countryCode, BorderLayout.WEST);
phonePanel.add(mobileField, BorderLayout.CENTER);
This is the result: 结果如下:
Finally, you can use insets to insert a little gap between labels and textfields. 最后,您可以使用inset在标签和文本字段之间插入一些间隙。
Your both tries (with GridBagLayout
and GridLayout
for the outer panel) were quite close to a solution. 您的两次尝试(外部面板使用
GridBagLayout
和GridLayout
)都非常接近解决方案。 The problem was the FlowLayout
of your phonePanel
. 问题出在您的
phonePanel
的FlowLayout
上。 In both variants you can solve the issue by replacing it with a BorderLayout
(with zero gaps): 在这两种变体中,您都可以通过将其替换为
BorderLayout
(零间距)来解决此问题:
//phonePanel and its components
phonePanel = new JPanel();
phonePanel.setLayout(new BorderLayout(0, 0));
mobileField = new JTextField(15);
countryCode = new JTextField(2);
countryCode.setText("+91");
countryCode.setEnabled(false);
phonePanel.add(countryCode, BorderLayout.WEST);
phonePanel.add(mobileField, BorderLayout.CENTER);
For your GridLayout
variant, do the above fix: 对于您的
GridLayout
变体,请执行以上修复:
For your GridBagLayout
variant, do the above fix. 对于您的
GridBagLayout
变体,请执行以上修复。
And for a nicer look you can introduce some padding around your components by: 为了使外观更好看,您可以通过以下方式在组件周围引入一些填充:
c.insets = new Insets(5, 10, 5, 10); // top, left, bottom, right padding
For GridBagLayout, update the following line of code. 对于GridBagLayout,更新以下代码行。 You are using FlowLayout.CENTER which moves the mobile number field to middle of panel.
您正在使用FlowLayout.CENTER将手机号码字段移动到面板中间。
phonePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.