Collin Fagan is a Sr. Software Engineer at NAVTEQ working on next generation map building software. He holds a BS in Computer Science from the Rochester Institute of Technology. Collin has worked in the Map, Medical, Produce Warehousing and Telecommunications industries on a wide assortment of projects ranging from customized Linux thin clients to highly concurrent telecommunications control systems. Collin has posted 13 posts at DZone. View Full User Profile

Layout Prototyping Part 1: XML

11.17.2008
| 12964 views |
  • submit to reddit
GUI Layout is hard, but is it harder then it should be in Java? Can we do something to better the situation? My next few blogs will be about prototyping different approaches in an attempt to find something better. For my first article I'm going to attempt to apply XML to the GUI layout. The goal is to approximate some of the features of MXML from Flex. In a previous article I compared layout logic in Flex/Flex Builder to Java. I found only one layout manager that had no Java equivalent. I wrote CoordinateLayout to mimic absolute layout from Flex. Here is a very basic example of it's usage.
public class CoordinateLayoutDemo extends JPanel {

public CoordinateLayoutDemo() {
setLayout(new CoordinateLayout());

add(new JLabel("Last Name:"), "x=10, y=10");
add(new JTextField(), "x=87, y=8, width=223");

add(new JLabel("First Name:"), "x=318, y=10");
add(new JTextField(), "x=395, y=10, width=207");

add(new JLabel("Phone:"), "x=10, y=36");
add(new JTextField(), "x=87, y=34, width=223");

add(new JLabel("Email:"), "x=318, y=36");
add(new JTextField(), "x=395, y=34, width=207");

add(new JLabel("Address:"), "x=10, y=62");
add(new JTextField(), "x=87, y=60, width=515");

add(new JLabel("City:"), "x=10, y=88");
add(new JTextField(), "x=87, y=86, width=223");

add(new JLabel("State"), "x=318, y=88");
add(new JTextField(), "x=395, y=86, width=207");
}
}


This lets one layout a screen pixel by pixel. It also has an "anchor mode" that allows one to determine how a component will resize by specifying the location of an anchor on one the four sides.
public class CoordinateLayoutDemo2 extends JPanel {
/**
*
*/
private static final long serialVersionUID = 5744676397576694341L;

public CoordinateLayoutDemo2() {
setLayout(new CoordinateLayout());

add(new JScrollPane(new JTextArea()),
"left=35, top=40, right=10, bottom=10");
add(new JSlider(SwingConstants.VERTICAL), "bottom=10, left=10, top=40");
add(new JComboBox(), "right=287, left=35, top=10");
add(new JButton("Button"), "right=10, top=10");
}
}
This code results in the following screen.


The only other thing I need is XML bindings and I have functionality similar to absolute layout. XMLBeans to the Rescue. Without going into too much detail, XMLbeans takes an XSD (XML Schema Definition) and creates java classes that can parse XML that conforms to that schema. Here is a tiny schema that represents CoordinateLayout.
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="CoordinateLayout">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="item">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="x" type="xs:int" />
<xs:attribute name="y" type="xs:int" />
<xs:attribute name="width" type="xs:string" />
<xs:attribute name="height" type="xs:string" />
<xs:attribute name="top" type="xs:int" />
<xs:attribute name="left" type="xs:int" />
<xs:attribute name="bottom" type="xs:int" />
<xs:attribute name="right" type="xs:int" />
<xs:attribute name="vcenter" type="xs:int" />
<xs:attribute name="hcenter" type="xs:int" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
If I run this XSD through the XMLBeans schema compiler (scomp) I get a jar with classes that parse this schema. Now with a little drudgery to move the values from the schema generated objects to my layout I am able to represent my UI as an XML file. Here is an XML file that conforms the XSD and arranges the components the same way as the first example.
<?xml version="1.0" encoding="UTF-8"?>
<CoordinateLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item name="lastNameLabel" x="10" y="10" />
<item name="lastName" x="87" y="8" width="223" />

<item name="firstNameLabel" x="318" y="10" />
<item name="firstName" x="395" y="10" width="207" />

<item name="phoneLabel" x="10" y="36" />
<item name="phone" x="87" y="34" width="223" />

<item name="emailLabel" x="318" y="36" />
<item name="email" x="395" y="34" width="207" />

<item name="addressLabel" x="10" y="62" />
<item name="address" x="87" y="60" width="515"/>

<item name="cityLabel" x="10" y="88" />
<item name="city" x="87" y="86" width="223"/>

<item name="stateLabel" x="318" y="88"/>
<item name="state" x="395" y="86" width="207"/>
</CoordinateLayout>
Published at DZone with permission of its author, Collin Fagan.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Mikael Grev replied on Mon, 2008/11/17 - 4:53am

Edit: Removed. I did not see that the article consisted of several pages...

:-)

Cheers,
Mikael

Jacek Furmankiewicz replied on Mon, 2008/11/17 - 8:10am

Let me introduce you to my little project called the Java SwingBuilder...instead of prototyping the UI, you actually create it (using MigLayout under the hood):

http://code.google.com/p/javabuilders/wiki/JavaSwingBuilder

 in particular this section:

http://code.google.com/p/javabuilders/wiki/LayoutDSL

In particular see more complex example at the bottom.

 P.S. XML blows. It's time you looked at YAML :-)

Collin Fagan replied on Mon, 2008/11/17 - 9:58am in response to: Jacek Furmankiewicz

Hi Jacek,

What I mean by prototyping is "prototyping new ways to do layout". This time I'm using XML. My next prototype will use something else, a scripting language, annotations, closures, something, anything until I find a compelling solution. I've taken a look at SwingBuilder and it looks really cool, but I'm going to keep exploring. Even if in the end I just end up proving that SwingBuilder is the way to go.

Jacek Furmankiewicz replied on Mon, 2008/11/17 - 10:06am in response to: Collin Fagan

Thanks for the clarification.

To be frank with you I find that all Java Swing/SWT layout management problems are solved by MigLayout, especially if you pass "debug" into its constructor (which paints all the container edges on the screen so you can see them), e.g.

setLayoutManager(new MigLayout("wrap 3, debug"));

With MigLayout being able to define ALL the layouts for any control in one and only line of code, any other approach to me is secondary.

The SwingBuilder DSL is just an attempt to make it even easier by providing something akin to a GUI builder (think of it as Matisse for Notepad) to make it more visual.

But in my humble opinion, any layout attempt that does not begin with MigLayout is the wrong approach from the get-go. And I speak of that as a MigLayout user (as I did not write it, it's Mikael Grev's brainchild).

Layout management in Java is only hard if you haven't yet discovered MigLayout. Simple :-)
In my team no one even thinks of doing a new Swing or SWT panel without using MigLayout as the main layout manager.

 

 

Alexandre Navarro replied on Mon, 2008/11/17 - 6:14pm

I totally agree with Jacek. A view in yaml (a JSON superset) and miglayout is so easy to understand and concise eventhough you don't know anything in Swing  (compare to a XML with another layout).

Miglayout and Java Swing Builder rock !!!

Alexandre

Jean-Francois P... replied on Mon, 2008/11/17 - 11:25pm

Personally, I don't buy all this "do it in XML instead of Java", this reminds me of the early times of Spring (before annotations support), which I always refused to use because of that. I wonder if using XML here really simplifies the work of developers who design a GUI: they still need to "code, try and fix" their code (be it Java or XML) until they get what they want. XML simply removes lots of compile-time checks that you can have with Java code.

Did you take a look at DesignGridLayout? With it, you really don't need any XML at all (actually, I'm sure that using XML would make it less easy to use). It makes irrelevant the "code, try and test" iterative GUI design, thanks to its API which makes it clear what the actual layout will look like.

My 2 cents (and shameless self-promotion;-))

Serge Bureau replied on Tue, 2008/11/18 - 8:43am in response to: Collin Fagan

Do you really consider XML as any kind of simplification ???

 

I think the Groovy SwingBuilder is the best try so far.

Collin Fagan replied on Tue, 2008/11/18 - 10:20am

Do you really consider XML as any kind of simplification ???

 

Honestly I wasn't sure how it sure how it would turn out. Flex and Pivot use XML for a lot more then just layout and I wanted to see if there would be any benefit to an XML based system. I agree that it does suffer from the general failing of XML, it's too verbose. It actually made GidBag easier. But as I said in the article, that's not hard. XML/XDS/XMLBeans does have a lot of power, it just might not be right for layout. I like the general idea of decoupling the layout constraints from the component creation code. It seems like that would be a good way make the kinds of subtle adjustments necessary for internationalization or branding. I'll try something else in my next prototype. After I read up on all these projects. :)

Serge Bureau replied on Wed, 2008/11/19 - 9:52am in response to: Collin Fagan

[quote=cfagan]

Do you really consider XML as any kind of simplification ???

 

Honestly I wasn't sure how it sure how it would turn out. Flex and Pivot use XML for a lot more then just layout and I wanted to see if there would be any benefit to an XML based system. I agree that it does suffer from the general failing of XML, it's too verbose. It actually made GidBag easier. But as I said in the article, that's not hard. XML/XDS/XMLBeans does have a lot of power, it just might not be right for layout. I like the general idea of decoupling the layout constraints from the component creation code. It seems like that would be a good way make the kinds of subtle adjustments necessary for internationalization or branding. I'll try something else in my next prototype. After I read up on all these projects. :)[/quote]

Too verbose is the least of it's problem.

You cannot verify what the XML does, code can be compiled and verified, you cannot inhirit from XML, but you do from code.

So to me using XML for this type of problem is the wrong use of it.

Heng Yuan replied on Fri, 2008/11/28 - 8:34am

I guess that you have never heard of CookSwing, which does GridBagLayout, JGoodies Forms layout, SpringLayout etc all in XML.

http://cookxml.yuanheng.org/cookswing/

There are far more profound problems than merely dealing with gridbag layout. Other issues include how swing components are generated and used. For instance, date, formatted fields, listener hook up etc.

Serge Bureau replied on Fri, 2008/11/28 - 12:53pm in response to: Heng Yuan

[quote=coconut]

I guess that you have never heard of CookSwing, which does GridBagLayout, JGoodies Forms layout, SpringLayout etc all in XML.

http://cookxml.yuanheng.org/cookswing/

There are far more profound problems than merely dealing with gridbag layout. Other issues include how swing components are generated and used. For instance, date, formatted fields, listener hook up etc.

[/quote]

Please expalin what you see as an advantage there ?

You end up with an XML mess that can only be checked at run time, very litle testability, etc ...

It is a big step backward.

Something like SwingBuilder in Groovy is much more advanced.

Heng Yuan replied on Sat, 2008/11/29 - 6:12am in response to: Serge Bureau

There are many advantages:

1. complete layout support for all Swing and JGoodies Forms layout all in XML, which are in hierarchical format.  The example in this article only deals with a single layer Gridbaglayout, which is really simple.  More complex layouts include working in conjunction with tabbed pane, card layout, splitpane etc.  Other things include "labelfor" for keyboard shortcuts.

2. i18n support using resourcebundle (specify in xml)

3. l10n support by switching to different XML template (completely different layout, font, text etc)

4. template support.  Check JGoodies presentation on uniform layouts.  The common layouts of Okay Cancel buttons can be included as templates.

5. specify complex settings for components inside xml.  There are many examples in CookSwingDemo (where xml is loaded and GUI generated on the fly).  For example, combo box items, choice selections, spinbox range, steps, etc.  Some components take a vector of strings which in turn have resourcebundle names.  Loading up icons etc.   If you want true separation of presentation layer with business logic, you need to have those.

CookSwing generally can take care of them right within XML in more intuitive ways (at least to me).  Usually, a good XUL motor would try to minimize going back-n-forth between Java and XML code.

6. Switching components on the fly.  In one application, I had the default JTextField component for <textfield>, which is quite mundane.  The art person asked if it is possible to add right click and shows the cut/paste/undo/redo menu.  I wrote a subclass of JTextField that has such capability and replace the definition of <textfield> with this class (only takes a single line statement), instantly, all text fields now have this updated feature.

For another in house application, I had <dialog> for  child dialog windows.  Later on, we switched to JIDE docking framework, I wrote a bridge class that replaces the original component used by <dialog>.  Instantly, we switched all of our dialogs to docking windows.  We actually tested our application using several different frameworks with this approach without drastically changing the code.

7. Exception handling.  CookSwing has several choices of handling exceptions.  One is trying to ignore them and do as much rendering as possible (which is reasonable, for example, some text / icons might be missing, but you will add them in later) but with traces.  One gives you immediate error to run with test, etc.

The list can go on and on.

As for testing, for serious GUI applications, you cannot test the GUI merely using a script.  You will have to check behaviors of buttons etc.  These are far more complex to test.  Laying out Swing components are actually the easiest and least work for Swing.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.