tags:

views:

780

answers:

13

Hi All,

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

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?

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

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

+11  A: 

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

Otherwise you can use the 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.

jjnguy
+1 : I also would use the GridBagLayout!
Markus Lausberg
+1 for GridBagLayout
Steve S
yup, this is pretty gridbag-able. JGoodies formlayout would be ok, but i've had some "iffy" results with that, especially if the size or controls change dynamically.
John Gardner
Hooray for GridBagLayout! \o/ I prefer to use the full GridBagConstraints constructor when adding new components, though. That makes it easier to insert additional components between existings ones without having to worry about “leftovers” in the constraints object.
Bombe
I think that the Constraints work well with default values most of the time. Just changing gridx/y and gridheight/width usually do it for me.
jjnguy
+1  A: 

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

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.

kdgregory
+1  A: 

I personally prefer 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.

+4  A: 

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.

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.

Robin
I had never heard of MigLayout but it looks great! I'm definitely going to give it a try now.
dancavallaro
I wouldn't really introduce a third-party layout manager when GridBagLayout is perfectly capable of solving this.
cletus
A: 

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

TableLayout

A: 

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
  • 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
  • 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...

Neil Coffey
Thanks, but I think this will have the problem of not automatically vertically aligning the labels....?
cagcowboy
You can set the labels to have a fixed size.
Neil Coffey
Neil, GridBagLayout isn’t that hard to use. I have come across a couple of occasions where a GridBagLayout was easier to implement than any other combination of LayoutManagers. Okay, the GridBagConstraints constructor is intimidating, but you know, great power, great responsibility and stuff. :)
Bombe
A: 

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

A: 
OscarRyz
A: 

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.

pek
A: 

GridBagLayout, of course.

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)

Field 0 - 4 and 9 will have gridwidth set to 4, others the default (1, but you need not set it to 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.

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)

Nivas
+1  A: 

I would definitly use 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.

jfpoilpret
A: 

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

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

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

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);
    }
}
Peter Lang
A: 

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

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