Newsletter sign-up
View all newsletters

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

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java Tip 121: Flex your grid layout

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

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

  • Print
  • Feedback
What is Tech Briefcase?
TechBriefcase is a new, free service where IT Professionals can Search, Store and Share IT white papers and content like this. Learn more
Bookmark content
Speed up your research efforts with content across the web.
Search and Store
Find the white papers you need. Create folders for any topic.
View Anywhere
Open your briefcase on your iPhone, tablet or desktop. Share with colleagues.
Don't have an account yet?

Resources