Java: FormatPanel
Warning: This is a beta version, and there may be changes. I use it myself on a number of projects, so it is not untested.
- javadoc
- com.fredswartz.fmt-0.7.zip Contains two jar files, com.fredswartz.fmt-0.7.jar which contains FormatPanel, and formatworkbench.jar, which contains a test program.
- FormatWorkbench has a number of FormatPanel examples, and allows changing the format of each examples (but not that component parameter list) to dynmically try different things. Hmmm, seems that the main class isn't marked in the manifest.
Known Bugs
- Failure to diagnose overlapping components (an error) in some cases involving w* or h* produces an ArrayIndexOutOfRangeException instead. This only happens will illegal formats.
Missing features
- Subpanels
- Multiplicities
- Additional validity checking.
Try it
You can try a Java Web Start version of the FormatWordbencb. This will load a Java program onto your machine, but it has security permisssions to read or write your files, or do anything else dangerous. It will remain cached on your machine so that you can run it offline if you wish. Every time you run it a check will be made to see if there are updates, so it is always current. FormatWorkbench
Background
GridBagLayout
makes it possible to build nice looking and behaving layouts, but it's insanely difficult and error prone to work with, even with convenience functions that most people write.- Other third-party layouts provide improvements, eg TableLayout and HIGLayout. They inspired me to take the process a little farther.
- FormatPanel extends JPanel. The current implementation uses an underlying GridBagLayout, but this may change to use my (unreleased) FlexiGridLayout in the future is unresolved. If this change is made, it should be backward compatible while providing additional facilities (like cell equality constraints and better degradation when reducing layouts below their preferred size).
Advantages
- Format driven
- The general idea is to specify a format string (eg, "'Name' $ / 'Phone' $") and an array of components (Java 5 allows variable length parameters list). If you're familiar with printf() or other format-driven styles of programming, you should be comfortable with FormatPanel. Generally laying out all elements takes only two or three lines of code!
- Grid with variable size rows and columns. Expandable.
- This is similar in concept to GridBagLayout or an HTML table. Rows and columns are numbered from one and don't count borders and gaps (see below). The row and column sizes are computed as the largest of the preferred sizes of all components in that row or column. Expandable (eg, window is resized) cells are specified with x (horizontally expandable, or y (vertically expandable).
- Multicell areas and alignment
- A component can span more than one cell in the grid. Components fill their entire area by default, but may take their preferred size and be centered or aligned to a single or any two edges.
- Borders and Gaps
- Sun's Human Interface Guidelines give some guidance on layout. GridBagLayout, however, knows nothing about these guidelines, specifically giving no special help with borders and gaps. Format panel defaults to a standard border size (11 or 12 pixels) with 5-pixel gaps between rows and columns.
- Massive reduction in layout code
- I would say it roughly reduces the number of lines of layout code by about 50.
- Labels and separators
- Labels (single quoted strings) and line separators (format characters | and _) can be specified in the format, thereby reducing the number of contentless components that need to be created.
Example
// Create components first. JTextField fnField = new JTextField(15); JTextField lnField = new JTextField(15); ... FormatPanel content = new FormatPanel( "'First Name' $x / 'Last Name' $" , new Component[] {fnField, lnField});
Basic Concepts
The format codes fall into the following groups.
- Component insertion. Components are taken from the parameter list ('$').
- Movement codes ('/' start next row, ',' next column, etc)
- Component creation. Literal components (labels and separators) can be created by the format.
- Constraint codes. These follow a component and specify information about it: width ('w'), height ('h'), expandability ('x' and 'y'), alignment in cell ('NSEW'), etc.
- Border specification ('B') - Working, but enhancements planned..
- Gap specification ('G') - Allows specification of default gap unit size.
- Subpanels ('[]') - Unimplemented.
Movement codes
Explicit movement (/ , \
)
/
- Start next row.,
- Skip current column.\
- Start next column.rn
- Specifies row n. It's usually better to use relative specification.cn
- Specifies col n. It's usually better to use relative specification.
Component codes
Component specification. ($ '...' F - |
) Followed by optional constraints. By default
inserts components in next free position in the current row.
$
- Inserts next component from parameter list. May be followed by constraints.'label'
- Creates and inserts a JLabel. May be followed by constraints._
- Creates and inserts a horizontal JSeparator. May be followed by constraints.|
- Creates and inserts a vertical JSeparator. May be followed by constraints.
Constraint codes (w h N S E W x y
)
Constraint codes must follow a component specification.
wn
- Width of component space in content columns (ie, ignore gaps).hn
- Height of component space in content rows (ignore gaps in counting rows).N S E W
- Where in the component space the component should be aligned. By default, components are expanded to all edges of their space. You may specify a single edge (N S E W), or any combination of two edges.x
- Component space may expand horizontally (x-axis) when container is stretched.y
- Component space may expand vertically (y-axis) when constainer is stretched.
Gaps
Gaps are specified by a direction (N S E W
), followed by an
optional size in pixels, and an optional x or y expansion.