2017-07-12 39 views
2

我想在我的程序中尝试GridBagLayout,但很遗憾我没有清楚地理解它,我也试过实现GridLayout,但都给了我不同的问题。让我告诉你的代码输出图片,以进一步澄清:如何使用GridBagLayout和GridLayout进行最佳对齐?

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

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

在gridbaglayout中,数字字段与其余字段不对齐,我希望它们在起始点对齐,就像jlabels一样。 而在gridlayout中,它们之间的缝隙和jlabels之间的距离太大,我尝试了很多解决方案,可惜无济于事。

回答

3

对于网格布局:

“差距”你中的JLabel和JTextField中之间看到由在网格布局,每一个细胞具有完全相同的宽度和高度的事实引起的。 因此,由于你的jtextfields比标签更宽,它们会变得更宽以适应它们的单元格。

所以,如果你仍然想使用一个网格布局没有这种差距你可以:

  • 试图限制你的JTextField的情况,给出了不同的列数的构造(目前上限为20)。
  • 将您的jlabels调整到正确的位置。这将导致空白间隙被放置在标签的左侧。

当然这些都不是解决方案,它们是一种妥协,因为你的面板会改变方面。

我建议你使用GridBagLayout,改变你的“phonePanel”布局。 如果你不关心你的phonePanel有其他文本框的宽度相同,您可以使用的FlowLayout,左对齐:

phonePanel.setLayout (new FlowLayout(FlowLayout.LEFT, 0, 0)); 

我们将看到这样的结果:

enter image description here

如果你喜欢有相同的宽度,你可以设置一个BorderLayout到你的phonePanel,在BorderLayout.WEST上添加国家代码(给它一个固定的大小),并在中心添加mobileField(让它占用所有额外的空间) 。

phonePanel.setLayout(new BorderLayout()); 
phonePanel.add(countryCode, BorderLayout.WEST); 
phonePanel.add(mobileField, BorderLayout.CENTER); 

这是结果:

enter image description here

最后,你可以使用insets插入标签和文本框之间的差距不大。

+0

谢谢你!正是我期待的;) – Hanzyusuf

2

您的两次尝试(与GridBagLayoutGridLayout为外面板)都非常接近解决方案。 问题是您的phonePanelFlowLayout。 在这两种变型,你可以通过用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); 

为了您GridLayout变种,做上述修正:

enter image description here

为了您GridBagLayout变种,做上述修复。
而对于一个更好的外观,你可以通过介绍你的周围元器件一些填充:

c.insets = new Insets(5, 10, 5, 10); // top, left, bottom, right padding 

enter image description here

+0

谢谢,它实际上使它看起来更好,但我在谈论JLabels和JTextFields之间的差距,它们之间的距离太远了,我希望它们更接近一点点并且如果你能够让它看起来更多专业无论如何,PLZ做的帮助:) – Hanzyusuf

+0

@Hanzyusuf我已经添加了一些提示,以更好地看你的'GridBagLayout'变种。感谢兄弟 –

1

对于GridBagLayout中,更新下面的代码行。您正在使用FlowLayout.CENTER将移动号码字段移动到面板中间。

phonePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); 
+0

,没有先看到你的答案。 – Hanzyusuf