【问题标题】:Java GridBagLayout components positioningJava GridBagLayout 组件定位
【发布时间】:2014-06-02 13:20:08
【问题描述】:

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

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);

看起来像这样:

我只需要更靠近按钮的标签,但我可以给它们的最接近的 x 值似乎是 1,它似乎相对定位 - 有没有办法可以绝对定位它们?

【问题讨论】:

  • 您可以将按钮和标签的对齐方式分别更改为左右对齐,这会使它们更接近。另外,我建议您为每个组件使用不同的 GridBagConstraints 实例。

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


【解决方案1】:

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

  1. 将约束的fill 字段设置为HORIZONTAL,并将标签对齐方式设置为WEST(或LINE_START,无论您使用哪种方式),并加上一个正权重x。这将使标签和按钮占据所有可用的水平空间,并且它们的对齐方式意味着文本将位于左边缘。
  2. 使用anchor 字段。这控制了较小组件在其单元格中的位置 - 您可能希望按钮居右或居中对齐,而标签居左。
  3. 如果您希望标签靠近按钮而不改变任何大小,那么网格将不能很好地为您服务,因为“输入句子”字段太长。您可能希望为顶部和底部设置 2 个不同的面板(BorderLayout much?),或者更智能的布局管理器

【讨论】:

  • 将约束文件设置为水平工作,谢谢!
【解决方案2】:

上面的窗口是用下面的代码生成的,它使用了 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 行更改为图片下方显示的行来生成的,关键是有几种相当简单的方法可以调整布局以使其看起来像你想要的那样——如何靠在一起和垂直对齐的方式,有两个问题。

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 类提供了灵活性。

【讨论】:

  • 有些人认为“外面”的包比@SplungeBob 提供的包(Fill、Anchor、GBConstraints)更好;自从 Splunge 提供以来,上面的那个恰好是我调查过的唯一一个。对我来说效果很好。
【解决方案3】:

尝试使用 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();
}

}

【讨论】:

  • 很抱歉,我看不到设置 gridy 或 gridheight 将如何解决 OP 问题或水平距离。
【解决方案4】:

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

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

  • 体重x
  • 锚点

这两个属性都可以帮助您(在 JLabel 上还有一个使用填充和文本对齐方式的选项,但它不太优雅,因为您的布局取决于组件属性和布局属性):

以及最终的结果:

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);
    }
}

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2014-03-23
    • 2012-10-13
    • 2012-09-27
    • 1970-01-01
    相关资源
    最近更新 更多