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.
|