Tutorial
Before we even get started, you will still need to understand the basics of the JGoodies Form Layout manager in order to be effective
with this tool. If you understand the principle of that manager, then you will feel right at home. That
tool can be found here. There is a PDF document
that will explain the basics of the layout manager.
For our tutorial, we will build a simple Customer dialog box that will have the following components...
- Name JGoodies Separator
- Surname JLabel
- Surname JComboBox
- First Name JLabel
- First Name JTextField
- Last Name JLabel
- Last Name JTextField
- Suffix JLabel
- Suffix JComboBox
- Contact JGoodies Separator
- Home Phone JLabel
- Home Phone JTextField
- Work Phone JLabel
- Work Phone JTextField
- Fax JLabel
- Fax JTextField
- Email JLabel
- Email JTextField
- Orders JGoodies Separator
- Order JTable
- JGoodies ButtonBar with OK and Cancel Buttons
So let's discuss the best way to get off the ground with this tool and build the example is to run
the executable jar. There are two jars, one that is executable (formLayoutBuilderx.jar) and one that simply has
the builder itself (formLayoutBuilder.jar). The latter should be used in your project in conjunction with the
JGoodies forms jar file. The executable jar includes the JGoodies stuff for those who just want an easy executable
jar just to test drive the tool. By the way, the code for this project is written using JDK 1.5 but
uses Toby Reyelt's Retroweaver
tool that takes 1.5 class files and converts them to 1.4. You will not be able to compile the code
without JDK 1.5.
java -jar formLayoutBuilderx.jar
The basic paradigm is that you have a set of row specs and column specs that form a grid. You add components by clicking
in the grid and clicking the New button above the table. You can also add rows and columns and delete components
using the buttons there. Try to construct the Customer Screen to look like the following image. You will have to
add rows, move components, etc.
Here is how I did it. This may help you a bit...
Questions and answers...
Q: How do I insert a component?
A: Click the cell in the component table where you want to add a component and click the 'New' Button
Q: How do I make the separator go all the way across?
A: Click the separator component in the table and increase the Column Span property
Q: What is the best way to build the buttons?
A: Create a JGoodies ButtonBar, type 'right' in the alignment property, and use the properties given to add buttons
Q: Why do my labels right align?
A: Because the column definition is right:max(30dlu:pref). Look in the JGoodies docs to see what this means...
Q: I can't find a component I created. How do I find it?
A: Go to the Show Component combobox and select your component, it will be highlighted.
Q: How do I insert a row or column?
A: Click in the table and hit the 'Add Row Before', 'Add Row After', 'Add Column Before', or 'Add Row After' buttons.
Q: How can I move a component around in the grid?
A: Click on the component in the table and use the Position arrows to move it around.
Q: How can I make a component stretch to fill the cell?
A: Click on the component in the table and set the Horizonal or Vertical Alignment properties to 'Fill'.
Q: How can I remove a component?
A: Click on the component in the table and the click the trash can icon.
Q: Can I add another panel and lay it out too?
A: Yes, just add a JPanel component. You will see another constraints tab you can use to layout the subpanel.
Q: How do I set the title on the frame?
A: You can do this with code later
Q: How do I make the JLabels PLAIN instead of BOLD?
A: You can do this with code later using UIManager
So now you have the form looking the way you want. What now. Well, let's first save the xml file out to where
you want to create the Java file for the dialog. Choose File | Save As and save the xml file. It will
look something like this xml file.
You will notice that all this really does is capture the row and column constraints, the names and constraints
of your components. Now let's look at the code that the tool creates. Click File | View Code. The
code looks something like the following...
// here are declarations for the controls you created
javax.swing.JComboBox suffixCombo =
new
javax.swing.JComboBox
()
;
javax.swing.JLabel lastNameLabel =
new
javax.swing.JLabel
(
"Last Name"
)
;
javax.swing.JTextField firstNameText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField lastNameText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField faxText =
new
javax.swing.JTextField
()
;
java.awt.Component contactSeparator = DefaultComponentFactory.getInstance
()
.createSeparator
(
"Contact Info"
)
;
javax.swing.JLabel surnameLabel =
new
javax.swing.JLabel
(
"Surname"
)
;
javax.swing.JButton okButton =
new
javax.swing.JButton
(
"OK"
)
;
javax.swing.JButton cancelButton =
new
javax.swing.JButton
(
"Cancel"
)
;
java.awt.Component buttonBar = ButtonBarFactory.buildRightAlignedBar
(
new
JButton
[] {
okButton,cancelButton
})
;
javax.swing.JLabel workPhoneLabel =
new
javax.swing.JLabel
(
"Work Phone"
)
;
javax.swing.JTextField workPhoneText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField emailText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField homePhoneText =
new
javax.swing.JTextField
()
;
javax.swing.JLabel faxLabel =
new
javax.swing.JLabel
(
"Fax Number"
)
;
java.awt.Component ordersSeparator = DefaultComponentFactory.getInstance
()
.createSeparator
(
"Orders"
)
;
javax.swing.JComboBox surnameCombo =
new
javax.swing.JComboBox
()
;
java.awt.Component nameSeparator = DefaultComponentFactory.getInstance
()
.createSeparator
(
"Name"
)
;
javax.swing.JLabel suffixLabel =
new
javax.swing.JLabel
(
"Suffix"
)
;
javax.swing.JLabel emailLabel =
new
javax.swing.JLabel
(
"E-mail"
)
;
javax.swing.JLabel homePhoneLabel =
new
javax.swing.JLabel
(
"Home Phone"
)
;
javax.swing.JLabel firstNameLabel =
new
javax.swing.JLabel
(
"First Name"
)
;
javax.swing.JTable orderTableControl =
new
javax.swing.JTable
()
;
javax.swing.JScrollPane orderTable =
new
javax.swing.JScrollPane
(
orderTableControl
)
;
// here is where we load the layout constraints. change the xml filename!!!
LayoutConstraintsManager layoutConstraintsManager =
LayoutConstraintsManager.getLayoutConstraintsManager
(
this
.getClass
()
.getResourceAsStream
(
"yourConstraintFile.xml"
))
;
// here we add the controls to the container. you may
// need to change the name of panel
panel.add
(
suffixCombo,
"suffixCombo"
)
;
panel.add
(
lastNameLabel,
"lastNameLabel"
)
;
panel.add
(
firstNameText,
"firstNameText"
)
;
panel.add
(
lastNameText,
"lastNameText"
)
;
panel.add
(
faxText,
"faxText"
)
;
panel.add
(
contactSeparator,
"contactSeparator"
)
;
panel.add
(
surnameLabel,
"surnameLabel"
)
;
panel.add
(
buttonBar,
"buttonBar"
)
;
panel.add
(
workPhoneLabel,
"workPhoneLabel"
)
;
panel.add
(
workPhoneText,
"workPhoneText"
)
;
panel.add
(
emailText,
"emailText"
)
;
panel.add
(
homePhoneText,
"homePhoneText"
)
;
panel.add
(
faxLabel,
"faxLabel"
)
;
panel.add
(
ordersSeparator,
"ordersSeparator"
)
;
panel.add
(
surnameCombo,
"surnameCombo"
)
;
panel.add
(
nameSeparator,
"nameSeparator"
)
;
panel.add
(
suffixLabel,
"suffixLabel"
)
;
panel.add
(
emailLabel,
"emailLabel"
)
;
panel.add
(
homePhoneLabel,
"homePhoneLabel"
)
;
panel.add
(
firstNameLabel,
"firstNameLabel"
)
;
panel.add
(
orderTable,
"orderTable"
)
;
At the top, you have declarations for the components you created. In the middle you have some code that shows you
how to create a LayoutConstraintsManager from the xml you created, and finally, you have the code you need to add
the components to the container.
So what we need to do is create a Java file called CustomerPanel in the same directory we saved the xml file.
I've created one for you and it's source is included in the distribution. It looks something like this...
package
org.mlc.swing.example;
import
java.awt.*;
import
java.awt.event.*;
import
java.io.*;
import
java.util.*;
import
javax.swing.*;
import
javax.swing.event.*;
import
javax.swing.table.*;
/**
*
@author
Michael Connor
*/
public class
CustomerPanel
extends
javax.swing.JPanel
{
javax.swing.JComboBox suffixCombo =
new
javax.swing.JComboBox
()
;
javax.swing.JLabel lastNameLabel =
new
javax.swing.JLabel
(
"Last Name"
)
;
javax.swing.JTextField firstNameText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField lastNameText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField faxText =
new
javax.swing.JTextField
()
;
java.awt.Component contactSeparator =
com.jgoodies.forms.factories.DefaultComponentFactory.getInstance
()
.createSeparator
(
"Contact Info"
)
;
javax.swing.JLabel surnameLabel =
new
javax.swing.JLabel
(
"Surname"
)
;
javax.swing.JButton okButton =
new
javax.swing.JButton
(
"OK"
)
;
javax.swing.JButton cancelButton =
new
javax.swing.JButton
(
"Cancel"
)
;
java.awt.Component buttonBar =
com.jgoodies.forms.factories.ButtonBarFactory.buildRightAlignedBar
(
new
JButton
[] {
okButton,cancelButton
})
;
javax.swing.JLabel workPhoneLabel =
new
javax.swing.JLabel
(
"Work Phone"
)
;
javax.swing.JTextField workPhoneText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField emailText =
new
javax.swing.JTextField
()
;
javax.swing.JTextField homePhoneText =
new
javax.swing.JTextField
()
;
javax.swing.JLabel faxLabel =
new
javax.swing.JLabel
(
"Fax Number"
)
;
java.awt.Component ordersSeparator =
com.jgoodies.forms.factories.DefaultComponentFactory.getInstance
()
.createSeparator
(
"Orders"
)
;
javax.swing.JComboBox surnameCombo =
new
javax.swing.JComboBox
()
;
java.awt.Component nameSeparator =
com.jgoodies.forms.factories.DefaultComponentFactory.getInstance
()
.createSeparator
(
"Name"
)
;
javax.swing.JLabel suffixLabel =
new
javax.swing.JLabel
(
"Suffix"
)
;
javax.swing.JLabel emailLabel =
new
javax.swing.JLabel
(
"E-mail"
)
;
javax.swing.JLabel homePhoneLabel =
new
javax.swing.JLabel
(
"Home Phone"
)
;
javax.swing.JLabel firstNameLabel =
new
javax.swing.JLabel
(
"First Name"
)
;
javax.swing.JTable orderTableControl =
new
javax.swing.JTable
()
;
javax.swing.JScrollPane orderTable =
new
javax.swing.JScrollPane
(
orderTableControl
)
;
public
CustomerPanel
()
{
super
()
;
org.mlc.swing.layout.LayoutConstraintsManager layoutConstraintsManager =
org.mlc.swing.layout.LayoutConstraintsManager.getLayoutConstraintsManager
(
this
.getClass
()
.getResourceAsStream
(
"customerLayout.xml"
))
;
setBorder
(
com.jgoodies.forms.factories.Borders.DIALOG_BORDER
)
;
LayoutManager panelLayout = layoutConstraintsManager.createLayout
(
"panel"
,
this
)
;
this
.setLayout
(
panelLayout
)
;
this
.add
(
suffixCombo,
"suffixCombo"
)
;
this
.add
(
lastNameLabel,
"lastNameLabel"
)
;
this
.add
(
firstNameText,
"firstNameText"
)
;
this
.add
(
lastNameText,
"lastNameText"
)
;
this
.add
(
faxText,
"faxText"
)
;
this
.add
(
contactSeparator,
"contactSeparator"
)
;
this
.add
(
surnameLabel,
"surnameLabel"
)
;
this
.add
(
buttonBar,
"buttonBar"
)
;
this
.add
(
workPhoneLabel,
"workPhoneLabel"
)
;
this
.add
(
workPhoneText,
"workPhoneText"
)
;
this
.add
(
emailText,
"emailText"
)
;
this
.add
(
homePhoneText,
"homePhoneText"
)
;
this
.add
(
faxLabel,
"faxLabel"
)
;
this
.add
(
ordersSeparator,
"ordersSeparator"
)
;
this
.add
(
surnameCombo,
"surnameCombo"
)
;
this
.add
(
nameSeparator,
"nameSeparator"
)
;
this
.add
(
suffixLabel,
"suffixLabel"
)
;
this
.add
(
emailLabel,
"emailLabel"
)
;
this
.add
(
homePhoneLabel,
"homePhoneLabel"
)
;
this
.add
(
firstNameLabel,
"firstNameLabel"
)
;
this
.add
(
orderTable,
"orderTable"
)
;
// LayoutFrame frame = new LayoutFrame (layoutConstraintsManager);
// frame.setVisible(true);
}
public static
void
main
(
String
[]
args
)
{
UIDefaults defaults = UIManager.getDefaults
()
;
defaults.put
(
"Label.font"
,
new
javax.swing.plaf.FontUIResource
(
new
java.awt.Font
(
"Arial"
, java.awt.Font.PLAIN,
12
)))
;
defaults.put
(
"ComboBox.background"
,
new
javax.swing.plaf.ColorUIResource
(
255
,
255
,
255
))
;
CustomerPanel customerPanel =
new
CustomerPanel
()
;
JFrame frame =
new
JFrame
(
"Edit Customer"
)
;
frame.setDefaultCloseOperation
(
JFrame.EXIT_ON_CLOSE
)
;
frame.getContentPane
()
.setLayout
(
new
BorderLayout
())
;
frame.getContentPane
()
.add
(
customerPanel, BorderLayout.CENTER
)
;
frame.setSize
(
600
,
700
)
;
frame.setVisible
(
true
)
;
}
We had to change a few things to go from the code that we had generated
to what we see here. First of all, in the line where we instantiate a LayoutConstraintsManager,
change the xml filename to the filename that you actually used. Also, there is a main
method and lots of other stuff that we had to create. Another thing we did was change all
of the panel.add() methods to this.add because we are actually just adding the components
to this instead of something we called panel. You will have to import the JGoodies stuff if you
used any of that.
At this point, you are ready to go. I would suggest a few things. First of all,
create a factory method for labels and change them from bold to regular. The
separators then stand out and the labels don't scream out at you. Also, create
a factory method for the JComboBox because it's background color should be white
like the other controls and it should be the same height as the JTextFields.
JTextArea also needs a factory method that gives it a border and sets the work breaks
properly.
More questions answered...
Q: What if I need to add a component that isn't in the tool?
A: No worries, just add some other component that is close in behavior so that it
shows up on the screen and then change the code later.
Q: How do I modify the layout once it's already been built.
A: This is where this tool really excels over IDEs. After you set the layout on your compontent, uncomment the following lines...
//LayoutFrame layoutFrame = new LayoutFrame(layoutConstraintsManager);
//layoutFrame.setVisible(true);
When you want to run the builder again, just uncomment these lines. When you run
your program, the builder will also show up and you can make changes, save the new xml
file, and get code for any components you may have added. I think it would be cool to
create an environment variable that would signal your panels provide a button that
when clicked would pop up the builder. By doing this, you could change the layouts
of your application while it is running.
|