我正在使用Java开发更大的GUI,我对布局管理器感到愤怒。
我有一个“设置 - 面板”,里面有可变数量的JComponents(标签,按钮,JSpinners,JSliders,......)。我只想要以下内容:
JLabel< - > JComponent的
JLabel< - > JComponent的
JLabel< - > JComponent的
...
我的面板大小为500px,因此有足够的空间容纳很多组件。不幸的是,即使我为每个组件设置了MaximumSize,GridLayout也总是将组件的大小扩展到整个Panel。如果只有两个按钮,每个高度为250px,它看起来很愚蠢。
我尝试了流布局,但我无法找到一种正确制作新线条的方法。我尝试了BoxLayout.Y_AXIS,但组件始终居中,而标签和组件不在同一行。
有没有人知道LayoutManagers可以正确处理这个问题?
答案 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)
您需要尝试以下方法之一:
它们提供了更多功能,更容易获得您想要的功能。
答案 5 :(得分:0)
我改用了 WrapFlowLayout
JPanel yourPanel = new JPanel(new WrapFlowLayout(10, 10);