com.gargoylesoftware.base.gui
Class TableLayout

java.lang.Object
  extended by com.gargoylesoftware.base.gui.TableLayout
All Implemented Interfaces:
java.awt.LayoutManager, java.awt.LayoutManager2, java.io.Serializable, javax.swing.SwingConstants

public class TableLayout
extends java.lang.Object
implements java.awt.LayoutManager2, javax.swing.SwingConstants, java.io.Serializable

The TableLayout lays out items based on a table of rows and columns.

If you are doing simple layout, you can specify constraints as strings of the format "row,column". If you want the component to stretch over multiple rows/columns then you can specify the constraint as "row+rowspan,column+columnspan" as shown in the sample below.

 final TableLayout layout = new TableLayout();
 final JPanel panel = new JPanel(layout);

 panel.add( new JLabel("squirrel"), "1,1" );
 panel.add( new JLabel("raccoon"), "1,2" );
 panel.add( new JLabel("bluejay"), "2,1" );
 panel.add( new JLabel("goldfish"), "2,2" );
 panel.add( new JLabel("marshhawk"), "3,1+3" );
 
If you want more flexibility over the layout then this, use a TableLayoutConstraints object instead of a string. Here is a more complicated sample that uses TableLayoutConstraints to customize the layout a bit more. Note the use of TableLayoutDebuggingPanel - this will draw lines on layout boundaries to help debug layout problems.
 final TableLayout layout = new TableLayout();
 final JPanel panel = new TableLayoutDebuggingPanel(layout);

 TableLayoutConstraints constraints;

 layout.setRowExpandable(1, true);

 constraints = new TableLayoutConstraints(1,1);
 constraints.setVerticalStretch(true);
 panel.add( new JButton("squirrel"), constraints );

 constraints = new TableLayoutConstraints(1,2);
 constraints.setVerticalAlignment(TableLayout.TOP);
 panel.add( new JButton("raccoon"), constraints );

 panel.add( new JButton("bluejay"), "2,1" );
 panel.add( new JButton("goldfish"), "2,2" );
 panel.add( new JButton("marshhawk"), "3,1+3" );
 
Debugging tip: Most layout problems become obvious if you use a TableLayoutDebuggingPanel to see where the layout boundaries are. In those rare cases where this doesn't give you enough information, try calling setTraceChannel(TraceChannel) with a non-null TraceChannel such as Trace.out or Trace.err. This will dump quite a bit of diagnostic information.
 layout.setTraceChannel(Trace.out)
 

Version:
$Revision: 1.7 $
Author:
Mike Bowler
See Also:
Serialized Form

Nested Class Summary
private  class TableLayout.Entry
          A convenience class to attach the constraints to a component.
private  class TableLayout.Header
          A convenience class to hold information specific to a row or column.
private  class TableLayout.HeaderPermanentInfo
          Contains the information that the user has specified for the specific row or column.
 
Field Summary
private  java.awt.Dimension actualSize_
           
private  int columnCount_
           
private  java.util.Set columnHeaderPermanentInfos_
           
private  java.util.List constraints_
           
private  int horizontalAlignment_
           
private  boolean ignoreInvisibleComponents_
           
private  java.awt.Dimension maximumSize_
           
private  java.awt.Dimension minimumSize_
           
private  java.awt.Container parent_
           
private  java.awt.Dimension preferredSize_
           
private  int rowCount_
           
private  java.util.Set rowHeaderPermanentInfos_
           
private static long serialVersionUID
           
private  TableLayout.Header[] tempColumnHeaders_
           
private  TableLayout.Header[] tempRowHeaders_
           
private  boolean tempSizesAreValid_
           
private  TraceChannel traceChannel_
           
private  int verticalAlignment_
           
 
Fields inherited from interface javax.swing.SwingConstants
BOTTOM, CENTER, EAST, HORIZONTAL, LEADING, LEFT, NEXT, NORTH, NORTH_EAST, NORTH_WEST, PREVIOUS, RIGHT, SOUTH, SOUTH_EAST, SOUTH_WEST, TOP, TRAILING, VERTICAL, WEST
 
Constructor Summary
TableLayout()
          Create a new TableLayout.
 
Method Summary
 void addLayoutComponent(java.awt.Component comp, java.lang.Object constraints)
          Add the specified component to the layout with the specified constraints.
 void addLayoutComponent(java.lang.String name, java.awt.Component comp)
          Add the specified component to the layout with the specified constraints.
private  void adjustHeaderSizes(TableLayout.Header[] sizes)
          Fix up all the headers such that minimum <= preferred <= maximum
private  void adjustSizesForSpanning(int start, int span, TableLayout.Header[] sizes, int minSize, int preferredSize, int maxSize)
          Adjust the various sizes to account for components than span multiple columns/rows.
private  boolean areAnyExpandable(java.util.Set permanentInfos)
          Return true if any of the infos are expandable.
protected  void assertNotNull(java.lang.String fieldName, java.lang.Object fieldValue)
          Verify that the specified value is not null.
private  void calculateActualSizes(java.awt.Dimension parentSize)
          Calculate the actual sizes to be used based on the actual dimension of the parent container.
private  int calculateActualSizes(TableLayout.Header[] sizes, int preferredLength, int clipLength)
          Calculate the actual sizes for the specified row or column headers.
private  void calculateMinMaxPreferredSizes()
          Calculate the various sizes.
private  void calculatePositions(java.awt.Container parent, java.awt.Dimension parentSize)
          Calculate all the positions of the various rows/columns
private  void calculateRowAndColumnCount()
          The list of constraints has been modified.
private  void calculateSizes()
          Calculate all the various sizing information required for this layout.
 void drawOutlines(java.awt.Graphics graphics)
          A debugging method that draws lines on the parent component to show where the table cell boundaries are.
private  void expandToFit(TableLayout.Header[] sizes, int clipLength)
          Expand the specified sizes to fit within the specified clipLength.
private  java.awt.Dimension getComponentMaximumSize(java.awt.Component component)
          Return the minimum size of the specified component.
private  java.awt.Dimension getComponentMinimumSize(java.awt.Component component)
          Return the minimum size of the specified component.
private  java.awt.Dimension getComponentPreferredSize(java.awt.Component component)
          Return the minimum size of the specified component.
private  TableLayoutConstraints getConstraints(java.awt.Component component)
          Return the TableLayoutConstraints object that corresponds to the specified component or null if this component could not be found.
private  TableLayout.Header[] getExpandableHeaders(int first, int last, TableLayout.Header[] headers)
          Return an array containing all the headers that are expandable.
 int getHorizontalAlignment()
          Return the horizontal alignment.
 boolean getIgnoreInvisibleComponents()
          Get whether or not we should ignore an components that are not visible.
 float getLayoutAlignmentX(java.awt.Container target)
          I don't really understand what this method is supposed to return so I always return 0F.
 float getLayoutAlignmentY(java.awt.Container target)
          I don't really understand what this method is supposed to return so I always return 0F.
private  int getMinimumColumnWidth(int index)
          Return the minimum column width.
private  int getMinimumRowHeight(int index)
          Return the minimum row height.
private  TableLayout.HeaderPermanentInfo getPermanentInfo(java.util.Set infoList, int index, boolean createIfNeeded)
          TODO: Provide comments
 TraceChannel getTraceChannel()
          Return the trace channel.
 int getVerticalAlignment()
          Return the vertical alignment.
private  void initTempSizes()
          Initialize the temporary arrays (tempRowHeaders_ and tempColumnHeaders_) for use in a calculation.
private  void invalidateLayout()
          Invalidate the layout.
 void invalidateLayout(java.awt.Container target)
          Invalidate the layout and throw away and temporary calculations.
 boolean isColumnExpandable(int index)
          Return true if this column can be expanded beyond its preferred size.
 boolean isRowExpandable(int index)
          Return true if this row can be expanded beyond its preferred size.
 void layoutContainer(java.awt.Container parent)
          Layout all the components in this container.
 java.awt.Dimension maximumLayoutSize(java.awt.Container target)
          Return the maximum layout size.
 java.awt.Dimension minimumLayoutSize(java.awt.Container parent)
          Get the minimum size of this layout.
private  void positionComponent(TableLayout.Entry entry, int x, int y, int width, int height)
          Position one component given the bounding coordinates
 java.awt.Dimension preferredLayoutSize(java.awt.Container parent)
          Return the preferred layout size.
 void removeLayoutComponent(java.awt.Component comp)
          Remove the specified component from the layout.
 void setColumnExpandable(int index, boolean isExpandable)
          Set whether this column can be expanded beyond its preferred size.
 void setHorizontalAlignment(int alignment)
          Set the vertical alignment.
 void setIgnoreInvisibleComponents(boolean ignore)
          Set whether or not we should ignore an components that are not visible.
 void setMinimumColumnWidth(int index, int size)
          Set the minimum column width for a specific column.
 void setMinimumRowHeight(int index, int size)
          Set the minimum row height for a specific row.
private  void setParent(java.awt.Container newParent)
          Set the parent container for this layout.
 void setRowExpandable(int index, boolean isExpandable)
          Set whether this row can be expanded beyond its preferred size.
 void setTraceChannel(TraceChannel channel)
          Set the trace channel used for printing diagnostic information.
 void setVerticalAlignment(int alignment)
          Set the vertical alignment.
private  void shrinkToFit(TableLayout.Header[] sizes, int clipLength)
          Shrink the specified sizes to fit within the specified clipLength.
private static java.lang.String toString(java.awt.Dimension dimension)
          Convenience method to create a string from a Dimension object.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

serialVersionUID

private static final long serialVersionUID
See Also:
Constant Field Values

rowHeaderPermanentInfos_

private final java.util.Set rowHeaderPermanentInfos_

columnHeaderPermanentInfos_

private final java.util.Set columnHeaderPermanentInfos_

parent_

private java.awt.Container parent_

constraints_

private final java.util.List constraints_

traceChannel_

private TraceChannel traceChannel_

tempColumnHeaders_

private TableLayout.Header[] tempColumnHeaders_

tempRowHeaders_

private TableLayout.Header[] tempRowHeaders_

columnCount_

private int columnCount_

rowCount_

private int rowCount_

tempSizesAreValid_

private boolean tempSizesAreValid_

verticalAlignment_

private int verticalAlignment_

horizontalAlignment_

private int horizontalAlignment_

minimumSize_

private java.awt.Dimension minimumSize_

maximumSize_

private java.awt.Dimension maximumSize_

preferredSize_

private java.awt.Dimension preferredSize_

actualSize_

private java.awt.Dimension actualSize_

ignoreInvisibleComponents_

private boolean ignoreInvisibleComponents_
Constructor Detail

TableLayout

public TableLayout()
Create a new TableLayout.

Method Detail

toString

private static java.lang.String toString(java.awt.Dimension dimension)
Convenience method to create a string from a Dimension object.

Parameters:
dimension - Description of Parameter
Returns:
Description of the Returned Value

setVerticalAlignment

public void setVerticalAlignment(int alignment)
Set the vertical alignment. Legal values are:

Parameters:
alignment - The new vertical alignment.

setHorizontalAlignment

public void setHorizontalAlignment(int alignment)
Set the vertical alignment. Legal values are:

Parameters:
alignment - The new horizontal alignment.

setMinimumRowHeight

public void setMinimumRowHeight(int index,
                                int size)
Set the minimum row height for a specific row.

Parameters:
index - The row that we are setting the height for.
size - The new minimum height.

setMinimumColumnWidth

public void setMinimumColumnWidth(int index,
                                  int size)
Set the minimum column width for a specific column.

Parameters:
index - The column that we are setting the width for.
size - The new width.

setRowExpandable

public void setRowExpandable(int index,
                             boolean isExpandable)
Set whether this row can be expanded beyond its preferred size.

Parameters:
index - The row index.
isExpandable - true if the row is to be expandable.

setColumnExpandable

public void setColumnExpandable(int index,
                                boolean isExpandable)
Set whether this column can be expanded beyond its preferred size.

Parameters:
index - The column index.
isExpandable - true if the column is to be expandable.

setTraceChannel

public void setTraceChannel(TraceChannel channel)
Set the trace channel used for printing diagnostic information. If the channel is null then no tracing will be done.

Parameters:
channel - The new trace channel.

setIgnoreInvisibleComponents

public void setIgnoreInvisibleComponents(boolean ignore)
Set whether or not we should ignore an components that are not visible.

Parameters:
ignore - True if we should ignore them.

getLayoutAlignmentX

public float getLayoutAlignmentX(java.awt.Container target)
I don't really understand what this method is supposed to return so I always return 0F. If you can explain this one to me then send me an email at mbowler@GargoyleSoftware.com and I'll fix this method up appropriately.

Specified by:
getLayoutAlignmentX in interface java.awt.LayoutManager2
Parameters:
target - The container that this layout is managing.
Returns:
Zero.

getLayoutAlignmentY

public float getLayoutAlignmentY(java.awt.Container target)
I don't really understand what this method is supposed to return so I always return 0F. If you can explain this one to me then send me an email at mbowler@GargoyleSoftware.com and I'll fix this method up appropriately.

Specified by:
getLayoutAlignmentY in interface java.awt.LayoutManager2
Parameters:
target - The container that this layout is managing.
Returns:
Zero.

getVerticalAlignment

public int getVerticalAlignment()
Return the vertical alignment.

Returns:
The vertical alignment.
See Also:
setVerticalAlignment(int)

getHorizontalAlignment

public int getHorizontalAlignment()
Return the horizontal alignment.

Returns:
The horizontal alignment.

isRowExpandable

public boolean isRowExpandable(int index)
Return true if this row can be expanded beyond its preferred size. The default is false.

Parameters:
index - The row index
Returns:
true if the specified row is expandable.

isColumnExpandable

public boolean isColumnExpandable(int index)
Return true if this column can be expanded beyond its preferred size. The default is false.

Parameters:
index - The column.
Returns:
true if the column is expandable.

getTraceChannel

public TraceChannel getTraceChannel()
Return the trace channel.

Returns:
The trace channel or null if one wasn't set.

getIgnoreInvisibleComponents

public boolean getIgnoreInvisibleComponents()
Get whether or not we should ignore an components that are not visible.

Returns:
True if we should ignore them.

addLayoutComponent

public void addLayoutComponent(java.lang.String name,
                               java.awt.Component comp)
                        throws java.lang.UnsupportedOperationException
Add the specified component to the layout with the specified constraints. This method should never be called as Container.addImpl() should call addLayoutComponent(Component,Object) instead. Not implemented.

Specified by:
addLayoutComponent in interface java.awt.LayoutManager
Parameters:
name - The constraints string.
comp - the component that is being added.
Throws:
java.lang.UnsupportedOperationException - If called.

addLayoutComponent

public void addLayoutComponent(java.awt.Component comp,
                               java.lang.Object constraints)
Add the specified component to the layout with the specified constraints. Throw an IllegalArgumentException if the same component is specified twice. The constraints object can be either an instance of TableLayoutConstraints or a String. If it is a string then an instance of TableLayoutConstraints will be created with the method TableLayoutConstraints.makeConstraints(String).

Specified by:
addLayoutComponent in interface java.awt.LayoutManager2
Parameters:
comp - The component that is being added.
constraints - The constraints object.
See Also:
TableLayoutConstraints.makeConstraints(String)

removeLayoutComponent

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

Specified by:
removeLayoutComponent in interface java.awt.LayoutManager
Parameters:
comp - The component to remove.

minimumLayoutSize

public java.awt.Dimension minimumLayoutSize(java.awt.Container parent)
Get the minimum size of this layout.

Specified by:
minimumLayoutSize in interface java.awt.LayoutManager
Parameters:
parent - The container that this layout is managing.
Returns:
The minimum size required for this layout.

preferredLayoutSize

public java.awt.Dimension preferredLayoutSize(java.awt.Container parent)
Return the preferred layout size.

Specified by:
preferredLayoutSize in interface java.awt.LayoutManager
Parameters:
parent - The container that this layout is managing.
Returns:
The preferred layout size.

layoutContainer

public void layoutContainer(java.awt.Container parent)
Layout all the components in this container.

Specified by:
layoutContainer in interface java.awt.LayoutManager
Parameters:
parent - The container that this layout is managing.

maximumLayoutSize

public java.awt.Dimension maximumLayoutSize(java.awt.Container target)
Return the maximum layout size.

Specified by:
maximumLayoutSize in interface java.awt.LayoutManager2
Parameters:
target - The container that this layout is managing.
Returns:
The maximum layout size.

invalidateLayout

public void invalidateLayout(java.awt.Container target)
Invalidate the layout and throw away and temporary calculations.

Specified by:
invalidateLayout in interface java.awt.LayoutManager2
Parameters:
target - The container that this layout is managing.

drawOutlines

public void drawOutlines(java.awt.Graphics graphics)
A debugging method that draws lines on the parent component to show where the table cell boundaries are. The lines will be drawn in the current colour.

Parameters:
graphics - The graphics object.
See Also:
TableLayoutDebuggingPanel

setParent

private void setParent(java.awt.Container newParent)
Set the parent container for this layout.

Parameters:
newParent - The new parent value

getExpandableHeaders

private TableLayout.Header[] getExpandableHeaders(int first,
                                                  int last,
                                                  TableLayout.Header[] headers)
Return an array containing all the headers that are expandable.

Parameters:
first - Description of Parameter
last - Description of Parameter
headers - Description of Parameter
Returns:
The expandableHeaders value

getMinimumRowHeight

private int getMinimumRowHeight(int index)
Return the minimum row height. The default is 0.

Parameters:
index - Description of Parameter
Returns:
The minimumRowHeight value

getMinimumColumnWidth

private int getMinimumColumnWidth(int index)
Return the minimum column width. The default is 0.

Parameters:
index - The column index.
Returns:
The minimum column width for the specified column.

getPermanentInfo

private TableLayout.HeaderPermanentInfo getPermanentInfo(java.util.Set infoList,
                                                         int index,
                                                         boolean createIfNeeded)
TODO: Provide comments

Parameters:
infoList - Description of Parameter
index - Description of Parameter
createIfNeeded - Description of Parameter
Returns:
The permanentInfo value

getConstraints

private TableLayoutConstraints getConstraints(java.awt.Component component)
Return the TableLayoutConstraints object that corresponds to the specified component or null if this component could not be found.

Parameters:
component - Description of Parameter
Returns:
The constraints value

getComponentMinimumSize

private final java.awt.Dimension getComponentMinimumSize(java.awt.Component component)
Return the minimum size of the specified component. If the component is not visible and we are ignoring invisible components then return a size of 0,0

Parameters:
component - The component that we will be querying
Returns:
The size

getComponentMaximumSize

private final java.awt.Dimension getComponentMaximumSize(java.awt.Component component)
Return the minimum size of the specified component. If the component is not visible and we are ignoring invisible components then return a size of 0,0

Parameters:
component - The component that we will be querying
Returns:
The size

getComponentPreferredSize

private final java.awt.Dimension getComponentPreferredSize(java.awt.Component component)
Return the minimum size of the specified component. If the component is not visible and we are ignoring invisible components then return a size of 0,0

Parameters:
component - The component that we will be querying
Returns:
The size

calculateMinMaxPreferredSizes

private void calculateMinMaxPreferredSizes()
Calculate the various sizes.


areAnyExpandable

private boolean areAnyExpandable(java.util.Set permanentInfos)
Return true if any of the infos are expandable.

Parameters:
permanentInfos - The infos.
Returns:
Description of the Returned Value

invalidateLayout

private void invalidateLayout()
Invalidate the layout.


calculateSizes

private void calculateSizes()
Calculate all the various sizing information required for this layout. Called by layoutContainer(), minimumLayoutSize(), maximumLayoutSize()


adjustSizesForSpanning

private void adjustSizesForSpanning(int start,
                                    int span,
                                    TableLayout.Header[] sizes,
                                    int minSize,
                                    int preferredSize,
                                    int maxSize)
Adjust the various sizes to account for components than span multiple columns/rows.

Parameters:
start - The starting index of the component.
span - The number of columns/rows that the component spans.
sizes - The headers that we are adjusting.
minSize - The minimum size of the component.
preferredSize - The preferred size of the component.
maxSize - The maximum size of the component.

calculatePositions

private void calculatePositions(java.awt.Container parent,
                                java.awt.Dimension parentSize)
Calculate all the positions of the various rows/columns

Parameters:
parent - Description of Parameter
parentSize - Description of Parameter

positionComponent

private void positionComponent(TableLayout.Entry entry,
                               int x,
                               int y,
                               int width,
                               int height)
Position one component given the bounding coordinates

Parameters:
entry - Description of Parameter
x - Description of Parameter
y - Description of Parameter
width - Description of Parameter
height - Description of Parameter

calculateRowAndColumnCount

private void calculateRowAndColumnCount()
The list of constraints has been modified. Update the row and column counts according to the new constraints.


calculateActualSizes

private void calculateActualSizes(java.awt.Dimension parentSize)
Calculate the actual sizes to be used based on the actual dimension of the parent container.

Parameters:
parentSize - Description of Parameter

adjustHeaderSizes

private void adjustHeaderSizes(TableLayout.Header[] sizes)
Fix up all the headers such that minimum <= preferred <= maximum

Parameters:
sizes - Description of Parameter

calculateActualSizes

private int calculateActualSizes(TableLayout.Header[] sizes,
                                 int preferredLength,
                                 int clipLength)
Calculate the actual sizes for the specified row or column headers. Return the actual length.

Parameters:
sizes - Description of Parameter
preferredLength - Description of Parameter
clipLength - Description of Parameter
Returns:
Description of the Returned Value

expandToFit

private void expandToFit(TableLayout.Header[] sizes,
                         int clipLength)
Expand the specified sizes to fit within the specified clipLength.

Parameters:
sizes - Description of Parameter
clipLength - Description of Parameter

shrinkToFit

private void shrinkToFit(TableLayout.Header[] sizes,
                         int clipLength)
Shrink the specified sizes to fit within the specified clipLength. Do not shrink beyond the minimum size.

Parameters:
sizes - Description of Parameter
clipLength - Description of Parameter

initTempSizes

private void initTempSizes()
Initialize the temporary arrays (tempRowHeaders_ and tempColumnHeaders_) for use in a calculation.


assertNotNull

protected final void assertNotNull(java.lang.String fieldName,
                                   java.lang.Object fieldValue)
                            throws DetailedNullPointerException
Verify that the specified value is not null. If it is then throw an exception

Parameters:
fieldName - The name of the field to check
fieldValue - The value of the field to check
Throws:
DetailedNullPointerException - If fieldValue is null