XmlGridLayout is a LayoutManager that seeks to provide all the power of
GridBagLayout with the simplicity of an HTML table. Also, it tries to be
a way to separate the layout declaration from the component declaration.
GridBagLayout with the simplicity of an HTML table. Also, it tries to be
a way to separate the layout declaration from the component declaration.
Let see an example with Layout and Component declared together:
JPanel panel=new JPanel(new BorderLayout());
panel.add(new JLabel(),BorderLayout.SOUTH);
panel.add(new JPanel(),BorderLayout.CENTER);
If we want to change the layout of this panel (be it change the manager
or change the placement) we would need to modify 3 lines of code.
Now let's see an example with Layout and Components declared separately:
JPanel panel=new JPanel(new XmlGridLayout(layout);
panel.add("mainPanel",new JPanel());
panel.add("statusLabel",new JLabel());
The layout variable could be a declared variable with the layout string,
or the readed content of a file.
Now,if we want to change the layout we just need to change the content
of the layout variable (or the file with the layout definition). This
means that the same layout coud be used by several components (just pass
the same layout variable to all the XmlGridLayout instances). Also,
notice that each component is given a descriptive name in the layout.
2. Requirements
XmlGridLayout has been tested with the JRE 1.4.0+. I think that it could
work in previous versions if the org.apache.crimson.parser.XMLReaderImpl
class and supporting classes are omewhere in the classpath, but haven't
test it so I can't guarantee it.
3. Directory Structure
The XmlGridLayout package has several directories in it:
src XmlGridLayout sources. These are the only sources you need to
rebuild the project
demo Source of the demo classes
tests Sources of the tests
doc Javadocs
out where all the compiled classes are stored.
4. Rebuilding from the sources
To recompile, check the build.xml file and provide the path to all the
libraries needed (basically, JUnit) and run the main target. At some
future time a package with all the required libraries will also be
provided.
5. Layout Sintaxis
A layout is defined using an xml document which has a sintax that is
very similar to that of an HTML table. Currently a DTD is not provided,
and the idea is that layout documents wont be checked against a DTD but
the parsing process will check for errors.
Tags and Attributes are case sensitive. Attribute values are/NOT/ case
sensitive. Following the list of recognized tags:
/Tag/ /Attribute/ /Description/
table Specify the begining of layout declaration
cellpadding This attribute specifies the internal padding of the
component, that is, how much to add to both minimun
width and height of the component. (default=0)
cellspacing This attribute specifies the external padding of the
component, the minimum amount of space between the
component and the edges of the cell (default=0)
tr Specify that a row of compoenents is being defined.
td Specify a cell.
fill Specify whether and how the component must grow to
fit the cell (if needed) Valid values are:
Both, Horizontal, Vertical and None (default: None).
align Specify the horizontal alignment of the component
inside the cell. Valid values are: Left, Right and
Center (default: Center)
valign Specify the vertical alignment of the component inside
the cell. Valud values are: Top, Bottom, Middle
(default: Middle).
colspan Specify how many columns this cell will take as a display
area (default: 1).
width The percentage of the row thar this cell will use.
Last cell will have all the remaining space.
Valid values: from 1% to 100%. Defaults to an even
distribution of space among cells.
height The percentage of the column that this cell will use.
Last cell will have all the remaining space.
Valid values: from 1% to 100%.
Defaults to an even distribution of space among cells.
class The style this cell will use (see below)
styles Opening element to group all the defined cell styles.
style Defines an style. It accepts all the td tag attributes
plus the attribute id
id Defines the id of this style, to be referenced by the class
atribute of the td tag
Let's see an example:
1 <table cellpadding='2' cellspacing='1'>
2 <styles>
3 <style id='fillall' fill='BOTH' width='100%' height='50%' />
4 </styles>
5 <tr>
6 <td align='right' width='50%' height='50%'>component1</td>
7 <td align='left' width=50%' height=50%' valign='top'>component2</td>
8 </tr>
9 <tr>
10 <td colspan='2' class='fillall'>component3</td>
11 </tr>
12 </table>
13
14
Let's explain it, line by line:
<table cellpadding='2' cellspacing='1'>
Here it's declaring a layout that has an internal padding of 2 pixels,
with 1 pixel separation between cells.
<styles>
<style id='fillall' fill='BOTH' width='100%' height='50%' />
</styles>
Now it's defining the styles to be used in the layout. Specifically,
it's creating a style named "fillall", Cells that use this style will
have the 100% of the remaining horizontal space, 50% of the remaining
vertical space and the component will stretch in both directions to fill it.
<tr>
<td align='right' width='50%' height='50%'>component1</td>
<td align='left' width=50%' height=50%' valign='top'>component2</td>
</tr>
Defines a row with two cells. The first cell will have its content
aligned to the right (align='right'), will receive 50% of the remaining
horizontal space (width='50%'), 50% of the remaining vertical space
(height='50%') and is associated to the name component1. The second cell
will have its content aligned to the left (align='left') and to the top
(valign='top'), will receive 50% of the remaining horizontal space
(width='50%'), 50% of the remaining vertical space (height='50%') and is
associated to the name component2.
<tr>
<td colspan='2' class='fillall'>component3</td>
</tr>
On the second row, there is only one cell that will span over 2 columns
(colspan='2'). Note that because the cell was associated to the class
"fillall" then it will have the properties as specified in the style
"fillall". This cell is associated to the name component3
6. How to layout components?
After you build your XML specifying the layout, you must create an
XMLGridLayout instance with that layout, and then add component to the
container using the same names used in the XML. Example:
JFrame frame=new JFrame();
Container panel = frame.getContentPane();
panel.setLayout(new XMLGridLayout(xmlLayout));
Now, you must create as many components as declared in the layout:
JLabel label=new JLabel("This is a label");
JTextField textField=new JTextField("This is a textField");
JTextArea textArea=new JTextArea("This is a textArea");
And now add them to the container, using as the name of the component
the name used in the cell you want it to be:
panel.add("component1",label);
panel.add("component2",textField);
panel.add("component3",textArea);
To see the result, run the class/org.soronthar.layout.ReadmeExample/. In
the top-left corner of the screen you should see the frame configured
using XMLGridLayout, and in the center of the screen the one configured
with the GridBagLayout. Play with both and try to find any difference.
Just for the sake of comparison, here are the equivalent constraints
with GridBagLayout, as used in the example class:
panel.add(label, new GridBagConstraints(0, 0,
1, 1,
0.5, 0.5,
GridBagConstraints.EAST,
GridBagConstraints.NONE,
new Insets(1, 1, 1, 1),
2, 2));
panel.add(textField, new GridBagConstraints(1, 0,
1, 1,
0.5, 0.5,
GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE,
new Insets(1, 1, 1, 1),
2, 2));
panel.add(textArea, new GridBagConstraints(0, 1,
2, 1,
1, 0.5,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
new Insets(1, 1, 1, 1),
2, 2));
7. Demo Classes
org.soronthar.layout.ReadmeExample The class with the example in this
document
org.soronthar.layout.DemoFrame A very crude demo. Toy with it commenting and
decomenting the "LabelC" component.
org.soronthar.layout.BigDemoFrame A performance demo. After the frame in shown,
check the console to see the time spend parsing
the layout from the XML. Toy with it changing the
number of component, but be careful to maintain
the number of columns on sync
*Copyright 2004 Rafael Alvarez (Soronthar)*
JPanel panel=new JPanel(new BorderLayout());
panel.add(new JLabel(),BorderLayout.SOUTH);
panel.add(new JPanel(),BorderLayout.CENTER);
If we want to change the layout of this panel (be it change the manager
or change the placement) we would need to modify 3 lines of code.
Now let's see an example with Layout and Components declared separately:
JPanel panel=new JPanel(new XmlGridLayout(layout);
panel.add("mainPanel",new JPanel());
panel.add("statusLabel",new JLabel());
The layout variable could be a declared variable with the layout string,
or the readed content of a file.
Now,if we want to change the layout we just need to change the content
of the layout variable (or the file with the layout definition). This
means that the same layout coud be used by several components (just pass
the same layout variable to all the XmlGridLayout instances). Also,
notice that each component is given a descriptive name in the layout.
2. Requirements
XmlGridLayout has been tested with the JRE 1.4.0+. I think that it could
work in previous versions if the org.apache.crimson.parser.XMLReaderImpl
class and supporting classes are omewhere in the classpath, but haven't
test it so I can't guarantee it.
3. Directory Structure
The XmlGridLayout package has several directories in it:
src XmlGridLayout sources. These are the only sources you need to
rebuild the project
demo Source of the demo classes
tests Sources of the tests
doc Javadocs
out where all the compiled classes are stored.
4. Rebuilding from the sources
To recompile, check the build.xml file and provide the path to all the
libraries needed (basically, JUnit) and run the main target. At some
future time a package with all the required libraries will also be
provided.
5. Layout Sintaxis
A layout is defined using an xml document which has a sintax that is
very similar to that of an HTML table. Currently a DTD is not provided,
and the idea is that layout documents wont be checked against a DTD but
the parsing process will check for errors.
Tags and Attributes are case sensitive. Attribute values are/NOT/ case
sensitive. Following the list of recognized tags:
/Tag/ /Attribute/ /Description/
table Specify the begining of layout declaration
cellpadding This attribute specifies the internal padding of the
component, that is, how much to add to both minimun
width and height of the component. (default=0)
cellspacing This attribute specifies the external padding of the
component, the minimum amount of space between the
component and the edges of the cell (default=0)
tr Specify that a row of compoenents is being defined.
td Specify a cell.
fill Specify whether and how the component must grow to
fit the cell (if needed) Valid values are:
Both, Horizontal, Vertical and None (default: None).
align Specify the horizontal alignment of the component
inside the cell. Valid values are: Left, Right and
Center (default: Center)
valign Specify the vertical alignment of the component inside
the cell. Valud values are: Top, Bottom, Middle
(default: Middle).
colspan Specify how many columns this cell will take as a display
area (default: 1).
width The percentage of the row thar this cell will use.
Last cell will have all the remaining space.
Valid values: from 1% to 100%. Defaults to an even
distribution of space among cells.
height The percentage of the column that this cell will use.
Last cell will have all the remaining space.
Valid values: from 1% to 100%.
Defaults to an even distribution of space among cells.
class The style this cell will use (see below)
styles Opening element to group all the defined cell styles.
style Defines an style. It accepts all the td tag attributes
plus the attribute id
id Defines the id of this style, to be referenced by the class
atribute of the td tag
Let's see an example:
1 <table cellpadding='2' cellspacing='1'>
2 <styles>
3 <style id='fillall' fill='BOTH' width='100%' height='50%' />
4 </styles>
5 <tr>
6 <td align='right' width='50%' height='50%'>component1</td>
7 <td align='left' width=50%' height=50%' valign='top'>component2</td>
8 </tr>
9 <tr>
10 <td colspan='2' class='fillall'>component3</td>
11 </tr>
12 </table>
13
14
Let's explain it, line by line:
<table cellpadding='2' cellspacing='1'>
Here it's declaring a layout that has an internal padding of 2 pixels,
with 1 pixel separation between cells.
<styles>
<style id='fillall' fill='BOTH' width='100%' height='50%' />
</styles>
Now it's defining the styles to be used in the layout. Specifically,
it's creating a style named "fillall", Cells that use this style will
have the 100% of the remaining horizontal space, 50% of the remaining
vertical space and the component will stretch in both directions to fill it.
<tr>
<td align='right' width='50%' height='50%'>component1</td>
<td align='left' width=50%' height=50%' valign='top'>component2</td>
</tr>
Defines a row with two cells. The first cell will have its content
aligned to the right (align='right'), will receive 50% of the remaining
horizontal space (width='50%'), 50% of the remaining vertical space
(height='50%') and is associated to the name component1. The second cell
will have its content aligned to the left (align='left') and to the top
(valign='top'), will receive 50% of the remaining horizontal space
(width='50%'), 50% of the remaining vertical space (height='50%') and is
associated to the name component2.
<tr>
<td colspan='2' class='fillall'>component3</td>
</tr>
On the second row, there is only one cell that will span over 2 columns
(colspan='2'). Note that because the cell was associated to the class
"fillall" then it will have the properties as specified in the style
"fillall". This cell is associated to the name component3
6. How to layout components?
After you build your XML specifying the layout, you must create an
XMLGridLayout instance with that layout, and then add component to the
container using the same names used in the XML. Example:
JFrame frame=new JFrame();
Container panel = frame.getContentPane();
panel.setLayout(new XMLGridLayout(xmlLayout));
Now, you must create as many components as declared in the layout:
JLabel label=new JLabel("This is a label");
JTextField textField=new JTextField("This is a textField");
JTextArea textArea=new JTextArea("This is a textArea");
And now add them to the container, using as the name of the component
the name used in the cell you want it to be:
panel.add("component1",label);
panel.add("component2",textField);
panel.add("component3",textArea);
To see the result, run the class/org.soronthar.layout.ReadmeExample/. In
the top-left corner of the screen you should see the frame configured
using XMLGridLayout, and in the center of the screen the one configured
with the GridBagLayout. Play with both and try to find any difference.
Just for the sake of comparison, here are the equivalent constraints
with GridBagLayout, as used in the example class:
panel.add(label, new GridBagConstraints(0, 0,
1, 1,
0.5, 0.5,
GridBagConstraints.EAST,
GridBagConstraints.NONE,
new Insets(1, 1, 1, 1),
2, 2));
panel.add(textField, new GridBagConstraints(1, 0,
1, 1,
0.5, 0.5,
GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE,
new Insets(1, 1, 1, 1),
2, 2));
panel.add(textArea, new GridBagConstraints(0, 1,
2, 1,
1, 0.5,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
new Insets(1, 1, 1, 1),
2, 2));
7. Demo Classes
org.soronthar.layout.ReadmeExample The class with the example in this
document
org.soronthar.layout.DemoFrame A very crude demo. Toy with it commenting and
decomenting the "LabelC" component.
org.soronthar.layout.BigDemoFrame A performance demo. After the frame in shown,
check the console to see the time spend parsing
the layout from the XML. Toy with it changing the
number of component, but be careful to maintain
the number of columns on sync
*Copyright 2004 Rafael Alvarez (Soronthar)*