简体   繁体   English

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

[英]How can I best lay out these components in Swing?

What would be the best approach / LayoutManager for a JPanel that needed to display the components shown in the image? 对于需要显示图像中显示的组件的JPanel,最佳方法/ LayoutManager是什么? (Note that the fields should resize horizontally when the size of the window is changed, but not the labels). (请注意,当更改窗口大小时,字段应水平调整大小,而不是标签)。

I'm currently trying (and struggling) to do it with a GridBagLayout. 我目前正在尝试(并且正在努力)使用GridBagLayout。 Is this the correct approach or is there a better way? 这是正确的方法还是有更好的方法? Should I be trying to divide + conquer the seperate sections maybe? 我应该试图分裂+征服单独的部分吗?

Any thoughts or advice would be gratefully appreciated. 任何想法或建议将不胜感激。 :-) :-)

http://img261.imageshack.us/img261/2091/layouthb6.png 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如果你读到这个并且没有图像,请在我解决时请耐心等待!

I would look at nesting JPanels . 我会看看嵌套JPanels It would be very easy to make each row a separate JPanel and then just stack the JPanels . 将每一行作为单独的JPanel然后只是堆叠JPanels将非常容易。

Otherwise you can use the GridBagLayout . 否则,您可以使用GridBagLayout That is the one I use for more control over where components are placed. 这是我用来更好地控制组件放置位置的那个。

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 = 0GridBagConstraint.gridy++以移动到下一行。

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). 标准的布局管理器很好,但是对于像这样的屏幕频繁使用而言是不够的(马蒂斯设计师在Netbeans中使用的新GroupLayout并非一无所获)。 The linked layout managers are a lot easier to use and maintain IMHO. 链接的布局管理器更容易使用和维护恕我直言。

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作者之一。

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比它的价值更麻烦 - 我已经编写了自己的布局管理器来避免它。

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构建器,也可以手动使用布局,如果您理解这些概念,则可以非常简单明了地使用。

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 TableLayout

Your layout looks like it's essentially composed of "lines". 您的布局看起来基本上由“线”组成。 So personally, I would: 所以我个人认为:

  • Create a vertical Box with Box.createVerticalBox(); 使用Box.createVerticalBox()创建一个垂直框; this will stack its components vertically-- in effect, let you add lines 这将垂直堆叠其组件 - 实际上,您可以添加线条
  • 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. 就个人而言,我从来没有用驳船杆接触GridBagLayout。 Maybe it's just me, but I find concurrent algorithms and machine code programming easier than fathoming out GridBagLayout... 也许这只是我,但我发现并发算法和机器代码编程比理解GridBagLayout更容易......

I used to really hate doing swing layouts until Netbeans came out with their gui builder. 我曾经非常讨厌做过摇摆布局,直到Netbeans推出他们的gui建设者。 You can see a demo here. 你可以在这里看到一个演示。 http://rghosting.co.cc http://rghosting.co.cc

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

GridBagLayout is definitely the best choice for this. GridBagLayout绝对是最好的选择。 And NetBeans Matisse is probably the fastest way of achieving this. NetBeans Matisse可能是实现这一目标的最快方式。 If you are using another IDE, just copy & paste the auto-generated code. 如果您使用的是其他IDE,只需复制并粘贴自动生成的代码即可。

GridBagLayout , of course. 当然是GridBagLayout

If the form is just this, then you done need more than one JPanel . 如果表单只是这个,那么你需要多个JPanel (If you have buttons, you probably need one more, depending on where/how they are) (如果你有按钮,你可能还需要一个按钮,具体取决于它们的位置/方式)

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的gridwidth设置为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. GridBagLayout并不复杂。 It just takes (a li'l bit of) time to get used to it. 它只需要(一点点)的时间来适应它。

Visual Editor + Eclipse can do these for you easily. Visual Editor + Eclipse可以轻松地为您完成这些工作。 (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) (我对Netbeans及其摇摆开发不太满意。尝试过,但从未坠入爱河。也许,我太沉迷于Eclipse)

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

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。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM