![](/img/trans.png)
[英]How to set size of a component in a GridLayout and expand JTextArea while typing?
[英]How to set the component size with GridLayout? Is there a better way?
我正在用 Java 开发一个更大的 GUI,我对布局管理器很生气。
我有一个“设置面板”,其中包含可变数量的 JComponent(标签、按钮、JSpinner、JSlider 等)。 我只想要以下内容:
JLabel <-> JComponent
JLabel <-> JComponent
JLabel <-> JComponent
...
我的面板大小为 500px,这样就有足够的空间容纳很多组件。 不幸的是 GridLayout 总是将组件的大小拉伸到整个面板,即使我为每个组件设置了 MaximumSize。 如果只有两个按钮,每个按钮的高度为 250 像素,这看起来很愚蠢。
我尝试了流布局,但我无法找到正确制作新线条的方法。 我试过BoxLayout.Y_AXIS,但是Components总是居中,Label和Component不在同一行。
有没有人知道 LayoutManagers 正确处理这个问题的好方法?
其他布局的替代方案可能是将带有 GridLayout 的面板放在另一个 FlowLayout 面板中。 这样,您的间距将保持不变,但不会扩展到整个可用空间。
不要将 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; 您可以将它添加到一个 BorderLayout JFrame,在 CENTER 区域:
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);
对于更复杂的布局,我经常使用GridBagLayout ,它更复杂,但这就是代价。 今天,我可能会查看MiGLayout 。
我改用了WrapFlowLayout
JPanel yourPanel = new JPanel(new WrapFlowLayout(10, 10);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.