如何在Swing中最好地布置这些组件?

时间:2009-01-09 14:36:43

标签: java swing layout

对于需要显示图像中显示的组件的JPanel,最佳方法/ LayoutManager是什么? (请注意,当更改窗口大小时,字段应水平调整大小,而不是标签)。

我目前正在尝试(并且正在努力)使用GridBagLayout。这是正确的方法还是有更好的方法?我是否应该尝试划分+征服单独的部分?

任何想法或建议都将不胜感激。 : - )

http://img261.imageshack.us/img261/2091/layouthb6.png

PS如果您看过这个并且没有图像,请在我修复时请耐心等待!

13 个答案:

答案 0 :(得分:11)

我会看看嵌套JPanels。将每一行设为单独的JPanel然后只堆叠JPanels将非常容易。

否则您可以使用GridBagLayout。这是我用来更好地控制组件放置位置的那个。

使用GridBagLayout,您可以通过递增GridBagConstraint .gridx然后重置GridBagConstraint.gridx = 0GridBagConstraint.gridy++来移动到下一行来布局行。

答案 1 :(得分:4)

我会建议第三方免费布局管理器。我会想到MigLayout(查看链接页面底部的示例表单),或JGoodies FormLayout,这些表格特别擅长。

标准的布局管理器很好,但是对于像这样的屏幕经常使用来说是不够的(马蒂斯设计师在Netbeans中使用的新GroupLayout并非一无所获)。链接的布局管理器更容易使用和维护恕我直言。

答案 2 :(得分:2)

我肯定会使用DesignGridLayout

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);

免责声明:我是Design GridLayout作者之一。

答案 3 :(得分:1)

如果您可以使用外部代码,请查看JGoodies布局管理器。

就我个人而言,我发现GridBagLayout比它的价值更麻烦 - 我已经编写了自己的布局管理器来避免它。

答案 4 :(得分:1)

我个人更喜欢GroupLayout

即使您没有使用GUI构建器,也可以手动使用布局,如果您理解这些概念,则可以非常简单明了地使用。

答案 5 :(得分:0)

TableLayout将是我的选择,您可以使用TableLayout.FILL等常量来自动调整大小并指定固定的像素宽度。

TableLayout

答案 6 :(得分:0)

您的布局看起来基本上由“线条”组成。所以我个人认为:

  • 使用Box.createVerticalBox()创建一个垂直Box;这将垂直堆叠其组件 - 实际上,让你添加行
  • 为每一行创建一个面板:我认为您可以使用带有BorderLayout的JPanel(左侧是标签,文本字段作为中心组件),或者再次使用Box.createHorizo​​ntalBox(),并添加标签和文本字段,具有适当的最小/首选大小
  • 您可以在需要行分隔符的垂直框中添加“支柱”
  • 你的两个标签/字段组需要一些特殊处理,但它基本上只是一个水平方框,里面有两条“线”。

就个人而言,我从未用驳船杆触碰GridBagLayout。也许这只是我,但我发现并发算法和机器代码编程比探索GridBagLayout更容易......

答案 7 :(得分:0)

我曾经非常讨厌做过摇摆布局,直到Netbeans推出他们的gui建设者。你可以在这里看到一个演示。 http://rghosting.co.cc

答案 8 :(得分:0)

自Java SE 6起,您可以使用GroupLayout

这很简单,看起来就像你想要的那样。

对于此窗口:

alt text http://img165.imageshack.us/img165/8237/sampleusinggrouplayoutca2.png

我有这段代码:

    // 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 ) );
    }

答案 9 :(得分:0)

GridBagLayout绝对是最佳选择。而NetBeans Matisse可能是实现这一目标的最快方式。如果您正在使用其他IDE,只需复制&粘贴自动生成的代码。

答案 10 :(得分:0)

GridBagLayout,当然。

如果表单就是这样,那么您需要多个JPanel。 (如果你有按钮,你可能还需要一个按钮,具体取决于它们的位置/方式)

字段0 - 4和9将gridwidth设置为4,其他设置为默认值(1,但您无需将其设置为1)

字段组之间的“空格”可以通过插图实现。

(对于这种布局,至少)我不会建议第三方布局管理器。 GridBagLayout并不复杂。它只需要(一点点)的时间来适应它。

Visual Editor + Eclipse可以轻松地为您完成这些工作。 (我对Netbeans及其摇摆发展不太满意。尝试过,但从未坠入爱河。也许,我太沉迷于Eclipse了)

答案 11 :(得分:0)

我认为,在所有标准布局中,GridBagLayout应该最适合您的需求。

你可以尝试类似下面的例子,我将使用addToLayout将复杂的GridBagConstraints构造函数简化为我真正需要的东西。

如果您可以使用IDE,这可以使事情变得更容易(例如,NetBeans中的Matisse)。

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);
    }
}

答案 12 :(得分:0)

您可以将布局描述为HTML表格,然后使用此工具: http://www.onyxbits.de/content/blog/patrick/java-gui-building-gridbaglayout-manager-made-easy

将布局转换为Java代码以配置GridBagLayout。