Hierarchical Layout

In GUI programming in Java, it needs much more code to layout components. The procedure consists of three steps:

  1. make a container,
  2. set a LayoutManager, and
  3. add components.
When containment relationship of components has hierarchical structure the code is not readable.

Panel panel1 = new Panel();
panel1.setLayout(LayoutManagerA);
panel1.add(component1);
...
Panel panel2 = new Panel();
ppanel2.setLayout(LayoutManagerB);
panel2.add(component3);
...
panel1.add(panel2);
...
add(panel1);

Hierarchical Layout allows intuitive representation of hierarichical structure of components using nested array.

Object[] format = new Object[]{ LayoutManagerA.class, component1,
                    new Object[]{ LayoutManagerB.class,  component2, ... }, ...
                  };
Layout.layout(container, format);

The first element of the array is a Class object which typically denotes a subclass of java.awt.LayoutManager. There should be a mapping from an array structure to its layout behavior for each Class. The mapping is responsible for processing the rest of the array.

pnuts.awt.Layout

pnuts.awt.Layout class is a "Manager" class for hierarchical layout. In most case it needs only the following method.
public static Container layout(Container container, Object[] format)
Layout components in container using format and return the container.

In Layout class, the following mappings are provided by default.

It is also possible to provide user-defined mapping by overriding the following method in subclass of Layout class.
public abstract Container createContainer(Container container, Object[] format)
Layout components in container using format, then return the container.
The mapping is registered with the following method.
public static void registerLayoutManager(Class aLayoutManager, Class aLayout)
Register aLayout class for array which starts with aLayoutManager class.
The following is an example of layout mapping for JTabbedPane of Swing.

BorderLayout mapping

e.g.
new Object[]{
  BorderLayout.class, new Object[]{new Integer(5), new Integer(5)},
  new Object[]{ "Center", new Button("Center") },
  new Object[]{ "South", new Button("South") },
  new Object[]{ "North", new Button("North") }
}

When the first element of array is BorderLayout.class, the 2nd element is an Object array which includes parameters of the constructor. The rest of the elements are one of these:

FlowLayout mapping

e.g.
new Object[]{
  FlowLayout.class, new Object[]{},
  new Button("One"),
  new Button("Two"),
  new Button("Three")
}

When the first element of array is GridLayout.class, the 2nd element is Object array which includes parameters of the constructor. The rest of the elements are one of these:

GridLayout mapping

e.g.
new Object[]{
  GridLayout.class, new Object[]{},
  new Button("One"),
  new Button("Two"),
  new Button("Three"),
  new Button("Four")
}

When the first element of array is GridLayout.class the 2nd element is Object array which includes parameters of the constructor. The rest of the elements are one of these:

GridBagLayout mapping

e.g.
new Object[]{
  GridBagLayout.class,
  new Object[]{"gridx=0, ...", new Button("One")},
  new Object[]{"gridx=0, ...", new Button("Two")},
  new Object[]{"gridx=0, ...", new Button("Three")},
  new Object[]{"gridx=0, ...", new Button("Four")}
}

When the first element of the array is GridBagLayout.class the rest of the elements are array of two elements.

Each value for 'fill' and 'anchor' is a name of static variable. For 'insets', colon-separated list of integer like 2:2:2:2 .

CardLayout mapping

e.g.
new Object[]{
  CardLayout.class, new Object[]{},
  new Object[]{"1", new Button("One")},
  new Object[]{"2", new Button("Two")},
  new Object[]{"3", new Button("Three")}
}

When the first element of array is CardLayout.class the 2nd element is Object array which includes parameters of the constructor. The rest of the elements are one of these:

PnutsLayout mapping

e.g.
new Object[]{
  PnutsLayout.class, "cols=2",
  button1,
  "label",
  null,
  new Object[]{
    button2, "colspan=2, padx=10"
  }
}

If the first element of the array is PnutsLayout.class the second element will be the parameter of PnutsLayout constructor. The rest of the array are elements which are in a container. Each element is either a Component object, String object, Object array, or null.

Therefore, the example above has following meaning.

setLayout(new PnutsLayout("cols=2"));
add(button1);
add(new Label("label"));
add(new Panel());
add(button2, "colspan=2, padx=10");
e.g.
Frame f = new Frame("11");
Layout.layout(f,
   new Object[]{PnutsLayout.class, "cols=2,padx=5,pady=5",
              new Object[]{PnutsLayout.class, "halign=left",
		 new Checkbox("8 points"),
		 new Checkbox("10 points"),
		 new Checkbox("12 points"),
		 new Checkbox("24 points")},
              new Object[]{PnutsLayout.class, "halign=left",
		 new Checkbox("Bold"),
		 new Checkbox("Italic"),
		 new Checkbox("Underline")}});
f.pack();
f.show();

Back