Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Java Tip 121: Flex your grid layout

Extend java.awt.GridLayout to allow for multisized columns and rows

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Developers often need to create graphical user interfaces (GUIs) that have a matrix-type layout with columns of different widths or rows of different heights. Those layout cells are unequal in order to minimize the space occupied by the laid out components. In those cases, you have to use the GridBagLayout class, whose numerous GridBagConstraints settings cause your code to grow quickly. However, the GridLayout layout manager seems more appropriate. It can help you write short and readable code while laying out components in equally sized cells. In this tip, I extend GridLayout to create cells of unequal size.

Note: If you use a JTable to display information in a matrix, then check out "Java Tip 116: Set Your Table Options -- at Runtime!" Sonal Goyal with John D. Mitchell.

GridLayout2

The GridLayout2 extension is fairly simple. The GridLayout2 class inherits from java.awt.GridLayout and then redefines the public methods preferredLayoutSize(), minimumLayoutSize(), and layoutContainer() to account for multisized grid cells. I started from the source code of those methods in the java.awt.GridLayout class. (Download the complete source code in Resources.)

Set preferred size

Here is the preferredLayoutSize() method:

  public Dimension preferredLayoutSize(Container parent) {
    synchronized (parent.getTreeLock()) {
      Insets insets = parent.getInsets();
      int ncomponents = parent.getComponentCount();
      int nrows = getRows();
      int ncols = getColumns();
      if (nrows > 0) {
        ncols = (ncomponents + nrows - 1) / nrows;
      }
      else {
        nrows = (ncomponents + ncols - 1) / ncols;
      }
      int[] w = new int[ncols];
      int[] h = new int[nrows];
      for (int i = 0; i < ncomponents; i ++) {
        int r = i / ncols;
        int c = i % ncols;
        Component comp = parent.getComponent(i);
        Dimension d = comp.getPreferredSize();
        if (w[c] < d.width) {
          w[c] = d.width;
        }
        if (h[r] < d.height) {
          h[r] = d.height;
        }
      }
      int nw = 0;
      for (int j = 0; j < ncols; j ++) {
        nw += w[j];
      }
      int nh = 0;
      for (int i = 0; i < nrows; i ++) {
        nh += h[i];
      }
      return new Dimension(insets.left + insets.right +
                     nw + (ncols-1) * getHgap(),
                     insets.top + insets.bottom +
                     nh + (nrows-1)*getVgap());
    }
  }


As you can see, the code is pretty straightforward. You first ensure that you have the right number of rows and columns to lay out the components. Then you find each component's preferred size. Finally, you compute each row's height as the row components' maximum height. You compute each column width as the maximum width of the row components. The preferred layout size also accounts for the horizontal and vertical gap sizes between components and the parent container insets.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (5)
Login
Forgot your account info?

Something oddBy Anonymous on August 3, 2010, 3:55 pmSomething odd happens when the components should be stretched to fill an entire area: There is always some space left to the right side and to the bottom. This space...

Reply | Read entire comment

Works like a charmBy Anonymous on August 3, 2010, 1:25 amAnd so useful. Thank you!

Reply | Read entire comment

You sir, are my hero of the dayBy Anonymous on August 1, 2010, 3:47 pmYou sir, are my hero of the day

Reply | Read entire comment

WowBy Anonymous on June 15, 2010, 7:17 amMassively useful. Thank you!

Reply | Read entire comment

arama algoritmas?By Anonymous on February 8, 2010, 3:11 pmFinally, you compute each row's height as the row components' maximum height. You compute each column width as the maximum width of the row components

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources