Java swing布局并没有做我想做的事情

时间:2011-12-13 17:04:10

标签: java swing layout gridbaglayout

我正在尝试编写我认为应该是一个易于指定的对话框,我有一些标签和一些文本区域,然后是一个确定和取消按钮。 在中间我有一个广泛的组件(例如我使用了标签)

 |label|  [combo box]
 |label|  [txtfield]
 |label|  [txtfield]
 |  long label here |


 [btn1]      [btn2]

我正在尝试使用GridBagLayout,它没有做我想要的,我不确定我理解为什么。基本上我希望按钮固定在对话框的底部。

以下代码告诉我如何使用它:

package gui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;

public class GridBagLayoutExample2 extends JFrame {

    private static final long serialVersionUID = -1972347726217162551L;
    final private JLabel lbl1 = new JLabel("LABEL1: ");
    final private JLabel lbl2 = new JLabel("LABEL2: ");
    final private JLabel lbl3 = new JLabel("LABEL3: ");
    final private JTextArea txt1 = new JTextArea(" ");
    final private JComboBox cmb1 = new JComboBox();
    final private JTextArea txt2 = new JTextArea("");
    final private JLabel lblLine = new JLabel("a compenent on all the line");
    final private JButton btnOK = new JButton("OK");
    final private JButton btnCancel = new JButton("Cancel");

    public GridBagLayoutExample2() {

        GridBagLayout bl = new GridBagLayout();
        Container pane = getContentPane();
        pane.setLayout(bl);
        GridBagConstraints c = new GridBagConstraints();
        int r = 0;

        placeComponentInGridBagLayout(lbl1, pane, bl, c, 0, r, null, null, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(cmb1, pane, bl, c, 1, r++, null, null, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(lbl2, pane, bl, c, 0, r, null, null, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(txt2, pane, bl, c, 1, r++, null, null, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(lbl3, pane, bl, c, 0, r, null, null, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(txt1, pane, bl, c, 1, r++, null, null, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(lblLine, pane, bl, c, 0, r++, null, null, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 2, null, null, null);
        placeComponentInGridBagLayout(btnOK, pane, bl, c, 0, null, null, null, GridBagConstraints.PAGE_END, GridBagConstraints.HORIZONTAL, null, null, null, null);
        placeComponentInGridBagLayout(btnCancel, pane, bl, c, 1, null, null, null, GridBagConstraints.PAGE_END, GridBagConstraints.HORIZONTAL, null, null, null, null);

        setSize(new Dimension(850, 350));
        pack();
        setVisible(true);
    }

    public static void placeComponentInGridBagLayout(Component component, Container container, GridBagLayout bagLayout, GridBagConstraints c, Integer gridX, Integer gridY, Double weightX, Double weightY, Integer anchor, Integer fill, Integer ipadx, Integer ipady,
            Integer gridWidth, Integer gridHeight) {
        if (c == null) {
            c = new GridBagConstraints();
        }
        if (gridX != null) {
            c.gridx = gridX;
        }
        if (gridY != null) {
            c.gridy = gridY;
        }
        if (weightX != null) {
            c.weightx = weightX;
        }
        if (weightY != null) {
            c.weighty = weightY;
        }
        if (fill != null) {
            c.fill = fill;
        }
        if (anchor != null) {
            c.anchor = anchor;
        }
        if (ipadx != null) {
            c.ipadx = ipadx;
        }
        if (ipady != null) {
            c.ipady = ipady;
        }
        if (gridWidth != null) {
            c.gridwidth = gridWidth;
        }
        if (gridHeight != null) {
            c.gridheight = gridHeight;
        }
        bagLayout.setConstraints(component, c);

        container.add(component);
    }

}

知道我做错了什么吗? 还有一种更现代的方式在Swing中实现同样的东西吗?

谢谢

4 个答案:

答案 0 :(得分:2)

我可以看到的一个问题是,您的长标签与OK按钮位于同一网格单元格中。 如果您希望按钮锚定在整个对话框的底部,请尝试使用BorderLayout。为按钮创建一个单独的面板,并将其放在BorderLayout.SOUTH中。然后将主要内容放在GridBagLayout的另一个面板中,并将其放在BorderLayout.CENTER.中。按钮与文本组件不完全对齐,但我认为没关系。

答案 1 :(得分:2)

在执行简单表单时,SpringLayout是一个有用的布局管理器。要将组件打包到一行,使用BoxLayout非常有用。

这是一个简单的例子:

enter image description here

以下是代码:

public class LayoutDemo extends JFrame {

    public LayoutDemo() {

        JLabel label1 = new JLabel("label 1");
        JLabel label2 = new JLabel("label 2");
        JLabel label3 = new JLabel("label 3");
        JComboBox<String> combobox = new JComboBox<>();
        JTextField field1 = new JTextField();
        JTextField field2 = new JTextField();

        JPanel formPanel = new JPanel(new SpringLayout());
        formPanel.add(label1);
        formPanel.add(combobox);
        formPanel.add(label2);
        formPanel.add(field1);
        formPanel.add(label3);
        formPanel.add(field2);

        SpringUtilities.makeCompactGrid(formPanel, 3, 2, 2, 2, 3, 3);

        JLabel longLabel = new JLabel("This is a longer label");
        longLabel.setAlignmentX(CENTER_ALIGNMENT);

        JButton button1 = new JButton("Button 1");
        JButton button2 = new JButton("Button 2");

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
        buttonPanel.add(button1);
        buttonPanel.add(Box.createHorizontalGlue());
        buttonPanel.add(button2);

        JPanel basePanel = new JPanel();
        basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.PAGE_AXIS));
        basePanel.add(formPanel);
        basePanel.add(longLabel);

        add(basePanel, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.SOUTH);
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

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

您可能希望使用BorderLayout来例如调整窗口大小时,将formPanel保持在顶部而不拉伸。但是我跳了一下,我给了你一些关于如何将SpringLayout用于表单的想法。

答案 2 :(得分:2)

您可以使用borderlayout和gridlayout的组合,如下所示

enter image description here

package sof;

import java.awt.BorderLayout;
import java.awt.GridLayout;

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

public class CustomLayoutFrame{
    public static void main(String args[]) {
        JFrame frame = new JFrame("Custom Layout Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        JPanel centerPnl = new JPanel();
        centerPnl.setLayout(new BorderLayout());
        JPanel gridLayoutPane = new JPanel(); 
        GridLayout gridLayout = new GridLayout(3,2);
        gridLayoutPane.setLayout(gridLayout);
        gridLayoutPane.add(new JLabel("Label1"));
        gridLayoutPane.add(new JComboBox());
        gridLayoutPane.add(new JLabel("Label2"));
        gridLayoutPane.add(new JTextField());
        gridLayoutPane.add(new JLabel("Label3"));
        gridLayoutPane.add(new JTextField());
        centerPnl.add(gridLayoutPane, BorderLayout.CENTER);
        centerPnl.add(new JLabel("Long label should be going here"), BorderLayout.SOUTH);

        frame.add(centerPnl, BorderLayout.CENTER);

        JPanel bottomPanel = new JPanel();
        bottomPanel.add(new JButton("Button1"));
        bottomPanel.add(new JButton("Button2"));

        frame.add(bottomPanel, BorderLayout.SOUTH);

        frame.setSize(300, 150);
        frame.setVisible(true);
      }
}

答案 3 :(得分:2)

出于这些目的的一个不错的LayoutManager是来自JGoodies的FormLayout