Skip to main content

An idea for a builder thingymajig

Posted by evanx on July 24, 2008 at 2:17 PM PDT

Let's say we have a following class with Swing components.

public class PersonEditor {
    JPanel mainPanel;
    JTextField firstname;
    JTextField surname;
    JFormattedTextField dateOfBirth;
    ...
    public PersonEditor() {
        GSwingBuilder.build(this); // inject the above components
    }
    ...   
}

Let's create the following companion resource file, named PersonEditor.def.

    JPanel mainPanel;
    JTextField firstname;
    JTextField surname;
    JFormattedTextField dateOfBirth;
    ...   
    mainPanel = panel();
        tabbedPane();
            panel();             
                firstnameLabel = label(); gbc(0, 0);
                firstname; gbc(gridx = 1);
                surnameLabel = label(); gbc(0, 1);
                surname; gbc(1, 1);
                ...
                applyChanges = button();
            panel();
            ...

where firstly, we have cut and pasted the component declarations from PersonEditor.java.
lockstart_session.png
But then we present a hierarchy of objects that are to be constructed using various methods eg. panel(), tabbedPane(), label(). Also, declared components are referenced by name eg. firstname, surname.

So the above resource file is like an extension script used in conjunction with the following Java builder that we implement.

 
public class GSwingBuilder extends GBuilder {

    JPanel panel() {
        return new JPanel(new GridBagLayout());
    }

    GridBagConstraints gbc(int gridx, int gridy) {
        ...
    }       

    JLabel label() {
        return new JLabel();
    }
    ...
    JTextField createTextField() {
        return new JTextField();              
    }

    JFormattedTextField createFormattedTextField() {
        return new JFormattedTextField();
    }   
    ...
    void add(Container container, Component component, GridBagConstraints gbc) {
        container.add(component, gbc);
    }
}

The build() method in the GBuilder superclass will parse the resource file script in order construct the objects (using reflection to find and invoke methods in the above builder subclass), and importantly, invoke add() to assemble the components. Finally it injects the constructed components into the declared fields of our PersonEditor object.

jabber_protocol_64.png
This offers the following niceties. Firstly and most importantly, we can use indentation to express our hierarchy most conveniently. Secondly, constituent components can be either unnamed eg. panels and panes, or named ie. for referencing and injection of input components into our UI controller class, and also of course for resource injection into these components ie. of translatable labels, customisable colors, fonts, et cetera.

So we create a Java builder class where we can define whatever methods we want, and the script file references these methods, together with fields in the target class, in order to construct, assemble and inject objects into the target.

Isn't this quite flexible, given that we couple Java code with our script in this way, such that builder code extends the script, and the script extends the target code?!

Next we might consider how this can be applied to HTML component trees e.g. where we create a GBuilder subclass called GHtmlBuilder, define a component tree using a script, and expose the components we want to access via the Java target class, for the purpose of creating HTML output using Java code (for its programmability) together with a complementary builder script.

Related Topics >>