简体   繁体   English

如何使用GridBagLayout和GridLayout进行最佳对齐?

[英]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而不留空隙,则可以:

  • Try to restrict your jtextfields, given a different number of columns to the constructor (currently max is 20). 给构造函数指定不同的列数,尝试限制您的jtextfields(当前最大为20)。
  • Align your jlabels to the right. 将jlabel对齐到右侧。 This will cause the empty gap to be placed on the left of the labels. 这将导致空白留在标签的左侧。

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. 您的两次尝试(外部面板使用GridBagLayoutGridLayout )都非常接近解决方案。 The problem was the FlowLayout of your phonePanel . 问题出在您的phonePanelFlowLayout上。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM