I use GridBagLyout quite a lot, but like many others before me, I quickly found out it can be quite verbose. There are many examples on the web of how users wrote utility methods and/or classes to help them generate GBL code. I’ll show you what I do.
1) First, I created 2 enums that are wrappers for the anchor and fill GridBagConstraints fields. I prefer the type checking of enums vs. ints, and it also allows me to write more concise code (as you’ll see later). And yes, I still use the older “directional” values for Anchor. I could never quite get used to the preferred values of PAGE_START
and the like. Use whatever you prefer.
Anchor.java:
package gbl; import java.awt.*; /** * Convenience enum that aliases out all possible values for the * GridBagConstraints anchor property. */ public enum Anchor { NORTH(GridBagConstraints.NORTH), SOUTH(GridBagConstraints.SOUTH), EAST(GridBagConstraints.EAST), WEST(GridBagConstraints.WEST), NORTHEAST(GridBagConstraints.NORTHEAST), NORTHWEST(GridBagConstraints.NORTHWEST), SOUTHEAST(GridBagConstraints.SOUTHEAST), SOUTHWEST(GridBagConstraints.SOUTHWEST), CENTER(GridBagConstraints.CENTER); private int constraint; private Anchor(int gbConstraint) { constraint = gbConstraint; } public int getConstraint() { return constraint; } }
Fill.java:
package gbl; import java.awt.*; /** * Convenience enum that aliases out all possible values for the * GridBagConstraints fill property. */ public enum Fill { NONE(GridBagConstraints.NONE), HORIZONTAL(GridBagConstraints.HORIZONTAL), VERTICAL(GridBagConstraints.VERTICAL), BOTH(GridBagConstraints.BOTH); private int constraint; private Fill(int gbConstraint) { constraint = gbConstraint; } public int getConstraint() { return constraint; } }
2) Then, I created a subclass of GridBagConstraints that allowed me “chain” the properties only as I need them, while utilizing common defaults:
GBConstraints.java:
package gbl; import java.awt.*; /** * Convenience class to simplify the creation of a GridBagConstraints object. */ public class GBConstraints extends GridBagConstraints { public GBConstraints(int gridX, int gridY) { super(); this.gridx = gridX; this.gridy = gridY; this.gridwidth = 1; this.gridheight = 1; this.weightx = 0; this.weighty = 0; this.anchor = NORTHWEST; // old default was CENTER this.fill = NONE; this.insets = new Insets(1,2,1,2); // old default was (0,0,0,0) this.ipadx = 1; // old default was 0 this.ipady = 1; // old default was 0 } public GBConstraints anchor(Anchor anchor) { this.anchor = anchor.getConstraint(); return this; } public GBConstraints fill(Fill fill) { this.fill = fill.getConstraint(); /* * As a convenience, set the weights appropriately since these values are * almost always used in tandem with the given Fill. The caller can always * call the weight(...) method later if these defaults aren't desired. */ switch (fill) { case HORIZONTAL: this.weightx = 1; this.weighty = 0; break; case VERTICAL: this.weightx = 0; this.weighty = 1; break; case BOTH: this.weightx = 1; this.weighty = 1; break; default: this.weightx = 0; this.weighty = 0; break; } return this; } public GBConstraints insets(int length) { return insets(length, length, length, length); } public GBConstraints insets(int top, int left, int bottom, int right) { this.insets = new Insets(top, left, bottom, right); return this; } public GBConstraints ipad(int ipadX, int ipadY) { this.ipadx = ipadX; this.ipady = ipadY; return this; } public GBConstraints span(int gridWidth, int gridHeight) { this.gridwidth = gridWidth; this.gridheight = gridHeight; return this; } public GBConstraints spanX(int gridWidth) { this.gridwidth = gridWidth; return this; } public GBConstraints spanY(int gridHeight) { this.gridheight = gridHeight; return this; } public GBConstraints weight(double weightX, double weightY) { this.weightx = weightX; this.weighty = weightY; return this; } public GBConstraints weightX(double weightX) { this.weightx = weightX; return this; } public GBConstraints weightY(double weightY) { this.weighty = weightY; return this; } }
3) Putting it all together, here’s a demo that shows how to use the above classes. This greatly simplifies using GridBagLayout, IMHO. Side note: I normally stay away from static imports, but I like it in this situation.
Demo:
package gbl; import static gbl.Anchor.*; import static gbl.Fill.*; import java.awt.*; import javax.swing.*; public class GridBagDemo implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new GridBagDemo()); } public void run() { JLabel lblFirst = new JLabel("First Name"); JLabel lblLast = new JLabel("Last Name"); JLabel lblStreet = new JLabel("Street"); JLabel lblCity = new JLabel("City"); JLabel lblState = new JLabel("State"); JLabel lblZip = new JLabel("ZIP"); JLabel lblNotes = new JLabel("Notes"); JTextField txfFirst = new JTextField(15); JTextField txfLast = new JTextField(20); JTextField txfStreet = new JTextField(40); JTextField txfCity = new JTextField(15); JTextField txfState = new JTextField(5); JTextField txfZip = new JTextField(10); JTextArea txaNotes = new JTextArea(5, 50); JScrollPane scrNotes = new JScrollPane(txaNotes); scrNotes.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); Component spacer1 = Box.createHorizontalStrut(5); Component spacer2 = Box.createHorizontalStrut(5); JPanel panel = new JPanel(new GridBagLayout()); panel.add(spacer1, new GBConstraints(0,0)); panel.add(lblFirst, new GBConstraints(0,1)); panel.add(txfFirst, new GBConstraints(1,1)); panel.add(lblLast, new GBConstraints(2,1)); panel.add(txfLast, new GBConstraints(3,1).spanX(3).fill(HORIZONTAL)); panel.add(lblStreet, new GBConstraints(0,2)); panel.add(txfStreet, new GBConstraints(1,2).spanX(5).fill(HORIZONTAL)); panel.add(lblCity, new GBConstraints(0,3)); panel.add(txfCity, new GBConstraints(1,3)); panel.add(lblState, new GBConstraints(2,3).anchor(EAST)); panel.add(txfState, new GBConstraints(3,3)); panel.add(lblZip, new GBConstraints(4,3)); panel.add(txfZip, new GBConstraints(5,3).fill(HORIZONTAL)); panel.add(lblNotes, new GBConstraints(0,4)); panel.add(scrNotes, new GBConstraints(1,4).spanX(5).fill(BOTH)); panel.add(spacer2, new GBConstraints(0,5)); JFrame frame = new JFrame("Grid Bag Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new JScrollPane(panel), BorderLayout.CENTER); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }
Again, this is just one of many ways you’ll find online. Hope this helps.