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

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

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

JLabel JComponent

JLabel JComponent

JLabel JComponent

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

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

有没有人知道LayoutManagers有一个好的和简短的方法来正确处理这个问题?

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

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

不要将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(); } }); } } 

在我的项目中,我设法使用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); 

您需要尝试以下之一:

  1. GridBagLayout的
  2. MigLayout
  3. SpringLayout中

它们提供了更多function,更容易获得您想要的function。