Java 如何在Swing中最好地布置这些组件?
对于需要显示图像中所示组件的JPanel,最佳的方法/布局管理器是什么? (请注意,更改窗口大小时,字段应水平调整大小,但标签不应如此) 我目前正在尝试(并且正在努力)使用GridBagLayout来完成它。这是正确的方法还是有更好的方法?也许我应该试着去分割并征服那些分开的部分吗 如有任何想法或建议,将不胜感激。:-)Java 如何在Swing中最好地布置这些组件?,java,swing,layout,Java,Swing,Layout,对于需要显示图像中所示组件的JPanel,最佳的方法/布局管理器是什么? (请注意,更改窗口大小时,字段应水平调整大小,但标签不应如此) 我目前正在尝试(并且正在努力)使用GridBagLayout来完成它。这是正确的方法还是有更好的方法?也许我应该试着去分割并征服那些分开的部分吗 如有任何想法或建议,将不胜感激。:-) PS如果你读了这篇文章,没有图片,请在我修复它的时候忍受我 我会看看嵌套JPanels。很容易将每一行变成一个单独的JPanel,然后只堆叠JPanel 否则,您可以使用。这
PS如果你读了这篇文章,没有图片,请在我修复它的时候忍受我 我会看看嵌套
JPanels
。很容易将每一行变成一个单独的JPanel
,然后只堆叠JPanel
否则,您可以使用。这就是我用来更好地控制组件放置位置的方法
使用
GridBagLayout
可以通过增加.gridx
然后重置GridBagConstraint.gridx=0
和GridBagConstraint.gridy++
移动到下一行来布局行。如果可以使用外部代码,请查看布局管理器
就我个人而言,我发现GridBagLayout的麻烦比它的价值还多——我已经编写了自己的布局管理器来避免它。我个人更喜欢它
即使您不使用GUI构建器,也可以手动使用布局,如果您理解这些概念,使用布局非常简单明了。我建议使用无第三方的布局管理器。出现在脑海中(查看链接页面底部的示例表单),或者,哪个表单特别擅长这些表单
标准的布局管理器很好,但是对于这样的屏幕来说,完全不适合频繁使用(Matisse designer在Netbeans中使用的新的GroupLayout不是免费构建的)。链接的布局管理器更易于使用和维护IMHO。我可以选择TableLayout,您可以使用诸如TableLayout.FILL之类的常量来自动调整大小,并指定固定的像素宽度
您的布局看起来基本上是由“线”组成的。因此,我个人认为:
- 使用Box.createVerticalBox()创建垂直框;这将垂直堆叠其组件——实际上,您可以添加行
- 为每一行创建一个面板:我认为您可以使用带有边框布局的JPanel(左侧的标签,文本字段作为中心组件),或者再次使用Box.createHorizontalBox(),并将标签和文本字段添加到其中,并使用适当的最小/首选大小
- 您可以在需要线分隔符的垂直框中添加“支柱”
- 带有两组标签/字段的行需要进行一些特殊处理,但它本质上只是一个水平框,其中包含两条“行”
就我个人而言,我从来没有用驳船杆子碰过GridBagLayout。也许只有我一个人,但我发现并发算法和机器代码编程比研究GridBagLayout更容易…在Netbeans的gui构建器问世之前,我一直非常讨厌使用swing布局。你可以在这里看到一个演示 既然您可以使用JavaSE6 这很简单,看起来就像你想要的 对于此窗口: 我有以下代码:
// Layout the components using the new GroupLayout added
// in java 1.6.
// Adding to the main frame
private void layoutComponents(){
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
SequentialGroup hGroup = layout.createSequentialGroup();
JLabel nameLbl = new JLabel("Name");
JLabel countLbl = new JLabel("Amount");
JLabel dateLbl = new JLabel("Date(dd/MM/yy)");
hGroup.addGroup(layout.createParallelGroup().
addComponent(nameLbl).
addComponent(countLbl).
addComponent(dateLbl).
addComponent(go));
hGroup.addGroup(layout.createParallelGroup().
addComponent(name).
addComponent(count).
addComponent(date));
layout.setHorizontalGroup(hGroup);
SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(nameLbl).
addComponent(name));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(countLbl).
addComponent(count));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(dateLbl).
addComponent(date));
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
addComponent(go));
layout.setVerticalGroup(vGroup);
frame.add( panel , BorderLayout.NORTH );
frame.add( new JScrollPane( textArea ) );
}
这绝对是最好的选择。这可能是实现这一目标的最快方式。如果您使用的是另一个IDE,只需复制并粘贴自动生成的代码。
GridBagLayout
如果表单就是这样,那么您确实需要不止一个JPanel
。(如果您有按钮,可能还需要一个,具体取决于按钮的位置/方式)
字段0-4和9将gridwidth
设置为4,其他字段为默认值(1,但无需将其设置为1)
字段组之间的“空格”可以通过插图实现
(至少对于这种布局)我不建议使用第三方布局管理器<代码>网格布局并不复杂。只是需要(一点点)时间来适应它
visualeditor+Eclipse可以轻松地完成这些任务。(我对Netbeans及其swing开发不太满意。尝试过,但从未坠入爱河。也许,我太沉迷于Eclipse了)我肯定会使用:
免责声明:我是DesignGridLayout的作者之一。我认为,在所有标准布局中,GridBagLayout应该最适合您的需要 您可以尝试下面的示例,其中我使用addToLayout将复杂的GridBagConstraints构造函数简化为我真正需要的 如果您可以使用IDE,这确实可以让事情变得更简单(例如NetBeans中的Matisse)
您可以将布局描述为HTML表,然后使用以下工具:
将布局转换为配置GridBagLayout的Java代码。我从未听说过MigLayout,但它看起来很棒!我现在肯定要尝试一下。如果GridBagLayout完全能够解决这个问题,我不会真的引入第三方布局管理器。谢谢,但我认为这会有一个问题,即不会自动垂直对齐标签…?你可以将标签设置为固定大小。Neil,GridBagLayout使用起来并不难。我曾经遇到过两种情况,GridBagLayout比任何其他布局管理器组合都更容易实现。好吧,GridBagConstraints构造器很吓人,但是你知道,强大的力量,巨大的责任感等等是的,这真是太棒了。JGoodies formlayout可以,但我有一些“不确定”的结果,特别是当大小或控件动态变化时。GridBagLayout万岁\不过,在添加新组件时,我更喜欢使用完整的GridBagConstraints构造函数。这使得在现有组件之间插入其他组件更容易,而不必担心
DesignGridLayout layout = new DesignGridLayout(this);
layout.row().grid(label0).add(field0);
layout.emptyRow();
layout.row().grid(label1).add(field1);
layout.row().grid(label2).add(field2);
layout.row().grid(label3).add(field3);
layout.row().grid(label4).add(field4);
layout.emptyRow();
layout.row().grid(label5).add(field5).grid(label6).add(field6);
layout.row().grid(label7).add(field7).grid(label8).add(field8);
layout.emptyRow();
layout.row().grid(label9).add(field9);
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GridBagLayoutTest extends JPanel {
public GridBagLayoutTest() {
setLayout(new GridBagLayout());
addToLayout(new JLabel( "Label 0" ), 0, 0, 0d, 1);
addToLayout(new JTextField( "Field 0" ), 0, 1, 1d, 4);
addToLayout(new JLabel( "*" ), 0, 5, 0d, 1);
addToLayout(new JPanel() , 1, 0, 0d, 1);
addToLayout(new JLabel( "Label 1" ), 2, 0, 0d, 1);
addToLayout(new JTextField( "Field 1" ), 2, 1, 1d, 4);
addToLayout(new JLabel( "*" ), 2, 5, 0d, 1);
addToLayout(new JLabel( "Label 2" ), 3, 0, 0d, 1);
addToLayout(new JTextField( "Field 2" ), 3, 1, 1d, 1);
addToLayout(new JLabel( "*" ), 3, 2, 0d, 1);
addToLayout(new JLabel( "Label 3" ), 3, 3, 0d, 1);
addToLayout(new JTextField( "Field 3" ), 3, 4, 1d, 1);
addToLayout(new JLabel( "*" ), 3, 5, 0d, 1);
}
private void addToLayout(java.awt.Component comp, int y, int x, double weightx, int gridwidth) {
add(comp, new GridBagConstraints(x, y, gridwidth, 1, weightx, 0d,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new java.awt.Insets(2, 4, 2, 4), 0, 0 ) );
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GridBagLayoutTest());
frame.setSize(800, 600);
frame.setVisible(true);
}
}