如何使用GridLayout设置组件大小?有没有更好的办法?

时间:2011-01-15 13:47:31

标签: java user-interface swing layout

我正在使用Java开发更大的GUI,我对布局管理器感到愤怒。

我有一个“设置 - 面板”,里面有可变数量的JComponents(标签,按钮,JSpinners,JSliders,......)。我只想要以下内容:

JLabel< - > JComponent的

JLabel< - > JComponent的

JLabel< - > JComponent的

...

我的面板大小为500px,因此有足够的空间容纳很多组件。不幸的是,即使我为每个组件设置了MaximumSize,GridLayout也总是将组件的大小扩展到整个Panel。如果只有两个按钮,每个高度为250px,它看起来很愚蠢。

我尝试了流布局,但我无法找到一种正确制作新线条的方法。我尝试了BoxLayout.Y_AXIS,但组件始终居中,而标签和组件不在同一行。

有没有人知道LayoutManagers可以正确处理这个问题?

6 个答案:

答案 0 :(得分:14)

其他布局的替代方法可能是将面板与GridLayout放在另一个面板FlowLayout中。这样,您的间距将保持不变,但不会扩展到整个可用空间。

答案 1 :(得分:4)

不要将GridLayout用于不应该做的事情。听起来像GridBagLayout更适合你,无论是那个还是MigLayout(尽管你不得不首先下载它,因为它不是标准Java的一部分)。或者将布局管理器(例如BoxLayout用于行和GridLayout)组合以容纳所有行。

例如,使用GridBagLayout:

import java.awt.*;
import javax.swing.*;

public class LayoutEg1 extends JPanel{
    private static final int ROWS = 10;

    public LayoutEg1() {
        setLayout(new GridBagLayout());
        for (int i = 0; i < ROWS; i++) {
            GridBagConstraints gbc = makeGbc(0, i);
            JLabel label = new JLabel("Row Label " + (i + 1));
            add(label, gbc);

            JPanel panel = new JPanel();
            panel.add(new JCheckBox("check box"));
            panel.add(new JTextField(10));
            panel.add(new JButton("Button"));
            panel.setBorder(BorderFactory.createEtchedBorder());
            gbc = makeGbc(1, i);
            add(panel, gbc);
        }
    }

    private GridBagConstraints makeGbc(int x, int y) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.weightx = x;
        gbc.weighty = 1.0;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.anchor = (x == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        return gbc;
    }

    private static void createAndShowUI() {
        JFrame frame = new JFrame("Layout Eg1");
        frame.getContentPane().add(new LayoutEg1());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

答案 2 :(得分:4)

对于更复杂的布局,我经常使用GridBagLayout,这更复杂,但这是价格。今天,我可能会查看MiGLayout

答案 3 :(得分:3)

在我的项目中,我设法使用GridLayout,结果非常稳定,没有闪烁,并且具有完美的垂直滚动条。

首先我为设置创建了一个JPanel;在我的例子中,它是一个网格,每个参数和两列有一行:左列用于标签,右列用于组件。我相信你的情况类似。

JPanel yourSettingsPanel = new JPanel();
yourSettingsPanel.setLayout(new GridLayout(numberOfParams, 2));

然后我通过迭代我的参数并在添加JLabel和添加组件之间交替来填充此面板。

for (int i = 0; i < numberOfParams; ++i) {
    yourSettingsPanel.add(labels[i]);
    yourSettingsPanel.add(components[i]);
}

为了防止YourSettingsPanel扩展到整个容器,我首先将它包装在虚拟面板的北部区域,我称之为northOnlyPanel。

JPanel northOnlyPanel = new JPanel();
northOnlyPanel.setLayout(new BorderLayout());
northOnlyPanel.add(yourSettingsPanel, BorderLayout.NORTH);

最后,我将northOnlyPanel包装在一个JScrollPane中,它应该在任何地方表现得非常好。

JScrollPane scroll = new JScrollPane(northOnlyPanel,
                                     JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                     JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

很可能你想在JFrame中显示这个扩展的JScrollPane;您可以将它添加到CENTER区域中的BorderLayout JFrame:

window.add(scroll, BorderLayout.CENTER);

在我的情况下,我将它放在GridLayout(1,2)面板的左栏,我使用右列显示每个参数的上下文帮助。

JTextArea help = new JTextArea();
help.setLineWrap(true);
help.setWrapStyleWord(true);
help.setEditable(false);

JPanel split = new JPanel();
split.setLayout(new GridLayout(1, 2));
split.add(scroll);
split.add(help);

答案 4 :(得分:2)

您需要尝试以下方法之一:

  1. GridBagLayout
  2. MigLayout
  3. SpringLayout
  4. 它们提供了更多功能,更容易获得您想要的功能。

答案 5 :(得分:0)

我改用了 WrapFlowLayout

JPanel yourPanel = new JPanel(new WrapFlowLayout(10, 10);