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

时间:2023-01-21 15:23:33

What would be the best approach / LayoutManager for a JPanel that needed to display the components shown in the image? (Note that the fields should resize horizontally when the size of the window is changed, but not the labels).

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

I'm currently trying (and struggling) to do it with a GridBagLayout. Is this the correct approach or is there a better way? Should I be trying to divide + conquer the seperate sections maybe?

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

Any thoughts or advice would be gratefully appreciated. :-)

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

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

PS If you read this and there's no image, please bear with me whilst I fix it!

PS如果你读过这个并且没有图像,请在我修复它的同时忍受我!

13 个解决方案

#1


I would look at nesting JPanels. It would be very easy to make each row a separate JPanel and then just stack the JPanels.

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

Otherwise you can use the GridBagLayout. That is the one I use for more control over where components are placed.

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

Using GridBagLayout you can layout a row by incrementing the GridBagConstraint.gridx and then resetting GridBagConstraint.gridx = 0 and GridBagConstraint.gridy++ to move to the next row.

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

#2


I would suggest a third party free layout manager. MigLayout comes to mind (check the example form at the bottom of the linked page), or JGoodies FormLayout, which is especially good at formslike these.

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

The standard layout managers are good, but whoefully inadequate for frequent use for screens like these (the new GroupLayout used by the Matisse designer in Netbeans wasn't built for nothing). The linked layout managers are a lot easier to use and maintain IMHO.

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

#3


I would definitly use DesignGridLayout:

我肯定会使用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);

Disclaimer: I am one of DesignGridLayout authors.

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

#4


If you can use external code, take a look at the JGoodies layout managers.

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

Personally, I find GridBagLayout to be more trouble than it's worth -- to the extent that I've written my own layout managers to avoid it.

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

#5


I personally prefer GroupLayout.

我个人更喜欢GroupLayout。

Even if you're not using a GUI builder you can use the layout by hand and it's fairly simple and straightforward to work with if you understand the concepts.

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

#6


TableLayout would be my choice, you can use constants such as TableLayout.FILL for auto-resizing and specify pixel widths for fixed.

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

TableLayout

#7


Your layout looks like it's essentially composed of "lines". So personally, I would:

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

  • Create a vertical Box with Box.createVerticalBox(); this will stack its components vertically-- in effect, let you add lines
  • 使用Box.createVerticalBox()创建一个垂直框;这将垂直堆叠其组件 - 实际上,您可以添加线条

  • Create a panel for each line: I think you could use a JPanel with a BorderLayout (and the label on the left, text field as the centre component), or again use Box.createHorizontalBox(), and add label and text field to that, with appropriate min/preferred size
  • 为每一行创建一个面板:我认为你可以使用带有BorderLayout的JPanel(左边的标签,文本字段作为中心组件),或者再次使用Box.createHorizo​​ntalBox(),并为其添加标签和文本字段,适当的最小/首选大小

  • You can add a "strut" to the vertical box where you need line separators
  • 您可以在需要行分隔符的垂直框中添加“支柱”

  • Your line with two groups of label/field needs a little bit of special treatment, but it's essentially just a horizontal box with TWO of your "lines" inside it.
  • 你的两个标签/字段组需要一些特殊处理,但它基本上只是一个水平框,里面有两条“线”。

Personally, I never touch GridBagLayout with a barge pole. Maybe it's just me, but I find concurrent algorithms and machine code programming easier than fathoming out GridBagLayout...

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

#8


I used to really hate doing swing layouts until Netbeans came out with their gui builder. You can see a demo here. http://rghosting.co.cc

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

#9


Since Java SE 6 you can use GroupLayout

从Java SE 6开始,您可以使用GroupLayout

It's very easy and looks just like you want.

它非常简单,看起来就像你想要的那样。

For this window:

对于这个窗口:

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

替代文字http://img165.imageshack.us/img165/8237/sampleusinggrouplayoutca2.png

I have this code:

我有这个代码:

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

#10


GridBagLayout is definitely the best choice for this. And NetBeans Matisse is probably the fastest way of achieving this. If you are using another IDE, just copy & paste the auto-generated code.

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

#11


GridBagLayout, of course.

当然是GridBagLayout。

If the form is just this, then you done need more than one JPanel. (If you have buttons, you probably need one more, depending on where/how they are)

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

Field 0 - 4 and 9 will have gridwidth set to 4, others the default (1, but you need not set it to 1)

字段0 - 4和9的网格宽度设置为4,其他字节设置为默认值(1,但不需要将其设置为1)

The 'spaces' between groups of fields can be achieved via insets.

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

(For this layout, at least) I would not suggest third party layout managers. GridBagLayout is not complex. It just takes (a li'l bit of) time to get used to it.

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

Visual Editor + Eclipse can do these for you easily. (I am not very comfortable with Netbeans and its swing development. Tried it, but never fell in love. Maybe, I am too much addicted to Eclipse)

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

#12


I think, that of all standard layouts, GridBagLayout should be best for what you need.

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

You could try something like the following example, where I simplified the complex GridBagConstraints constructor to what I really need by using addToLayout.

您可以尝试类似下面的示例,其中我使用addToLayout将复杂的GridBagConstraints构造函数简化为我真正需要的内容。

If you can use an IDE though, this can really make things easier (Matisse in NetBeans for instance).

如果您可以使用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);
    }
}

#13


You could describe the layout as a HTML table and then use this tool: http://www.onyxbits.de/content/blog/patrick/java-gui-building-gridbaglayout-manager-made-easy

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

To translate the layout into Java code for configuring a GridBagLayout.

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

#1


I would look at nesting JPanels. It would be very easy to make each row a separate JPanel and then just stack the JPanels.

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

Otherwise you can use the GridBagLayout. That is the one I use for more control over where components are placed.

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

Using GridBagLayout you can layout a row by incrementing the GridBagConstraint.gridx and then resetting GridBagConstraint.gridx = 0 and GridBagConstraint.gridy++ to move to the next row.

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

#2


I would suggest a third party free layout manager. MigLayout comes to mind (check the example form at the bottom of the linked page), or JGoodies FormLayout, which is especially good at formslike these.

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

The standard layout managers are good, but whoefully inadequate for frequent use for screens like these (the new GroupLayout used by the Matisse designer in Netbeans wasn't built for nothing). The linked layout managers are a lot easier to use and maintain IMHO.

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

#3


I would definitly use DesignGridLayout:

我肯定会使用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);

Disclaimer: I am one of DesignGridLayout authors.

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

#4


If you can use external code, take a look at the JGoodies layout managers.

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

Personally, I find GridBagLayout to be more trouble than it's worth -- to the extent that I've written my own layout managers to avoid it.

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

#5


I personally prefer GroupLayout.

我个人更喜欢GroupLayout。

Even if you're not using a GUI builder you can use the layout by hand and it's fairly simple and straightforward to work with if you understand the concepts.

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

#6


TableLayout would be my choice, you can use constants such as TableLayout.FILL for auto-resizing and specify pixel widths for fixed.

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

TableLayout

#7


Your layout looks like it's essentially composed of "lines". So personally, I would:

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

  • Create a vertical Box with Box.createVerticalBox(); this will stack its components vertically-- in effect, let you add lines
  • 使用Box.createVerticalBox()创建一个垂直框;这将垂直堆叠其组件 - 实际上,您可以添加线条

  • Create a panel for each line: I think you could use a JPanel with a BorderLayout (and the label on the left, text field as the centre component), or again use Box.createHorizontalBox(), and add label and text field to that, with appropriate min/preferred size
  • 为每一行创建一个面板:我认为你可以使用带有BorderLayout的JPanel(左边的标签,文本字段作为中心组件),或者再次使用Box.createHorizo​​ntalBox(),并为其添加标签和文本字段,适当的最小/首选大小

  • You can add a "strut" to the vertical box where you need line separators
  • 您可以在需要行分隔符的垂直框中添加“支柱”

  • Your line with two groups of label/field needs a little bit of special treatment, but it's essentially just a horizontal box with TWO of your "lines" inside it.
  • 你的两个标签/字段组需要一些特殊处理,但它基本上只是一个水平框,里面有两条“线”。

Personally, I never touch GridBagLayout with a barge pole. Maybe it's just me, but I find concurrent algorithms and machine code programming easier than fathoming out GridBagLayout...

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

#8


I used to really hate doing swing layouts until Netbeans came out with their gui builder. You can see a demo here. http://rghosting.co.cc

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

#9


Since Java SE 6 you can use GroupLayout

从Java SE 6开始,您可以使用GroupLayout

It's very easy and looks just like you want.

它非常简单,看起来就像你想要的那样。

For this window:

对于这个窗口:

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

替代文字http://img165.imageshack.us/img165/8237/sampleusinggrouplayoutca2.png

I have this code:

我有这个代码:

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

#10


GridBagLayout is definitely the best choice for this. And NetBeans Matisse is probably the fastest way of achieving this. If you are using another IDE, just copy & paste the auto-generated code.

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

#11


GridBagLayout, of course.

当然是GridBagLayout。

If the form is just this, then you done need more than one JPanel. (If you have buttons, you probably need one more, depending on where/how they are)

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

Field 0 - 4 and 9 will have gridwidth set to 4, others the default (1, but you need not set it to 1)

字段0 - 4和9的网格宽度设置为4,其他字节设置为默认值(1,但不需要将其设置为1)

The 'spaces' between groups of fields can be achieved via insets.

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

(For this layout, at least) I would not suggest third party layout managers. GridBagLayout is not complex. It just takes (a li'l bit of) time to get used to it.

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

Visual Editor + Eclipse can do these for you easily. (I am not very comfortable with Netbeans and its swing development. Tried it, but never fell in love. Maybe, I am too much addicted to Eclipse)

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

#12


I think, that of all standard layouts, GridBagLayout should be best for what you need.

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

You could try something like the following example, where I simplified the complex GridBagConstraints constructor to what I really need by using addToLayout.

您可以尝试类似下面的示例,其中我使用addToLayout将复杂的GridBagConstraints构造函数简化为我真正需要的内容。

If you can use an IDE though, this can really make things easier (Matisse in NetBeans for instance).

如果您可以使用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);
    }
}

#13


You could describe the layout as a HTML table and then use this tool: http://www.onyxbits.de/content/blog/patrick/java-gui-building-gridbaglayout-manager-made-easy

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

To translate the layout into Java code for configuring a GridBagLayout.

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