Archive

Posts Tagged ‘GUI’

Useful Swing libraries for look and feel, layout and data binding

February 2nd, 2009

Recently I’ve been looking into Java Swing development. Last time I touched this was probably 3 years ago, during an undergraduate course. We made some basic GUIs to create family trees and lines pointing to children, parents, siblings etc.

Now, Swing has evolved quite alot since then. Especially with the advent of new libraries to make development easier. I remember some things to be issues with vanilla Swing. Namely, the look and feel, the overhead and complexity of creating layout, and updating the domain model in a way that didn’t break the MVC pattern.

Model-View-Controller (MVC) is an architecture pattern to seperate business logic (Model) from GUI elements (View). In addition, keeping the business logic seperated from the domain model, but it’s not the main point. The Controller acts as a mediator between the user’s actions and the business logic. Typically in a Swing application, it will react to certain events, process and check user input and then pass it down to the business logic.

When looking around for libraries, I had some criterias. There had to be good and easily accessible documentation and less overall overhead than vanilla Swing.

First I tried the GUI builder in Netbeans 6.0 (formerly Project Matisse), which is a very powerful tool for creating Swing desktop applications with little coding overhead. It has a simple drag and drop visual interface. In addition it can bind domain objects to some fields with the beansbinding library. However I found it to be cumbersome to use, customizing code took too long time and anyone that did not use the GUI builder would have had a hard time understanding the messy generated code.

I found three libraries that solved my needs for customizable look and feel, easy layout and data binding. Below I will briefly outline what each library offers and give a very simple example.

Substance

Substance aims to create a fast, solid and extensible library for visually appealing Swing applications. There are alot of options to tweak around with, but the most basic use is given below:

UIManager.setLookAndFeel(new org.jvnet.substance.skin.SubstanceMagmaLookAndFeel());

This sets the look and feel, Magma.

Jgoodies Forms

Jgoodies Forms facilitates the layout process and makes it better.  It has powerful features for creating precise, flexible and more readable layout code.

private JComponent buildPanel() {
    initComponents();
    FormLayout layout = new FormLayout("$lcgap,p,$lcgap,150dlu,$lcgap",
    "$lgap,p,$lgap,p,$lgap,p,$lgap");
    PanelBuilder builder = new PanelBuilder(layout);
    CellConstraints cc = new CellConstraints();

    builder.addSeparator("BookRegistration", cc.xyw(2, 2, 4));
    builder.addLabel("Name", cc.xy(2, 4));
    builder.add(nameField, cc.xy(4, 4));
    builder.addLabel("Author", cc.xy(2, 6));
    builder.add(authorField, cc.xy(4, 6));

    return builder.getPanel();
}

Which will produce something like this (inside a JFrame):

bookapp_form

Intitially the FormLayout might seem like some mumbo-jumbo. But when you get to know it, it starts to make sense. It is very powerful and you can create almost any layout with it. The PanelBuilder has alot of helpers for boilerplate code, such as adding labels and seperators that goes with other typical JComponents.

Jgoodies Binding

Jgoodies Binding main goals are to stream-line the development process for data-binding and assist in seperating the presentation layer from the domain layer.

public class Book extends Model {

    public static final String PROPERTY_NAME = "name";
    public static final String PROPERTY_AUTHOR = "author";
    private String name;
    private String author;

    public Book() {
    }

    public String getAuthor() {
    return author;
    }

    public void setAuthor(String author) {
        String oldAuthor = this.author;
        firePropertyChange(PROPERTY_AUTHOR, oldAuthor, author);
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        String oldName = this.name;
        firePropertyChange(PROPERTY_NAME, oldName, name);
        this.name = name;
    }
}

/**
* BookApplication class
*/


private void initComponents() {
    nameField = BasicComponentFactory.createTextField(presentationModel.getModel(Book.PROPERTY_NAME),false);
    authorField = BasicComponentFactory.createTextField(presentationModel.getModel(Book.PROPERTY_AUTHOR),false);
    nameLabel = BasicComponentFactory.createLabel(presentationModel.getModel(Book.PROPERTY_NAME));
}

Notice that the Book-class extends the binding-library Model. It is an abstract class to make it easier to change bean properties. Whenever a bean property is set, it fires a property change to notify any listeners that the bean property has changed. The BasicComponentFactory can automagically create various Swing components to listen on ValueModels.

Putting it all together

When all is put together, it looks something like this:

bookapp_all

Here, the name in the Book object is bound to the name JTextField (by referring to PROPERTY_NAME). The JLabel at the bottom listens on any changes and updates itself accordingly.

The many GUI builders out there opts for rapid GUI layout and construction. But in my opinion they suffer from clunky, uncustomizable and hard-to-read generated code. It also makes the project highly dependent on the GUI builder in question. Which is why I have presented three handy libraries for easy, maintainable and cleaner Swing GUI development.

Java, Programming , , , , , , , , , , , , ,