com.jgoodies.forms.layout
Class FormLayout

java.lang.Object
  extended by com.jgoodies.forms.layout.FormLayout
All Implemented Interfaces:
java.awt.LayoutManager, java.awt.LayoutManager2, java.io.Serializable

public final class FormLayout
extends java.lang.Object
implements java.awt.LayoutManager2, java.io.Serializable

FormLayout is a powerful, flexible and precise general purpose layout manager. It aligns components vertically and horizontally in a dynamic rectangular grid of cells, with each component occupying one or more cells. A whitepaper about the FormLayout ships with the product documentation and is available online.

To use FormLayout you first define the grid by specifying the columns and rows. In a second step you add components to the grid. You can specify columns and rows via human-readable String descriptions or via arrays of ColumnSpec and RowSpec instances.

Each component managed by a FormLayout is associated with an instance of CellConstraints. The constraints object specifies where a component should be located on the form's grid and how the component should be positioned. In addition to its constraints object the FormLayout also considers each component's minimum and preferred sizes in order to determine a component's size.

FormLayout has been designed to work with non-visual builders that help you specify the layout and fill the grid. For example, the ButtonBarBuilder assists you in building button bars; it creates a standardized FormLayout and provides a minimal API that specializes in adding buttons. Other builders can create frequently used panel design, for example a form that consists of rows of label-component pairs.

FormLayout has been prepared to work with different types of sizes as defined by the Size interface.

Example 1 (Plain FormLayout):
The following example creates a panel with 3 data columns and 3 data rows; the columns and rows are specified before components are added to the form.

 FormLayout layout = new FormLayout(
      "right:pref, 6dlu, 50dlu, 4dlu, default",  // columns
      "pref, 3dlu, pref, 3dlu, pref");           // rows

 CellConstraints cc = new CellConstraints();
 JPanel panel = new JPanel(layout);
 panel.add(new JLabel("Label1"),   cc.xy  (1, 1));
 panel.add(new JTextField(),       cc.xywh(3, 1, 3, 1));
 panel.add(new JLabel("Label2"),   cc.xy  (1, 3));
 panel.add(new JTextField(),       cc.xy  (3, 3));
 panel.add(new JLabel("Label3"),   cc.xy  (1, 5));
 panel.add(new JTextField(),       cc.xy  (3, 5));
 panel.add(new JButton("/u2026"),  cc.xy  (5, 5));
 return panel;
 

Example 2 (Using PanelBuilder):
This example creates the same panel as above using the PanelBuilder to add components to the form.

 FormLayout layout = new FormLayout(
      "right:pref, 6dlu, 50dlu, 4dlu, default",  // columns
      "pref, 3dlu, pref, 3dlu, pref");           // rows

 PanelBuilder builder = new PanelBuilder(layout);
 CellConstraints cc = new CellConstraints();
 builder.addLabel("Label1",         cc.xy  (1, 1));
 builder.add(new JTextField(),      cc.xywh(3, 1, 3, 1));
 builder.addLabel("Label2",         cc.xy  (1, 3));
 builder.add(new JTextField(),      cc.xy  (3, 3));
 builder.addLabel("Label3",         cc.xy  (1, 5));
 builder.add(new JTextField(),      cc.xy  (3, 5));
 builder.add(new JButton("/u2026"), cc.xy  (5, 5));
 return builder.getPanel();
 

Example 3 (Using DefaultFormBuilder):
This example utilizes the DefaultFormBuilder that ships with the source distribution.

 FormLayout layout = new FormLayout(
      "right:pref, 6dlu, 50dlu, 4dlu, default"); // 5 columns; add rows later

 DefaultFormBuilder builder = new DefaultFormBuilder(layout);
 builder.append("Label1", new JTextField(), 3);
 builder.append("Label2", new JTextField());
 builder.append("Label3", new JTextField());
 builder.append(new JButton("/u2026"));
 return builder.getPanel();
 

TODO: In the Forms 1.0.x invisible components are not taken into account when the FormLayout lays out the container. Add an optional setting for this on both the container-level and component-level. So one can specify that invisible components shall be taken into account, but may exclude individual components. Or the other way round, exclude invisible components, and include individual components. The API of both the FormLayout and CellConstraints classes shall be extended to support this option. This feature is planned for the Forms version 1.1 and is described in issue #28 of the Forms' issue tracker where you can track the progress.

Version:
$Revision: 54721 $
Author:
Karsten Lentzsch
See Also:
ColumnSpec, RowSpec, CellConstraints, AbstractFormBuilder, ButtonBarBuilder, DefaultFormBuilder, FormFactory, Size, Sizes, Serialized Form

Nested Class Summary
private static class FormLayout.CachingMeasure
          An abstract implementation of the Measure interface that caches component sizes.
private static class FormLayout.ComponentSizeCache
          A cache for component minimum and preferred sizes.
static class FormLayout.LayoutInfo
          Stores column and row origins.
(package private) static interface FormLayout.Measure
          An interface that describes how to measure a Component.
private static class FormLayout.MinimumHeightMeasure
          Measures a component by computing its minimum height.
private static class FormLayout.MinimumWidthMeasure
          Measures a component by computing its minimum width.
private static class FormLayout.PreferredHeightMeasure
          Measures a component by computing its preferred height.
private static class FormLayout.PreferredWidthMeasure
          Measures a component by computing its preferred width.
 
Field Summary
private  java.util.List[] colComponents
          Holds the components that occupy exactly one column.
private  int[][] colGroupIndices
          Holds the column groups as an array of arrays of column indices.
private  java.util.List colSpecs
          Holds the column specifications.
private  FormLayout.ComponentSizeCache componentSizeCache
          Caches component minimum and preferred sizes.
private  java.util.Map constraintMap
          Maps components to their associated CellConstraints.
private  FormLayout.Measure minimumHeightMeasure
           
private  FormLayout.Measure minimumWidthMeasure
          These functional objects are used to measure component sizes.
private  FormLayout.Measure preferredHeightMeasure
           
private  FormLayout.Measure preferredWidthMeasure
           
private  java.util.List[] rowComponents
          Holds the components that occupy exactly one row.
private  int[][] rowGroupIndices
          Holds the row groups as an array of arrays of row indices.
private  java.util.List rowSpecs
          Holds the row specifications.
 
Constructor Summary
FormLayout()
          Constructs an empty FormLayout.
FormLayout(ColumnSpec[] colSpecs, RowSpec[] rowSpecs)
          Constructs a FormLayout using the given column and row specifications.
FormLayout(java.lang.String encodedColumnSpecs)
          Constructs a FormLayout using the given encoded column specifications.
FormLayout(java.lang.String encodedColumnSpecs, java.lang.String encodedRowSpecs)
          Constructs a FormLayout using the given encoded column and row specifications.
 
Method Summary
 void addGroupedColumn(int columnIndex)
          Adds the specified column index to the last column group.
 void addGroupedRow(int rowIndex)
          Adds the specified row index to the last row group.
 void addLayoutComponent(java.awt.Component comp, java.lang.Object constraints)
          Adds the specified component to the layout, using the specified constraints object.
 void addLayoutComponent(java.lang.String name, java.awt.Component component)
          Throws an UnsupportedOperationException.
private  void adjustGroupIndices(int[][] allGroupIndices, int modifiedIndex, boolean remove)
          Adjusts group indices.
 void appendColumn(ColumnSpec columnSpec)
          Appends the given column specification to the right hand side of all columns.
 void appendRow(RowSpec rowSpec)
          Appends the given row specification to the bottom of all rows.
private  int[] compressedSizes(java.util.List formSpecs, int totalSize, int totalMinSize, int totalPrefSize, int[] minSizes, int[] prefSizes)
          Computes and returns the compressed sizes.
private  int[] computeGridOrigins(java.awt.Container container, int totalSize, int offset, java.util.List formSpecs, java.util.List[] componentLists, int[][] groupIndices, FormLayout.Measure minMeasure, FormLayout.Measure prefMeasure)
          Computes and returns the grid's origins.
private  java.awt.Dimension computeLayoutSize(java.awt.Container parent, FormLayout.Measure defaultWidthMeasure, FormLayout.Measure defaultHeightMeasure)
          Computes and returns the layout size of the given parent container using the specified measures.
private  int[] computeMaximumFixedSpanTable(java.util.List formSpecs)
          Computes and returns a table that maps a column/row index to the maximum number of columns/rows that a component can span without spanning a growing column.
private  int[] computeOrigins(int[] sizes, int offset)
          Computes origins from sizes taking the specified offset into account.
private  int[][] deepClone(int[][] array)
          Creates and returns a deep copy of the given array.
private  int[] distributedSizes(java.util.List formSpecs, int totalSize, int totalPrefSize, int[] inputSizes)
          Distributes free space over columns and rows and returns the sizes after this distribution process.
 int getColumnCount()
          Returns the number of columns in this layout.
 int[][] getColumnGroups()
          Returns a deep copy of the column groups.
 ColumnSpec getColumnSpec(int columnIndex)
          Returns the ColumnSpec at the specified column index.
 CellConstraints getConstraints(java.awt.Component component)
          Looks up and returns the constraints for the specified component.
 float getLayoutAlignmentX(java.awt.Container parent)
          Returns the alignment along the x axis.
 float getLayoutAlignmentY(java.awt.Container parent)
          Returns the alignment along the y axis.
 FormLayout.LayoutInfo getLayoutInfo(java.awt.Container parent)
          Computes and returns the horizontal and vertical grid origins.
 int getRowCount()
          Returns the number of rows in this layout.
 int[][] getRowGroups()
          Returns a deep copy of the row groups.
 RowSpec getRowSpec(int rowIndex)
          Returns the RowSpec at the specified row index.
private  int[] groupedSizes(int[][] groups, int[] rawSizes)
          Computes and returns the grouped sizes.
private  void initializeColAndRowComponentLists()
          Initializes two lists for columns and rows that hold a column's or row's components that span only this column or row.
 void insertColumn(int columnIndex, ColumnSpec columnSpec)
          Inserts the specified column at the specified position.
 void insertRow(int rowIndex, RowSpec rowSpec)
          Inserts the specified column at the specified position.
private  void invalidateCaches()
          Invalidates the component size caches.
 void invalidateLayout(java.awt.Container target)
          Invalidates the layout, indicating that if the layout manager has cached information it should be discarded.
private  void layoutComponents(int[] x, int[] y)
          Lays out the components using the given x and y origins, the column and row specifications, and the component constraints.
 void layoutContainer(java.awt.Container parent)
          Lays out the specified container using this form layout.
 java.awt.Dimension maximumLayoutSize(java.awt.Container target)
          Returns the maximum dimensions for this layout given the components in the specified target container.
private  int[] maximumSizes(java.awt.Container container, java.util.List formSpecs, java.util.List[] componentLists, FormLayout.Measure minMeasure, FormLayout.Measure prefMeasure, FormLayout.Measure defaultMeasure)
          Computes and returns the sizes for the given form specs, component lists and measures fot minimum, preferred, and default size.
 java.awt.Dimension minimumLayoutSize(java.awt.Container parent)
          Determines the minimum size of the parent container using this form layout.
 java.awt.Dimension preferredLayoutSize(java.awt.Container parent)
          Determines the preferred size of the parent container using this form layout.
 void removeColumn(int columnIndex)
          Removes the column with the given column index from the layout.
private  void removeConstraints(java.awt.Component component)
          Removes the constraints for the specified component in this layout.
 void removeLayoutComponent(java.awt.Component comp)
          Removes the specified component from this layout.
 void removeRow(int rowIndex)
          Removes the row with the given row index from the layout.
 void setColumnGroups(int[][] colGroupIndices)
          Sets the column groups, where each column in a group gets the same group wide width.
 void setColumnSpec(int columnIndex, ColumnSpec columnSpec)
          Sets the ColumnSpec at the specified column index.
 void setConstraints(java.awt.Component component, CellConstraints constraints)
          Sets the constraints for the specified component in this layout.
 void setRowGroups(int[][] rowGroupIndices)
          Sets the row groups, where each row in such a group gets the same group wide height.
 void setRowSpec(int rowIndex, RowSpec rowSpec)
          Sets the RowSpec at the specified row index.
private  void shiftComponentsHorizontally(int columnIndex, boolean remove)
          Shifts components horizontally, either to the right if a column has been inserted or to the left if a column has been removed.
private  void shiftComponentsVertically(int rowIndex, boolean remove)
          Shifts components vertically, either to the bottom if a row has been inserted or to the top if a row has been removed.
private  int sum(int[] sizes)
          Computes and returns the sum of integers in the given array of ints.
private  void writeObject(java.io.ObjectOutputStream out)
          In addition to the default serialization mechanism this class invalidates the component size cache.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

colSpecs

private final java.util.List colSpecs
Holds the column specifications.

See Also:
ColumnSpec, getColumnCount(), getColumnSpec(int), appendColumn(ColumnSpec), insertColumn(int, ColumnSpec), removeColumn(int)

rowSpecs

private final java.util.List rowSpecs
Holds the row specifications.

See Also:
RowSpec, getRowCount(), getRowSpec(int), appendRow(RowSpec), insertRow(int, RowSpec), removeRow(int)

colGroupIndices

private int[][] colGroupIndices
Holds the column groups as an array of arrays of column indices.

See Also:
getColumnGroups(), setColumnGroups(int[][]), addGroupedColumn(int)

rowGroupIndices

private int[][] rowGroupIndices
Holds the row groups as an array of arrays of row indices.

See Also:
getRowGroups(), setRowGroups(int[][]), addGroupedRow(int)

constraintMap

private final java.util.Map constraintMap
Maps components to their associated CellConstraints.

See Also:
CellConstraints, getConstraints(Component), setConstraints(Component, CellConstraints)

colComponents

private transient java.util.List[] colComponents
Holds the components that occupy exactly one column. For each column we keep a list of these components.


rowComponents

private transient java.util.List[] rowComponents
Holds the components that occupy exactly one row. For each row we keep a list of these components.


componentSizeCache

private final FormLayout.ComponentSizeCache componentSizeCache
Caches component minimum and preferred sizes. All requests for component sizes shall be directed to the cache.


minimumWidthMeasure

private final FormLayout.Measure minimumWidthMeasure
These functional objects are used to measure component sizes. They abstract from horizontal and vertical orientation and so, allow to implement the layout algorithm for both orientations with a single set of methods.


minimumHeightMeasure

private final FormLayout.Measure minimumHeightMeasure

preferredWidthMeasure

private final FormLayout.Measure preferredWidthMeasure

preferredHeightMeasure

private final FormLayout.Measure preferredHeightMeasure
Constructor Detail

FormLayout

public FormLayout()
Constructs an empty FormLayout. Columns and rows must be added before components can be added to the layout container.

This constructor is intended to be used in environments that add columns and rows dynamically.


FormLayout

public FormLayout(java.lang.String encodedColumnSpecs)
Constructs a FormLayout using the given encoded column specifications. The constructed layout has no rows; these must be added before components can be added to the layout container.

This constructor is primarily intended to be used with builder classes that add rows dynamically, such as the DefaultFormBuilder.

Examples:

 // Label, gap, component
 FormLayout layout = new FormLayout(
      "pref, 4dlu, pref");

 // Right-aligned label, gap, component, gap, component
 FormLayout layout = new FormLayout(
      "right:pref, 4dlu, 50dlu, 4dlu, 50dlu");

 // Left-aligned labels, gap, components, gap, components
 FormLayout layout = new FormLayout(
      "left:pref, 4dlu, pref, 4dlu, pref");
 
See the class comment for more examples.

Parameters:
encodedColumnSpecs - comma separated encoded column specifications
Throws:
java.lang.NullPointerException - if encodedColumnSpecs is null

FormLayout

public FormLayout(java.lang.String encodedColumnSpecs,
                  java.lang.String encodedRowSpecs)
Constructs a FormLayout using the given encoded column and row specifications.

This constructor is recommended for most hand-coded layouts.

Examples:

 FormLayout layout = new FormLayout(
      "pref, 4dlu, pref",               // columns
      "p, 3dlu, p");                    // rows

 FormLayout layout = new FormLayout(
      "right:pref, 4dlu, pref",         // columns
      "p, 3dlu, p, 3dlu, fill:p:grow"); // rows

 FormLayout layout = new FormLayout(
      "left:pref, 4dlu, 50dlu",         // columns
      "p, 2px, p, 3dlu, p, 9dlu, p");   // rows

 FormLayout layout = new FormLayout(
      "max(75dlu;pref), 4dlu, default", // columns
      "p, 3dlu, p, 3dlu, p, 3dlu, p");  // rows
 
See the class comment for more examples.

Parameters:
encodedColumnSpecs - comma separated encoded column specifications
encodedRowSpecs - comma separated encoded row specifications
Throws:
java.lang.NullPointerException - if encodedColumnSpecs or encodedRowSpecs is null

FormLayout

public FormLayout(ColumnSpec[] colSpecs,
                  RowSpec[] rowSpecs)
Constructs a FormLayout using the given column and row specifications.

Parameters:
colSpecs - an array of column specifications.
rowSpecs - an array of row specifications.
Throws:
java.lang.NullPointerException - if colSpecs or rowSpecs is null
Method Detail

getColumnCount

public int getColumnCount()
Returns the number of columns in this layout.

Returns:
the number of columns

getRowCount

public int getRowCount()
Returns the number of rows in this layout.

Returns:
the number of rows

getColumnSpec

public ColumnSpec getColumnSpec(int columnIndex)
Returns the ColumnSpec at the specified column index.

Parameters:
columnIndex - the column index of the requested ColumnSpec
Returns:
the ColumnSpec at the specified column
Throws:
java.lang.IndexOutOfBoundsException - if the column index is out of range

setColumnSpec

public void setColumnSpec(int columnIndex,
                          ColumnSpec columnSpec)
Sets the ColumnSpec at the specified column index.

Parameters:
columnIndex - the index of the column to be changed
columnSpec - the ColumnSpec to be set
Throws:
java.lang.NullPointerException - if the column specification is null
java.lang.IndexOutOfBoundsException - if the column index is out of range

getRowSpec

public RowSpec getRowSpec(int rowIndex)
Returns the RowSpec at the specified row index.

Parameters:
rowIndex - the row index of the requested RowSpec
Returns:
the RowSpec at the specified row
Throws:
java.lang.IndexOutOfBoundsException - if the row index is out of range

setRowSpec

public void setRowSpec(int rowIndex,
                       RowSpec rowSpec)
Sets the RowSpec at the specified row index.

Parameters:
rowIndex - the index of the row to be changed
rowSpec - the RowSpec to be set
Throws:
java.lang.NullPointerException - if the row specification is null
java.lang.IndexOutOfBoundsException - if the row index is out of range

appendColumn

public void appendColumn(ColumnSpec columnSpec)
Appends the given column specification to the right hand side of all columns.

Parameters:
columnSpec - the column specification to be added
Throws:
java.lang.NullPointerException - if the column specification is null

insertColumn

public void insertColumn(int columnIndex,
                         ColumnSpec columnSpec)
Inserts the specified column at the specified position. Shifts components that intersect the new column to the right hand side and readjusts column groups.

The component shift works as follows: components that were located on the right hand side of the inserted column are shifted one column to the right; component column span is increased by one if it intersects the new column.

Column group indices that are greater or equal than the given column index will be increased by one.

Parameters:
columnIndex - index of the column to be inserted
columnSpec - specification of the column to be inserted
Throws:
java.lang.IndexOutOfBoundsException - if the column index is out of range

removeColumn

public void removeColumn(int columnIndex)
Removes the column with the given column index from the layout. Components will be rearranged and column groups will be readjusted. Therefore, the column must not contain components and must not be part of a column group.

The component shift works as follows: components that were located on the right hand side of the removed column are moved one column to the left; component column span is decreased by one if it intersects the removed column.

Column group indices that are greater than the column index will be decreased by one.

Note: If one of the constraints mentioned above is violated, this layout's state becomes illegal and it is unsafe to work with this layout. A typical layout implementation can ensure that these constraints are not violated. However, in some cases you may need to check these conditions before you invoke this method. The Forms extras contain source code for class FormLayoutUtils that provides the required test methods:
#columnContainsComponents(Container, int) and
#isGroupedColumn(FormLayout, int).

Parameters:
columnIndex - index of the column to remove
Throws:
java.lang.IndexOutOfBoundsException - if the column index is out of range
java.lang.IllegalStateException - if the column contains components or if the column is already grouped

appendRow

public void appendRow(RowSpec rowSpec)
Appends the given row specification to the bottom of all rows.

Parameters:
rowSpec - the row specification to be added to the form layout
Throws:
java.lang.NullPointerException - if the rowSpec is null

insertRow

public void insertRow(int rowIndex,
                      RowSpec rowSpec)
Inserts the specified column at the specified position. Shifts components that intersect the new column to the right and readjusts column groups.

The component shift works as follows: components that were located on the right hand side of the inserted column are shifted one column to the right; component column span is increased by one if it intersects the new column.

Column group indices that are greater or equal than the given column index will be increased by one.

Parameters:
rowIndex - index of the row to be inserted
rowSpec - specification of the row to be inserted
Throws:
java.lang.IndexOutOfBoundsException - if the row index is out of range

removeRow

public void removeRow(int rowIndex)
Removes the row with the given row index from the layout. Components will be rearranged and row groups will be readjusted. Therefore, the row must not contain components and must not be part of a row group.

The component shift works as follows: components that were located below the removed row are moved up one row; component row span is decreased by one if it intersects the removed row.

Row group indices that are greater than the row index will be decreased by one.

Note: If one of the constraints mentioned above is violated, this layout's state becomes illegal and it is unsafe to work with this layout. A typical layout implementation can ensure that these constraints are not violated. However, in some cases you may need to check these conditions before you invoke this method. The Forms extras contain source code for class FormLayoutUtils that provides the required test methods:
#rowContainsComponents(Container, int) and
#isGroupedRow(FormLayout, int).

Parameters:
rowIndex - index of the row to remove
Throws:
java.lang.IndexOutOfBoundsException - if the row index is out of range
java.lang.IllegalStateException - if the row contains components or if the row is already grouped

shiftComponentsHorizontally

private void shiftComponentsHorizontally(int columnIndex,
                                         boolean remove)
Shifts components horizontally, either to the right if a column has been inserted or to the left if a column has been removed.

Parameters:
columnIndex - index of the column to remove
remove - true for remove, false for insert
Throws:
java.lang.IllegalStateException - if a removed column contains components

shiftComponentsVertically

private void shiftComponentsVertically(int rowIndex,
                                       boolean remove)
Shifts components vertically, either to the bottom if a row has been inserted or to the top if a row has been removed.

Parameters:
rowIndex - index of the row to remove
remove - true for remove, false for insert
Throws:
java.lang.IllegalStateException - if a removed column contains components

adjustGroupIndices

private void adjustGroupIndices(int[][] allGroupIndices,
                                int modifiedIndex,
                                boolean remove)
Adjusts group indices. Shifts the given groups to left, right, up, down according to the specified remove or add flag.

Parameters:
allGroupIndices - the groups to be adjusted
modifiedIndex - the modified column or row index
remove - true for remove, false for add
Throws:
java.lang.IllegalStateException - if we remove and the index is grouped

getConstraints

public CellConstraints getConstraints(java.awt.Component component)
Looks up and returns the constraints for the specified component. A copy of the actual CellConstraints object is returned.

Parameters:
component - the component to be queried
Returns:
the CellConstraints for the specified component
Throws:
java.lang.NullPointerException - if component is null or has not been added to the container

setConstraints

public void setConstraints(java.awt.Component component,
                           CellConstraints constraints)
Sets the constraints for the specified component in this layout.

Parameters:
component - the component to be modified
constraints - the constraints to be applied
Throws:
java.lang.NullPointerException - if the component or constraints object is null

removeConstraints

private void removeConstraints(java.awt.Component component)
Removes the constraints for the specified component in this layout.

Parameters:
component - the component to be modified

getColumnGroups

public int[][] getColumnGroups()
Returns a deep copy of the column groups.

Returns:
the column groups as two-dimensional int array

setColumnGroups

public void setColumnGroups(int[][] colGroupIndices)
Sets the column groups, where each column in a group gets the same group wide width. Each group is described by an array of integers that are interpreted as column indices. The parameter is an array of such group descriptions.

Examples:

 // Group columns 1, 3 and 4.
 setColumnGroups(new int[][]{ {1, 3, 4}});

 // Group columns 1, 3, 4, and group columns 7 and 9
 setColumnGroups(new int[][]{ {1, 3, 4}, {7, 9}});
 

Parameters:
colGroupIndices - a two-dimensional array of column groups indices
Throws:
java.lang.IndexOutOfBoundsException - if an index is outside the grid
java.lang.IllegalArgumentException - if a column index is used twice

addGroupedColumn

public void addGroupedColumn(int columnIndex)
Adds the specified column index to the last column group. In case there are no groups, a new group will be created.

Parameters:
columnIndex - the column index to be set grouped

getRowGroups

public int[][] getRowGroups()
Returns a deep copy of the row groups.

Returns:
the row groups as two-dimensional int array

setRowGroups

public void setRowGroups(int[][] rowGroupIndices)
Sets the row groups, where each row in such a group gets the same group wide height. Each group is described by an array of integers that are interpreted as row indices. The parameter is an array of such group descriptions.

Examples:

 // Group rows 1 and 2.
 setRowGroups(new int[][]{ {1, 2}});

 // Group rows 1 and 2, and group rows 5, 7, and 9.
 setRowGroups(new int[][]{ {1, 2}, {5, 7, 9}});
 

Parameters:
rowGroupIndices - a two-dimensional array of row group indices.
Throws:
java.lang.IndexOutOfBoundsException - if an index is outside the grid

addGroupedRow

public void addGroupedRow(int rowIndex)
Adds the specified row index to the last row group. In case there are no groups, a new group will be created.

Parameters:
rowIndex - the index of the row that should be grouped

addLayoutComponent

public void addLayoutComponent(java.lang.String name,
                               java.awt.Component component)
Throws an UnsupportedOperationException. Does not add the specified component with the specified name to the layout.

Specified by:
addLayoutComponent in interface java.awt.LayoutManager
Parameters:
name - indicates entry's position and anchor
component - component to add
Throws:
java.lang.UnsupportedOperationException - always

addLayoutComponent

public void addLayoutComponent(java.awt.Component comp,
                               java.lang.Object constraints)
Adds the specified component to the layout, using the specified constraints object. Note that constraints are mutable and are, therefore, cloned when cached.

Specified by:
addLayoutComponent in interface java.awt.LayoutManager2
Parameters:
comp - the component to be added
constraints - the component's cell constraints
Throws:
java.lang.NullPointerException - if constraints is null
java.lang.IllegalArgumentException - if constraints is not a CellConstraints or a String that cannot be used to construct a CellConstraints

removeLayoutComponent

public void removeLayoutComponent(java.awt.Component comp)
Removes the specified component from this layout.

Most applications do not call this method directly.

Specified by:
removeLayoutComponent in interface java.awt.LayoutManager
Parameters:
comp - the component to be removed.
See Also:
Container.remove(java.awt.Component), Container.removeAll()

minimumLayoutSize

public java.awt.Dimension minimumLayoutSize(java.awt.Container parent)
Determines the minimum size of the parent container using this form layout.

Most applications do not call this method directly.

Specified by:
minimumLayoutSize in interface java.awt.LayoutManager
Parameters:
parent - the container in which to do the layout
Returns:
the minimum size of the parent container
See Also:
Container.doLayout()

preferredLayoutSize

public java.awt.Dimension preferredLayoutSize(java.awt.Container parent)
Determines the preferred size of the parent container using this form layout.

Most applications do not call this method directly.

Specified by:
preferredLayoutSize in interface java.awt.LayoutManager
Parameters:
parent - the container in which to do the layout
Returns:
the preferred size of the parent container
See Also:
Container.getPreferredSize()

maximumLayoutSize

public java.awt.Dimension maximumLayoutSize(java.awt.Container target)
Returns the maximum dimensions for this layout given the components in the specified target container.

Specified by:
maximumLayoutSize in interface java.awt.LayoutManager2
Parameters:
target - the container which needs to be laid out
Returns:
the maximum dimensions for this layout
See Also:
Container, minimumLayoutSize(Container), preferredLayoutSize(Container)

getLayoutAlignmentX

public float getLayoutAlignmentX(java.awt.Container parent)
Returns the alignment along the x axis. This specifies how the component would like to be aligned relative to other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 is aligned the furthest away from the origin, 0.5 is centered, etc.

Specified by:
getLayoutAlignmentX in interface java.awt.LayoutManager2
Parameters:
parent - the parent container
Returns:
the value 0.5f to indicate center alignment

getLayoutAlignmentY

public float getLayoutAlignmentY(java.awt.Container parent)
Returns the alignment along the y axis. This specifies how the component would like to be aligned relative to other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 is aligned the furthest away from the origin, 0.5 is centered, etc.

Specified by:
getLayoutAlignmentY in interface java.awt.LayoutManager2
Parameters:
parent - the parent container
Returns:
the value 0.5f to indicate center alignment

invalidateLayout

public void invalidateLayout(java.awt.Container target)
Invalidates the layout, indicating that if the layout manager has cached information it should be discarded.

Specified by:
invalidateLayout in interface java.awt.LayoutManager2
Parameters:
target - the container that holds the layout to be invalidated

layoutContainer

public void layoutContainer(java.awt.Container parent)
Lays out the specified container using this form layout. This method reshapes components in the specified container in order to satisfy the contraints of this FormLayout object.

Most applications do not call this method directly.

The form layout performs the following steps:

  1. find components that occupy exactly one column or row
  2. compute minimum widths and heights
  3. compute preferred widths and heights
  4. give cols and row equal size if they share a group
  5. compress default columns and rows if total is less than pref size
  6. give cols and row equal size if they share a group
  7. distribute free space
  8. set components bounds

Specified by:
layoutContainer in interface java.awt.LayoutManager
Parameters:
parent - the container in which to do the layout
See Also:
Container, Container.doLayout()

initializeColAndRowComponentLists

private void initializeColAndRowComponentLists()
Initializes two lists for columns and rows that hold a column's or row's components that span only this column or row.

Iterates over all components and their associated constraints; every component that has a column span or row span of 1 is put into the column's or row's component list.

As of the Forms version 1.0.x invisible components are not taken into account when the container is layed out. See the TODO in the JavaDoc class commment for details on this issue.


computeLayoutSize

private java.awt.Dimension computeLayoutSize(java.awt.Container parent,
                                             FormLayout.Measure defaultWidthMeasure,
                                             FormLayout.Measure defaultHeightMeasure)
Computes and returns the layout size of the given parent container using the specified measures.

Parameters:
parent - the container in which to do the layout
defaultWidthMeasure - the measure used to compute the default width
defaultHeightMeasure - the measure used to compute the default height
Returns:
the layout size of the parent container

computeGridOrigins

private int[] computeGridOrigins(java.awt.Container container,
                                 int totalSize,
                                 int offset,
                                 java.util.List formSpecs,
                                 java.util.List[] componentLists,
                                 int[][] groupIndices,
                                 FormLayout.Measure minMeasure,
                                 FormLayout.Measure prefMeasure)
Computes and returns the grid's origins.

Parameters:
container - the layout container
totalSize - the total size to assign
offset - the offset from left or top margin
formSpecs - the column or row specs, resp.
componentLists - the components list for each col/row
minMeasure - the measure used to determin min sizes
prefMeasure - the measure used to determin pre sizes
groupIndices - the group specification
Returns:
an int array with the origins

computeOrigins

private int[] computeOrigins(int[] sizes,
                             int offset)
Computes origins from sizes taking the specified offset into account.

Parameters:
sizes - the array of sizes
offset - an offset for the first origin
Returns:
an array of origins

layoutComponents

private void layoutComponents(int[] x,
                              int[] y)
Lays out the components using the given x and y origins, the column and row specifications, and the component constraints.

The actual computation is done by each component's form constraint object. We just compute the cell, the cell bounds and then hand over the component, cell bounds, and measure to the form constraints. This will allow potential subclasses of CellConstraints to do special micro-layout corrections. For example, such a subclass could map JComponent classes to visual layout bounds that may lead to a slightly different bounds.

Parameters:
x - an int array of the horizontal origins
y - an int array of the vertical origins

invalidateCaches

private void invalidateCaches()
Invalidates the component size caches.


maximumSizes

private int[] maximumSizes(java.awt.Container container,
                           java.util.List formSpecs,
                           java.util.List[] componentLists,
                           FormLayout.Measure minMeasure,
                           FormLayout.Measure prefMeasure,
                           FormLayout.Measure defaultMeasure)
Computes and returns the sizes for the given form specs, component lists and measures fot minimum, preferred, and default size.

Parameters:
container - the layout container
formSpecs - the column or row specs, resp.
componentLists - the components list for each col/row
minMeasure - the measure used to determin min sizes
prefMeasure - the measure used to determin pre sizes
defaultMeasure - the measure used to determin default sizes
Returns:
the column or row sizes

compressedSizes

private int[] compressedSizes(java.util.List formSpecs,
                              int totalSize,
                              int totalMinSize,
                              int totalPrefSize,
                              int[] minSizes,
                              int[] prefSizes)
Computes and returns the compressed sizes. Compresses space for columns and rows iff the available space is less than the total preferred size but more than the total minimum size.

Only columns and row that are specified to be compressable will be affected. You can specify a column and row as compressable by giving it the component size default.

Parameters:
formSpecs - the column or row specs to use
totalSize - the total available size
totalMinSize - the sum of all minimum sizes
totalPrefSize - the sum of all preferred sizes
minSizes - an int array of column/row minimum sizes
prefSizes - an int array of column/row preferred sizes
Returns:
an int array of compressed column/row sizes

groupedSizes

private int[] groupedSizes(int[][] groups,
                           int[] rawSizes)
Computes and returns the grouped sizes. Gives grouped columns and rows the same size.

Parameters:
groups - the group specification
rawSizes - the raw sizes before the grouping
Returns:
the grouped sizes

distributedSizes

private int[] distributedSizes(java.util.List formSpecs,
                               int totalSize,
                               int totalPrefSize,
                               int[] inputSizes)
Distributes free space over columns and rows and returns the sizes after this distribution process.

Parameters:
formSpecs - the column/row specifications to work with
totalSize - the total available size
totalPrefSize - the sum of all preferred sizes
inputSizes - the input sizes
Returns:
the distributed sizes

sum

private int sum(int[] sizes)
Computes and returns the sum of integers in the given array of ints.

Parameters:
sizes - an array of ints to sum up
Returns:
the sum of ints in the array

computeMaximumFixedSpanTable

private int[] computeMaximumFixedSpanTable(java.util.List formSpecs)
Computes and returns a table that maps a column/row index to the maximum number of columns/rows that a component can span without spanning a growing column.

Iterates over the specs from right to left/bottom to top, sets the table value to zero if a spec can grow, otherwise increases the span by one.

Examples:

 "pref, 4dlu, pref, 2dlu, p:grow, 2dlu,      pref" ->
 [4,    3,    2,    1,    0,      MAX_VALUE, MAX_VALUE]

 "p:grow, 4dlu, p:grow, 9dlu,      pref" ->
 [0,      1,    0,      MAX_VALUE, MAX_VALUE]

 "p, 4dlu, p, 2dlu, 0:grow" ->
 [4, 3,    2, 1,    0]
 

Parameters:
formSpecs - the column specs or row specs
Returns:
a table that maps a spec index to the maximum span for fixed size specs

getLayoutInfo

public FormLayout.LayoutInfo getLayoutInfo(java.awt.Container parent)
Computes and returns the horizontal and vertical grid origins. Performs the same layout process as #layoutContainer but does not layout the components.

This method has been added only to make it easier to debug the form layout. You must not call this method directly; It may be removed in a future release or the visibility may be reduced.

Parameters:
parent - the Container to inspect
Returns:
an object that comprises the grid x and y origins

deepClone

private int[][] deepClone(int[][] array)
Creates and returns a deep copy of the given array. Unlike #clone that performs a shallow copy, this method copies both array levels.

Parameters:
array - the array to clone
Returns:
a deep copy of the given array
See Also:
Object.clone()

writeObject

private void writeObject(java.io.ObjectOutputStream out)
                  throws java.io.IOException
In addition to the default serialization mechanism this class invalidates the component size cache. The cache will be populated again after the deserialization. Also, the fields colComponents and rowComponents have been marked as transient to exclude them from the serialization.

Throws:
java.io.IOException