How can I use GroupLayout to create a form?

What is the easiest way to create a form in Java using GroupLayout? With a form, I mean what has text fields with a label in front. Something like that:

Form screenshot

+4
source share
4 answers

Using Group Layout , you can do the following:

package foo; import javax.swing.*; import java.awt.*; public class ChangeIpSettingsDialog extends JDialog { public ChangeIpSettingsDialog( Frame owner ) { super( owner, true ); setContentPane( createContent() ); } private Container createContent() { JPanel result = new JPanel(); result.setBorder( BorderFactory.createEmptyBorder( 10, 10, 10, 10 ) ); // Create the layout GroupLayout layout = new GroupLayout( result ); result.setLayout( layout ); layout.setAutoCreateGaps( true ); // Create the components we will put in the form JLabel ipAddressLabel = new JLabel( "IP Address:" ); JTextField ipAddressTextField = new JTextField( 20 ); JLabel subnetLabel = new JLabel( "Subnet:" ); JTextField subnetTextField = new JTextField( 20 ); JLabel gatewayLabel = new JLabel( "Gateway:" ); JTextField gatewayTextField = new JTextField( 20 ); // Horizontally, we want to align the labels and the text fields // along the left (LEADING) edge layout.setHorizontalGroup( layout.createSequentialGroup() .addGroup( layout.createParallelGroup( GroupLayout.Alignment.LEADING ) .addComponent( ipAddressLabel ) .addComponent( subnetLabel ) .addComponent( gatewayLabel ) ) .addGroup( layout.createParallelGroup( GroupLayout.Alignment.LEADING ) .addComponent( ipAddressTextField ) .addComponent( subnetTextField ) .addComponent( gatewayTextField ) ) ); // Vertically, we want to align each label with his textfield // on the baseline of the components layout.setVerticalGroup( layout.createSequentialGroup() .addGroup( layout.createParallelGroup( GroupLayout.Alignment.BASELINE ) .addComponent( ipAddressLabel ) .addComponent( ipAddressTextField ) ) .addGroup( layout.createParallelGroup( GroupLayout.Alignment.BASELINE ) .addComponent( subnetLabel ) .addComponent( subnetTextField ) ) .addGroup( layout.createParallelGroup( GroupLayout.Alignment.BASELINE ) .addComponent( gatewayLabel ) .addComponent( gatewayTextField ) ) ); return result; } public static void main( String[] args ) { ChangeIpSettingsDialog dialog = new ChangeIpSettingsDialog( null ); dialog.pack(); dialog.setVisible( true ); } } 
+6
source

Or you throw away GroupLayout and use FormLayout , which was basically designed as a layout for ... forms FormLayout

+4
source

Just use the GUI editor loaded into NetBeans called Matisse. This is the most amazing graphic editor I've ever seen. It works very well, and all of your windows that you create are subject to change.

This editor creates code using GroupLayout.

A clone of Matisse is also available as an Eclipse plugin, but I don't think it's free. Take a look at this here (Disclaimer: I have never used this plugin before, so I can’t say if it is of the same quality as the original Matisse)
http://marketplace.eclipse.org/content/swing-gui-designer

Here is a good screenshot:

enter image description here

+3
source

An example of how you could achieve a demonstrated layout using a GridBagLayout :

 class Main extends JFrame implements Runnable { JLabel lblIpAddress = new JLabel(); JLabel lblSubnet = new JLabel(); JLabel lblGateway = new JLabel(); JTextField txtIpAddress = new JTextField(); JTextField txtSubnet = new JTextField(); JTextField txtGateway = new JTextField(); public void run() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container content = this.getContentPane(); lblIpAddress.setText("IP Address"); lblIpAddress.setLabelFor(txtIpAddress); lblSubnet.setText("Subnet"); lblSubnet.setLabelFor(txtSubnet); lblGateway.setText("Gateway"); lblGateway.setLabelFor(txtGateway); GridBagLayout layout = new GridBagLayout(); content.setLayout(layout); content.add(lblIpAddress, newLabelConstraints()); content.add(txtIpAddress, newTextFieldConstraints()); content.add(lblSubnet, newLabelConstraints()); content.add(txtSubnet, newTextFieldConstraints()); content.add(lblGateway, newLabelConstraints()); content.add(txtGateway, newTextFieldConstraints()); // Add a spacer to push all the form rows to the top of the window. GridBagConstraints spacer = new GridBagConstraints(); spacer.fill=BOTH; spacer.gridwidth=REMAINDER; content.add(new JPanel(), spacer); // make sure you can't "cut off" the controls when making the window smaller this.pack(); this.setMinimumSize(this.getSize()); this.setVisible(true); } private GridBagConstraints newConstraints() { GridBagConstraints c = new GridBagConstraints(); // a little breathing room c.insets = new Insets(2, 2, 2, 2); return c; } private GridBagConstraints newLabelConstraints() { GridBagConstraints c = newConstraints(); // right-align labels c.anchor = BASELINE_TRAILING; // do not grow labels c.weightx=0.0; return c; } private GridBagConstraints newTextFieldConstraints() { GridBagConstraints c = newConstraints(); c.anchor = BASELINE; // grow text fields horizontally c.weightx=1.0; c.fill=HORIZONTAL; // text fields end a row c.gridwidth=REMAINDER; return c; } public static void main(String[] args) { SwingUtilities.invokeLater(new Main()); } } 

The main drawback is that if you want to say, add the right-aligned row of buttons (for example: "OK" and "Cancel") at the bottom, where the buttons do not match anything else, you'd need to use a nested JPanel. (Or do something like a form that has a separate column for each button, and then the text field fields cover all of these columns and an extra separation column. This is pretty inconsistent, and it will negatively affect readability. I believe MiGLayout that is the third-party layout manager can handle this situation accurately, because since it allows you to group / overlap grid cells and split the merged cell.)

+3
source

All Articles