Class FormLayout
- java.lang.Object
-
- 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
andRowSpec
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 theFormLayout
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 thePanelBuilder
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 theDefaultFormBuilder
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$
- Author:
- Karsten Lentzsch
- See Also:
ColumnSpec
,RowSpec
,CellConstraints
,AbstractFormBuilder
,ButtonBarBuilder
,DefaultFormBuilder
,FormFactory
,Size
,Sizes
, Serialized Form
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
FormLayout.LayoutInfo
Stores column and row origins.
-
Constructor Summary
Constructors Constructor Description 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
All Methods Instance Methods Concrete Methods Modifier and Type Method Description 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 specifiedconstraints
object.void
addLayoutComponent(java.lang.String name, java.awt.Component component)
Throws anUnsupportedOperationException
.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.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 theColumnSpec
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 theRowSpec
at the specified row index.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.void
invalidateLayout(java.awt.Container target)
Invalidates the layout, indicating that if the layout manager has cached information it should be discarded.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.java.awt.Dimension
minimumLayoutSize(java.awt.Container parent)
Determines the minimum size of theparent
container using this form layout.java.awt.Dimension
preferredLayoutSize(java.awt.Container parent)
Determines the preferred size of theparent
container using this form layout.void
removeColumn(int columnIndex)
Removes the column with the given column index from the 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 theColumnSpec
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 theRowSpec
at the specified row index.
-
-
-
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 isnull
-
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 specificationsencodedRowSpecs
- comma separated encoded row specifications- Throws:
java.lang.NullPointerException
- if encodedColumnSpecs or encodedRowSpecs isnull
-
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 theColumnSpec
at the specified column index.- Parameters:
columnIndex
- the column index of the requestedColumnSpec
- 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 theColumnSpec
at the specified column index.- Parameters:
columnIndex
- the index of the column to be changedcolumnSpec
- theColumnSpec
to be set- Throws:
java.lang.NullPointerException
- if the column specification is nulljava.lang.IndexOutOfBoundsException
- if the column index is out of range
-
getRowSpec
public RowSpec getRowSpec(int rowIndex)
Returns theRowSpec
at the specified row index.- Parameters:
rowIndex
- the row index of the requestedRowSpec
- 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 theRowSpec
at the specified row index.- Parameters:
rowIndex
- the index of the row to be changedrowSpec
- theRowSpec
to be set- Throws:
java.lang.NullPointerException
- if the row specification is nulljava.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 insertedcolumnSpec
- 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 rangejava.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 insertedrowSpec
- 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 rangejava.lang.IllegalStateException
- if the row contains components or if the row is already grouped
-
getConstraints
public CellConstraints getConstraints(java.awt.Component component)
Looks up and returns the constraints for the specified component. A copy of the actualCellConstraints
object is returned.- Parameters:
component
- the component to be queried- Returns:
- the
CellConstraints
for the specified component - Throws:
java.lang.NullPointerException
- if component isnull
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 modifiedconstraints
- the constraints to be applied- Throws:
java.lang.NullPointerException
- if the component or constraints object isnull
-
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 gridjava.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 anUnsupportedOperationException
. Does not add the specified component with the specified name to the layout.- Specified by:
addLayoutComponent
in interfacejava.awt.LayoutManager
- Parameters:
name
- indicates entry's position and anchorcomponent
- 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 specifiedconstraints
object. Note that constraints are mutable and are, therefore, cloned when cached.- Specified by:
addLayoutComponent
in interfacejava.awt.LayoutManager2
- Parameters:
comp
- the component to be addedconstraints
- the component's cell constraints- Throws:
java.lang.NullPointerException
- ifconstraints
isnull
java.lang.IllegalArgumentException
- ifconstraints
is not aCellConstraints
or a String that cannot be used to construct aCellConstraints
-
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 interfacejava.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 theparent
container using this form layout.Most applications do not call this method directly.
- Specified by:
minimumLayoutSize
in interfacejava.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 theparent
container using this form layout.Most applications do not call this method directly.
- Specified by:
preferredLayoutSize
in interfacejava.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 interfacejava.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 interfacejava.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 interfacejava.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 interfacejava.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 constraints of thisFormLayout
object.Most applications do not call this method directly.
The form layout performs the following steps:
- find components that occupy exactly one column or row
- compute minimum widths and heights
- compute preferred widths and heights
- give cols and row equal size if they share a group
- compress default columns and rows if total is less than pref size
- give cols and row equal size if they share a group
- distribute free space
- set components bounds
- Specified by:
layoutContainer
in interfacejava.awt.LayoutManager
- Parameters:
parent
- the container in which to do the layout- See Also:
Container
,Container.doLayout()
-
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
- theContainer
to inspect- Returns:
- an object that comprises the grid x and y origins
-
-