Java GridBagLayout组件定位

时间:2014-06-02 13:20:09

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

我试图制作一个简单的布局,标签位于按钮旁边并关闭。 这是我添加它们的顺序:

add(label_1, cons);

cons.gridx = 1;
add(textArea,cons);

cons.gridx = 0;
cons.gridy = 2;
add(button_1,cons);

cons.gridx= 0;
cons.gridy = 4;
add(button_2,cons);

cons.gridx=0;
cons.gridy=6;
add(button_3,cons);

cons.gridx = 1;
cons.gridy = 2;
add(label_2, cons);       

cons.gridy=4;
add(label_3,cons);

cons.gridy=6;
add(label_4,cons);

看起来像这样:

enter image description here

我只需要将标签放在靠近按钮的地方,但看起来我能给它们的最接近的x值是1,它似乎相对定位 - 有没有办法让我绝对定位它们?

4 个答案:

答案 0 :(得分:3)

您可以使用多种选项,具体取决于您希望的样子,所有选项都在已发布的tutorial中进行了解释。

  1. 将约束的fill字段设置为HORIZONTAL,并将标签对齐到WEST(或LINE_START,无论您习惯的话),以及积极的体重。这将使标签和按钮占据所有可用的水平空间,它们的对齐意味着文本将位于左边缘。
  2. 使用anchor字段。这可以控制较小组件在其单元格中的位置 - 您可能希望按钮的右对齐或中央对齐,并留给标签。
  3. 如果您希望标签靠近按钮而不改变任何尺寸,那么网格将无法很好地为您服务,因为“输入句子”字段太长。您可能希望顶部和底部有两个不同的面板(BorderLayout多少?),或者更智能的布局管理器

答案 1 :(得分:2)

enter image description here

上面的窗口是使用下面的代码生成的,它使用了3个外部类。

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class GridBagLayout{

  JFrame      frame;

  public GridBagLayout() {
    initComponents();
  }

  private void initComponents(){
    JTextField  text  = new JTextField("",10);
    JButton     but1  = new JButton("button 1");
    JButton     but2  = new JButton("button 2");
    JButton     but3  = new JButton("button 3");
    JLabel      lab0  = new JLabel("Enter a sentence");
    JLabel      lab1  = new JLabel("test 1");
    JLabel      lab2  = new JLabel("test 2");
    JLabel      lab3  = new JLabel("test 3");

    frame  = new JFrame("TestGridBagLayout");
    frame.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    frame.setLayout(new java.awt.GridBagLayout());

    frame.add(lab0,   new GBConstraints(0,0));
    frame.add(text,   new GBConstraints(1,0));

    frame.add(but1,   new GBConstraints(0,1));
    frame.add(lab1,   new GBConstraints(1,1));

    frame.add(but2,   new GBConstraints(0,2));
    frame.add(lab2,   new GBConstraints(1,2));

    frame.add(but3,   new GBConstraints(0,3));
    frame.add(lab3,   new GBConstraints(1,3));

    frame.setVisible(true);
    frame.pack();
  }  

  public static void main(String[] args) {
    new GridBagLayout();
  }
}

下面的窗口是通过将上面的new GBConstraints行更改为图片下方显示的行来生成的,关键是有几种相当简单的方法可以调整布局,使其看起来像您想要的那样 - - 对于两个问题,如何靠近以及如何垂直对齐。

enter image description here

frame.add(lab0,   new GBConstraints(0,0).anchor(EAST));
frame.add(text,   new GBConstraints(1,0).ipad(100, 0).anchor(WEST));

frame.add(but1,   new GBConstraints(0,1));
frame.add(lab1,   new GBConstraints(1,1));

frame.add(but2,   new GBConstraints(0,2));
frame.add(lab2,   new GBConstraints(1,2).insets(15, -15, 5, 5));

frame.add(but3,   new GBConstraints(0,3).anchor(EAST));
frame.add(lab3,   new GBConstraints(1,3).anchor(WEST));

请注意,上面的第二行有两个约束添加到GBConstraint; @SplungeBob在this thread中提供的FillAnchorGBConstraints类提供了灵活性。

答案 2 :(得分:1)

尝试使用GridBagConstraints的以下属性:gridheight和weighty。我会尝试修改你的代码的这一部分:

cons.gridx = 1;
cons.gridy = 2;
cons.weighty = 0;
add(label_2, cons);

有关详细信息:http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

检查此代码,这可能会对您有所帮助:

public class GUITest {
private JPanel mainPanel;   
private JLabel l1;
private JLabel l2;
private JLabel l3;
private JButton b1;
private JButton b2;
private JTextField text;
private JFrame guiFrame;
private Container pane;

public GUITest() {
    // TODO Auto-generated constructor stub
    guiFrame = new JFrame();
    pane = new Container();
    pane.setLayout(new BorderLayout());
    //make sure the program exits when the frame closes
    guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    guiFrame.setTitle("Example GUI");
    guiFrame.setSize(300,250);

    mainPanel = new JPanel(new GridBagLayout());

    l1 = new JLabel("Label 1");
    b1 = new JButton("Button 1");
    l2 = new JLabel("Label 2");
    b2 = new JButton("Button 2");
    l3 = new JLabel("Enter a sentence");
    text = new JTextField(50);

    GridBagConstraints c = new GridBagConstraints();
    c.gridheight = 1;
    c.gridwidth = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0;
    c.weighty = 0;
    Insets i = new Insets(5, 5, 5, 5);
    c.insets = i;

    c.gridx= 0;
    c.gridy = 0;
    mainPanel.add(l3,c);

    c.gridx = 1;
    c.gridy = 0;        
    mainPanel.add(text, c);

    c.gridx = 0;
    c.gridy = 1;
    mainPanel.add(b1,c);

    c.gridx = 1;
    c.gridy = 1;
    mainPanel.add(l1,c);

    c.gridx= 0;
    c.gridy = 2;
    mainPanel.add(b2,c);

    c.gridx = 1;
    c.gridy = 2;
    mainPanel.add(l2, c);



    pane.add(mainPanel,BorderLayout.NORTH);
    guiFrame.setContentPane(pane);
    guiFrame.setVisible(true);

}

public static void main(String[] args) {
    GUITest g = new GUITest();
}

}

答案 3 :(得分:1)

使用GridBagLayout时,使用相对定位总是更容易维护。

现在关于左/右定位,您需要正确使用

  • 的weightx

这两个属性都会帮助你(在JLabel上有另一个选项使用填充和文本对齐方式,但它的优雅程度要低得多,因为你的布局取决于组件属性和布局属性):

最终结果是:

enter image description here

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class TestGridBagLayout {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestGridBagLayout().initUI();
            }
        });
    }

    private JLabel label_1 =  new JLabel("Enter a sentence");
    private JLabel label_2 =  new JLabel("test");
    private JLabel label_3 =  new JLabel("test");
    private JLabel label_4 =  new JLabel("test");
    private JTextField textArea = new JTextField(15);
    private JButton button_1 = new JButton("button 1");
    private JButton button_2 = new JButton("button 2");
    private JButton button_3 = new JButton("button 3");

    protected void initUI() {
        JFrame frame= new JFrame(TestGridBagLayout.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints left = new GridBagConstraints();
        left.anchor = GridBagConstraints.EAST;
        left.weightx = 1;
        left.insets = new Insets(5, 5, 5, 5);
        GridBagConstraints right = new GridBagConstraints();
        right.weightx=1;
        right.gridwidth = GridBagConstraints.REMAINDER;
        right.anchor = GridBagConstraints.WEST;
        right.insets = new Insets(5, 5, 5, 5);

        panel.add(label_1, left);
        panel.add(textArea,right);

        panel.add(button_1 ,left);
        panel.add(label_2, right);

        panel.add(button_2,left);
        panel.add(label_3,right);

        panel.add(button_3,left);
        panel.add(label_4,right);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}