sun.com/products/jfc/tsc/articles/bidi for an introduction to component orientation and bidirectional text support. The leading justification will align the component along the leading edge of the container and the trailing justification will align the component along the trailing edge. There is no leading or trailing justification along the vertical axis since all modern languages are read from top to bottom and no bottom-to-top orientation is defined in
java.awt.ComponentOrientation.
For components using the ComponentOrientation.LEFT_TO_RIGHT
orientation, the leading edge is the left edge and the trailing edge is the right one. For components using the ComponentOrientation.RIGHT_TO_LEFT
orientation, the opposite is true. For components that are using ComponentOrientation.UNKNOWN
and for Java runtime environments that do not support component orientation, left-to-right orientation is assumed for backwards compatibility.
Gaps Horizontal and vertical gaps can be placed between rows and columns in two ways. If uniformed gaps are desired, the
setHGap
and
setVGap
methods may be used. To vary the size of gaps, simply use empty rows and columns with absolute sizes. Similiarly, to make a border around a container that does not have insets, use empty rows and columns along the edges of the container.
Constraints Using TableLayout is a simple two step process. First, create a grid for your container by specifying row and column sizes using either a TableLayout constructor or the
insertRow
and
insertColumn
methods. Second, add components to the cells formed by the rows and columns.
When adding a component to a container that uses TableLayout, you specify the component's constraints that state which cells the component will occupy and how the component will be aligned. The constraints can be specified into two ways. The
TableLayoutConstraints
class can be used to systematically specify the constraints. This is useful to dynamic code, bean builders, and rapid application development software.
For manual coding, a quicker and easier way to specify constraints is with a short string in the form "x1, y1, x2, y2, hAlign, vAlign" where (x1, y1) identifies the top left cell (column x1, row y1) for the component and (x2, y2) identfies the bottom right cell. x2 and y2 are optional. If they are not specified, the component will occupy only one cell, (x1, y1). hAlign and vAlign are also optional with default values of full justification. Alignments may be spelt fully as in "LEFT" or abbreviated as in "L". The text is not case sensitive, but it is recommended that uppercase is used for two reasons. First, these text values are in essence constants. Second, some fonts use the same glyphs for representing a lowercase L and the number one. Ex., "l" vs. "1". Even fonts that do not will often use similar glyphs so using uppercase avoids confusion.
Dynamically altering the layout Rows and columns can be dynamically created, resized, and removed at any time, even if the container is visible. Components will be shifted appropriately as rows and columns are inserted or removed, just as cells are shifted in a spreadsheet.
Rows and columns can be made "hidden" or effectively invisible by setting their size to zero. They can be shown again by setting their size back to a non-zero value. This is very useful for toggle form elements without having to remove individual components.
Preferred sizes Often it is desireable to make a row or column just large enough to ensure that all components contained partially or wholly in that row or column are their preferred size. To make this easy, there is a constant called
PREFERRED
that can be used to specify row or column sizes. There is another constant called
MINIMUM
that does a similar task using components' minimum sizes instead of their preferred sizes.
There is no corresponding
MAXIMUM
constant for several reasons. First, it is mathematically impossible to honor both the minimum and maximum sizes of more than one component when conflicts arise. For example, say components a and b are in the same row. If a's maximum height is less than b's minimum height, then one of these constraints must be violated. Since TableLayout is a complete, general Cartesian layout manager, it would be possible to specify conflicting constraints if a
MAXIMUM
constant existed.
Second, the ability to make a component grow up to a maximum size is primarily of interest to layout managers like SpringLayout
that have to balance the sizes of components because the presence of one component affects the size of another. Other than the effect of preferred and minimum size rows/columns, which are essentially convenient ways of specifying absolute sizes, the existence and constraints of one component does not affect any other components when using TableLayout. This is accomplished because rows and columns are explicit in TableLayout.
Third, the ability to constrain a component to its maximum size is subsumed by the ability to constrain it to its preferred size, which is precisely what happens when a component is aligned using anything but full justification. In the case of full justification, the component's maximum size is by definition unbounded.
Example import java.awt.*; import javax.swing.*; import com.alee.extended.layout.TableLayout; public class Preferred extends JFrame { public static void main (String args[]) { new Preferred(); } public Preferred () { super("The Power of Preferred Sizes"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container pane = getContentPane(); // b - border // f - FILL // p - PREFERRED // vs - vertical space between labels and text fields // vg - vertical gap between form elements // hg - horizontal gap between form elements double b = 10; double f = TableLayout.FILL; double p = TableLayout.PREFERRED; double vs = 5; double vg = 10; double hg = 10; double size[][] = {{b, f, hg, p, hg, p, b}, {b, p, vs, p, vg, p, vs, p, vg, p, vs, p, vg, p, b}}; TableLayout layout = new TableLayout(size); pane.setLayout (layout); // Create all controls JLabel labelName = new JLabel("Name"); JLabel labelAddress = new JLabel("Address"); JLabel labelCity = new JLabel("City"); JLabel labelState = new JLabel("State"); JLabel labelZip = new JLabel("Zip"); JTextField textfieldName = new JTextField(10); JTextField textfieldAddress = new JTextField(20); JTextField textfieldCity = new JTextField(10); JTextField textfieldState = new JTextField(2); JTextField textfieldZip = new JTextField(5); JButton buttonOk = new JButton("OK"); JButton buttonCancel = new JButton("Cancel"); JPanel panelButton = new JPanel(); panelButton.add(buttonOk); panelButton.add(buttonCancel); // Add all controls pane.add(labelName, "1, 1, 5, 1"); pane.add(textfieldName, "1, 3, 5, 3"); pane.add(labelAddress, "1, 5, 5, 5"); pane.add(textfieldAddress, "1, 7, 5, 7"); pane.add(labelCity, "1, 9"); pane.add(textfieldCity, "1, 11"); pane.add(labelState, "3, 9"); pane.add(textfieldState, "3, 11"); pane.add(labelZip, "5, 9"); pane.add(textfieldZip, "5, 11"); pane.add(panelButton, "1, 13, 5, 13"); pack(); setResizable(false); show(); } }
@author Daniel E. Barbalace
@version 4.0 September 14, 2005