Class FormLayout

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

public final class FormLayout extends Object implements LayoutManager2, 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 and Actions. 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

 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);
 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();
 

Version:
$Revision: 1.30 $
See Also:
  • Field Details

  • Constructor Details

    • 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(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. The string decoding uses the default LayoutMap.

      This constructor is 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:
      NullPointerException - if encodedColumnSpecs is null
      See Also:
    • FormLayout

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

      This constructor is 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",
            myLayoutMap);
      
       // Right-aligned label, gap, component, gap, component
       FormLayout layout = new FormLayout(
            "right:pref, @lcgap, 50dlu, 4dlu, 50dlu",
            myLayoutMap);
      
       // Left-aligned labels, gap, components, gap, components
       FormLayout layout = new FormLayout(
            "left:pref, @lcgap, pref, @myGap, pref",
            myLayoutMap);
       
      See the class comment for more examples.
      Parameters:
      encodedColumnSpecs - comma separated encoded column specifications
      layoutMap - expands layout column and row variables
      Throws:
      NullPointerException - if encodedColumnSpecs or layoutMap is null
      Since:
      1.2
      See Also:
    • FormLayout

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

      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:
      NullPointerException - if encodedColumnSpecs or encodedRowSpecs is null
      See Also:
    • FormLayout

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

      Examples:

       FormLayout layout = new FormLayout(
            "pref, 4dlu, pref",               // columns
            "p, 3dlu, p",                     // rows
            myLayoutMap);                     // custom LayoutMap
      
       FormLayout layout = new FormLayout(
            "right:pref, 4dlu, pref",         // columns
            "p, @lgap, p, @lgap, fill:p:grow",// rows
            myLayoutMap);                     // custom LayoutMap
      
       FormLayout layout = new FormLayout(
            "left:pref, 4dlu, 50dlu",         // columns
            "p, 2px, p, 3dlu, p, 9dlu, p",    // rows
            myLayoutMap);                     // custom LayoutMap
      
       FormLayout layout = new FormLayout(
            "max(75dlu;pref), 4dlu, default", // columns
            "p, 3dlu, p, 3dlu, p, 3dlu, p",   // rows
            myLayoutMap);                     // custom LayoutMap
       
      See the class comment for more examples.
      Parameters:
      encodedColumnSpecs - comma separated encoded column specifications
      encodedRowSpecs - comma separated encoded row specifications
      layoutMap - expands layout column and row variables
      Throws:
      NullPointerException - if encodedColumnSpecs, encodedRowSpecs, or layoutMap is null
      Since:
      1.2
    • FormLayout

      public FormLayout(ColumnSpec[] colSpecs)
      Constructs a FormLayout using the given column specifications. The constructed layout has no rows; these must be added before components can be added to the layout container.
      Parameters:
      colSpecs - an array of column specifications.
      Throws:
      NullPointerException - if colSpecs is null
      Since:
      1.1
    • 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:
      NullPointerException - if colSpecs or rowSpecs is null
  • Method Details

    • getColumnCount

      public int getColumnCount()
      Returns the number of columns in this layout.
      Returns:
      the number of columns
    • 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:
      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:
      NullPointerException - if columnSpec is null
      IndexOutOfBoundsException - if the column 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:
      NullPointerException - if columnSpec 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:
      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:
      IndexOutOfBoundsException - if the column index is out of range
      IllegalStateException - if the column contains components or if the column is already grouped
      See Also:
    • getRowCount

      public int getRowCount()
      Returns the number of rows in this layout.
      Returns:
      the number of rows
    • 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:
      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:
      NullPointerException - if rowSpec is null
      IndexOutOfBoundsException - if the row index is out of range
    • 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:
      NullPointerException - if rowSpec is null
    • insertRow

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

      The component shift works as follows: components that were located below the inserted row are shifted one row to the bottom; component row span is increased by one if it intersects the new row.

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

      Parameters:
      rowIndex - index of the row to be inserted
      rowSpec - specification of the row to be inserted
      Throws:
      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:
      IndexOutOfBoundsException - if the row index is out of range
      IllegalStateException - if the row contains components or if the row is already grouped
      See Also:
    • 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:
      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:
      IllegalStateException - if a removed column contains components
    • adjustGroupIndices

      private static 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:
      IllegalStateException - if we remove and the index is grouped
    • getConstraints

      public CellConstraints getConstraints(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:
      NullPointerException - if component is null
      IllegalStateException - if component has not been added to the container
    • getConstraints0

      private CellConstraints getConstraints0(Component component)
    • setConstraints

      public void setConstraints(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:
      NullPointerException - if component or constraints is null
    • removeConstraints

      private void removeConstraints(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[][] groupOfIndices)
      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:
      groupOfIndices - a two-dimensional array of column groups indices
      Throws:
      IndexOutOfBoundsException - if an index is outside the grid
      IllegalArgumentException - if a column index is used twice, or of a group of indices contains only a single element
    • setColumnGroupsImpl

      private void setColumnGroupsImpl(int[][] groupOfIndices, boolean checkIndices)
    • setColumnGroup

      public void setColumnGroup(int... indices)
      Sets a single column group, where each column gets the same width.

      Example:

       // Group columns 1, 3 and 4.
       setColumnGroup(1, 3, 4);
       
      Parameters:
      indices - the indices for a single column group
      Throws:
      IndexOutOfBoundsException - if an index is outside the grid
      IllegalArgumentException - if a column index is used twice or if there is only a single index
      NullPointerException - if indices is null
      Since:
      1.8
      See Also:
    • 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[][] groupOfIndices)
      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:
      groupOfIndices - a two-dimensional array of row group indices
      Throws:
      IndexOutOfBoundsException - if an index is outside the grid
      IllegalArgumentException - if a column index is used twice, or of a group of indices contains only a single element
    • setRowGroupsImpl

      private void setRowGroupsImpl(int[][] groupOfIndices, boolean checkIndices)
    • setRowGroup

      public void setRowGroup(int... indices)
      Sets a single row group, where each row gets the same height.

      Example:

       // Group rows 1 and 2.
       setRowGroup(1, 2);
       
      Parameters:
      indices - the indices for a single row group
      Throws:
      IndexOutOfBoundsException - if an index is outside the grid
      IllegalArgumentException - if a row index is used twice or if there is only a single index
      NullPointerException - if indices is null
      Since:
      1.8
      See Also:
    • 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
    • getHonorsVisibility

      public boolean getHonorsVisibility()
      Returns whether invisible components shall be taken into account by this layout. This container-wide setting can be overridden per component. See setHonorsVisibility(boolean) for details.
      Returns:
      true if the component visibility is honored by this FormLayout, false if it is ignored. This setting can be overridden for individual CellConstraints using setHonorsVisibility(Component, Boolean).
      Since:
      1.2
    • setHonorsVisibility

      public void setHonorsVisibility(boolean b)
      Specifies whether invisible components shall be taken into account by this layout for computing the layout size and setting component bounds. If set to true invisible components will be ignored by the layout. If set to false components will be taken into account regardless of their visibility. Visible components are always used for sizing and positioning.

      The default value for this setting is true. It is useful to set the value to false (in other words to ignore the visibility) if you switch the component visibility dynamically and want the container to retain the size and component positions.

      This container-wide default setting can be overridden per component using setHonorsVisibility(Component, Boolean).

      Components are taken into account, if

      1. they are visible, or
      2. they have no individual setting and the container-wide settings ignores the visibility (honorsVisibility set to false), or
      3. the individual component ignores the visibility.
      Parameters:
      b - true to honor the visibility, i.e. to exclude invisible components from the sizing and positioning, false to ignore the visibility, in other words to layout visible and invisible components
      Since:
      1.2
    • setHonorsVisibility

      public void setHonorsVisibility(Component component, Boolean b)
      Specifies whether the given component shall be taken into account for sizing and positioning. This setting overrides the container-wide default. See setHonorsVisibility(boolean) for details.
      Parameters:
      component - the component that shall get an individual setting
      b - Boolean.TRUE to override the container default and honor the visibility for the given component, Boolean.FALSE to override the container default and ignore the visibility for the given component, null to use the container default value as specified by getHonorsVisibility().
      Since:
      1.2
    • addLayoutComponent

      public void addLayoutComponent(String name, Component component)
      Throws an UnsupportedOperationException. Does not add the specified component with the specified name to the layout.
      Specified by:
      addLayoutComponent in interface LayoutManager
      Parameters:
      name - indicates entry's position and anchor
      component - component to add
      Throws:
      UnsupportedOperationException - always
    • addLayoutComponent

      public void addLayoutComponent(Component comp, 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 LayoutManager2
      Parameters:
      comp - the component to be added
      constraints - the component's cell constraints
      Throws:
      NullPointerException - if constraints is null
      IllegalArgumentException - if constraints is neither a String, nor a CellConstraints object, or a String that is rejected by the CellConstraints construction
    • removeLayoutComponent

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

      Most applications do not call this method directly.

      Specified by:
      removeLayoutComponent in interface LayoutManager
      Parameters:
      comp - the component to be removed.
      See Also:
    • minimumLayoutSize

      public Dimension minimumLayoutSize(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 LayoutManager
      Parameters:
      parent - the container in which to do the layout
      Returns:
      the minimum size of the parent container
      See Also:
    • preferredLayoutSize

      public Dimension preferredLayoutSize(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 LayoutManager
      Parameters:
      parent - the container in which to do the layout
      Returns:
      the preferred size of the parent container
      See Also:
    • maximumLayoutSize

      public Dimension maximumLayoutSize(Container target)
      Returns the maximum dimensions for this layout given the components in the specified target container.
      Specified by:
      maximumLayoutSize in interface LayoutManager2
      Parameters:
      target - the container which needs to be laid out
      Returns:
      the maximum dimensions for this layout
      See Also:
    • getLayoutAlignmentX

      public float getLayoutAlignmentX(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 farthest away from the origin, 0.5 is centered, etc.
      Specified by:
      getLayoutAlignmentX in interface LayoutManager2
      Parameters:
      parent - the parent container
      Returns:
      the value 0.5f to indicate center alignment
    • getLayoutAlignmentY

      public float getLayoutAlignmentY(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 farthest away from the origin, 0.5 is centered, etc.
      Specified by:
      getLayoutAlignmentY in interface LayoutManager2
      Parameters:
      parent - the parent container
      Returns:
      the value 0.5f to indicate center alignment
    • invalidateLayout

      public void invalidateLayout(Container target)
      Invalidates the layout, indicating that if the layout manager has cached information it should be discarded.
      Specified by:
      invalidateLayout in interface LayoutManager2
      Parameters:
      target - the container that holds the layout to be invalidated
    • layoutContainer

      public void layoutContainer(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 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 LayoutManager
      Parameters:
      parent - the container in which to do the layout
      See Also:
    • 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.

    • computeLayoutSize

      private Dimension computeLayoutSize(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 static int[] computeGridOrigins(Container container, int totalSize, int offset, List formSpecs, 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
      groupIndices - the group specification
      minMeasure - the measure used to determine min sizes
      prefMeasure - the measure used to determine pre sizes
      Returns:
      an int array with the origins
    • computeOrigins

      private static 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 static int[] maximumSizes(Container container, List formSpecs, 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 for 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 determine min sizes
      prefMeasure - the measure used to determine pre sizes
      defaultMeasure - the measure used to determine default sizes
      Returns:
      the column or row sizes
    • compressedSizes

      private static int[] compressedSizes(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 rows that are specified to be compressible will be affected. You can specify a column and row as compressible 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 static 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 static int[] distributedSizes(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
    • computeMaximumFixedSpanTable

      private static int[] computeMaximumFixedSpanTable(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
    • sum

      private static 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
    • invalidateAndRepaint

      private static void invalidateAndRepaint(Container container)
    • takeIntoAccount

      private boolean takeIntoAccount(Component component, CellConstraints cc)
      Checks and answers whether the given component with the specified CellConstraints shall be taken into account for the layout.
      Parameters:
      component - the component to test
      cc - the component's associated CellConstraints
      Returns:
      true if a) component is visible, or b) component has no individual setting and the container-wide settings ignores the visibility, or c) cc indicates that this individual component ignores the visibility.
    • getLayoutInfo

      public FormLayout.LayoutInfo getLayoutInfo(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 static 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:
    • writeObject

      private void writeObject(ObjectOutputStream out) throws 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:
      IOException