Skip to end of metadata
Go to start of metadata

Introduction

SDL/Swing is a very simple declarative framework for building rich cross platform desktop and Web Start applications. Our company has been involved in writing many, many desktop applications in Swing, Flex, WinForms, Silverlight, WPF and other frameworks. Its always seemed like more work than it should be. SDL/Swing is the product of our frustration with other frameworks. Our goal is to build the simplest, most developer friendly desktop application framework on the planet.

SDL/Swing applications use the Simple Declarative Language to define screens in a terse, human readable definition file. Controllers can be written in Java, or any other JVM targeted language.

Why Another Java Rich Client Framework

The Eclipse and NetBeans RCP platforms are very powerful but they are not declarative and have a steep learning curve. JSR-296, the Swing Application Framework, was intended to provide a simple Swing framework but there has been little activity on this JSR in recent months and it too lacks a declarative component.

JavaFX has some nice capabilities including a declarative scripting language, a rich effects engine, data-binding, mutation triggers and declarative animation. I like the fact it doesn't use giant ugly XML files for UI definitions, but it is a relatively large framework that introduces a new, rather involved language. SDL/Swing definitions are much more concise, the framework is tiny (283k) and its very simple to learn.

Getting Started

To get started simply download the SDL Pad sample application, double click to launch, type "Hello World" in the text pane on the right, and click "Refresh". You should see the results below:

Easy, eh? SDL/Swing interprets string literals (text in quotes) as a label, menu, menu item, list item, or combobox item depending on context. Here is an example of a menu definition:

menus {
    "File" {
        "Open" do="open" // calls "open()" in the controller
        "---"
        "Exit" do="exit"
    }
}

The strings in the menubar are automatically interpreted as menus and menu items. The "do" attributes call an action method in the controller associated with the form containing this menubar. SDL attributes are converted to bean properties. This allows you to easily configure components like so:

button "Hello" opaque=false icon="waving_hand.png" foreground="red"

The "button" tag below is mapped to javax.swing.JButton in a bindings property file. There are default bindings for common components. See the Component Tags area for a complete list of components. Application developers can add their own bindings or override default bindings like so:

button=com.ooi.swing.RoundButton

Container components take a "layout" attribute that maps to one of about a dozen layout managers ranging from simple vertical and horizontal stacking layouts to complex table layouts. Here is a browser bar (the area with the URL and buttons at the top of your browser) using a vertical layout:

hpane border=2 { // creates an empty border with all sides having a thickness of 2
    "URL: "
    text loc="fill"
    spacer 5
    button "<"
    button ">"
}

Result:

We can build this layout with a single API call referencing the file containing this definition:

JComponent browser = UI.build("comps/browser.sdl");

Examples of more complex layouts including table and spring can be seen here:

The UI in this example was constructed entirely with SDL/Swing. It would require approximately 5 times the number of lines to create the same UI in Java procedurally and the results would be much harder to read.

The formpane component allows you to easily define and interact with forms:

The SDL / Pad example itself has a very simple screen definition:

frame {
    menus {
        "File" {
            "Exit" do="exit"
        }
        "Help" {
            "About" do="about"
        }
    }
    
    form ID="App" preferredSize="700,500" {
        pane layout="horizontal" border=5 loc="north" backgroundPaint="gradient:soft_gray" {
            button "Refresh" do="refresh" icon="refresh"
            glass loc="fill"
            `Type SDL/Swing code on the right and hit "Refresh"` border="0,0,0,10"
        }
        split layout="horizontal" resizeWeight=.5 {
            split layout="vertical" resizeWeight=.5 {
                pane ID="user_pane"
                pane ID="console_pane"
            }
            scroll {
                textarea ID="sdl_text" tabSize=4 font="code"
            }
        }
    }
}

The controller code is equally simple:

public class AppController extends FormController {
        
    private static Interpreter interp;
    
    public void initialize() {
        Pane pane = (Pane)form.getChildByID("console_pane");
        JConsole console = new JConsole();
        interp = new Interpreter(console);
        pane.add(console);
    }
    
    public void shown() {
        try {
            interp.eval("import com.ooi.io.*");
            interp.set("form", form);
        } catch (EvalError e) { /* won't happen */ }
        
        new Thread(interp).start();
    }
    
    public void refresh() {
        Pane pane = (Pane)form.getChildByID("user_pane");
        pane.removeAll();
        String sdl = (String)getValue("sdl_text");
        try {
            pane.add(new ComponentBuilder().build(new StringReader(sdl)));
            pane.validate();
            pane.repaint();
        } catch (UIBindingException e) {
            this.showError("Binding error in user SDL/Swing definition.", e);
        } catch (IOException e) {
            // Will never happen
        } catch (SDLParseException e) {
            this.showError("Malformed SDL in user SDL/Swing definition.", e);           
        }
    }
    
    // Controller Methods ////////////////////////////////////////
    
    public void exit() {
        System.exit(0);
    }
    
    public void about() {
        this.showMessage("Ooi Pad 1.0.0 by Ikayzo - http://ikayzo.com");
    }
    
    /////
    
    public static void main(String[] args) throws Exception {
        UI.startApplication("Ooi Pad", "app");
    }
}

UI.startApplication in main(String[]) above takes two parameters. The first is the name of the application, which is also set as the title on the main frame. The second is the filename, sans the .sdl extension, of the component definition file found in the resources/components directory.

The SDL and the Java code shown above constitute the entire Ooi Pad application. The best way to learn SDL/Swing is to practice creating simple UIs with Ooi Pad. Once you are comfortable creating UIs, crack open the Ooi pad application source and see how the parts work.

Forms and Controllers
All controllers are placed in a package specified in resource/ui_global.properties. For OoiPad the contents of this file are:

Controllers use (package name).(form ID)Controller as a naming convention. In the example above, the form having the ID "App" is connected to the controller com.ooi.swing.ooipad.AppController. SDL/Swing automatically wires the controller to the form using this naming association. Controllers have two life cycle events - initialize() which is called after the form is configured by its SDL definition, and shown() which is called when the form is made visible.

I'll leave you with an example of a browser defined in SDL/Swing:

form ID="Browser" {
    hpane loc="north" border="2,2,2,2" \
            preferredHeight=24 {

        "URL" border="0,5,0,3" font="strong"
        button "Clear" do="clearURL" focusPainted=false
        text "http://www.cnn.com" constraint="fill" do="browseTo" minimumSize="5,5"
        button "Go" background="dark_green" do="browseTo"
        spacer 7
        button icon="recycle" do="refresh" style="toolbar"
        spacer 5
        button icon="navigate_left" do="back" style="toolbar"
        button icon="navigate_right" do="forward" style="toolbar"
    }

    browser URL="http://cnn.com" ID="browser"
}

Note: This example uses an excellent Swing friendly browser component provided by JadeLiquid.

SDL/Swing has a number of other interesting features including declarative CSS-like styles and integration with the SwingX painters framework. We will include more detailed documentation about these features in the near future.

Learn More

New! We just set up a Google Group to facilitate conversation about the framework. The mailing list is sdlswing@googlegroups.com.

Recently Updated

 
Navigate space
Labels: