Click here to Skip to main content
Click here to Skip to main content

Ease Swing GUI Creation with HTML Templating

, 24 Nov 2010
Rate this:
Please Sign up or sign in to vote.
Shows how to manage swing components in HTML style

Introduction

Creating GUI in Java is rather difficult. Ordinary code looks like:

JPanel south = new JPanel(new BorderLayout());  
south.add(new JLabel(«login»), BorderLayout.WEST); 
south.add(new JTextField(),BorderLayout.CENTER);
rootPanel.add(south, BorderLayout.SOUTH);

Imagine that you have 15 fields... TableLayout and MigLayout ease layout for many fields, but anyway you have to write Java code.

Background

A lot of programmers (especially in Russia) started with Delphi. The cool thing in Delphi is that you don't have to write GUI code at all. GUI markup is located in a separate file and is linked to the app by IDE.

Almost the same approach is used in Jetbrains IntelliJ Idea. The markup is located in .form file and is converted to the Java code by IDE. Also form's (controller's) fields are injected with appropriate components.

Using the Code

My approach is to put all markup into external file and to construct form in runtime with the help of framework. This approach is like IOC pattern — you do not think about managing of form, you just describe it in a declarative manner and use the results.

So here is an example:

/ru/swing/html/example/LoginForm.html 
<html>
<head>
    <style type="text/css">
        .red {
            color: red;
        }
        .top {
            vertical-align: top;
        }
        #loginForm {
            x-miglayout-column-constraints: [right]related[grow,fill];
        }
        body {
            border: compound (empty 12 12 12 12) (compound (etched) (empty 12 12 12 12));
        }
    </style>
</head>
<body id="rootPanel" style="display: border; width: 400; height:300; 
	border: empty 12 12 12 12">
<table>
    <tr>
        <td rowspan="3" class="top">
            <img src="http://www.codeproject.com/img/login_icon.gif" alt=""/>
        </td>
        <td width="fill">
            <form id="loginForm">
                <p>Login:</p>
                <input id="login" type="text" align="wrap"/>
                <p>Password:</p>
                <input id="password" type="password" align="wrap" />
            </form>
        </td>
    </tr>
    <tr>
        <td>
            <p id="result" class="red"></p>
        </td>
    </tr>
    <tr>
        <td>
            <div style="display: box; x-boxlayout-direction: 
		horizontal; border: empty 0 0 0 6">
                <glue type="horizontal"/>
                <input type="button" text="OK" id="ok" icon="/img/accept.png" />
                <strut type="horizontal" style="width: 6"/>
                <input type="button" text="Cancel" id="cancel" icon="/img/cancel.png"/>
            </div>
        </td>
    </tr>
</table>
</body>
</html>

This is the HTML markup of login form. Every HTML tag will produce some swing component. For example, <body> will produce javax.swing.JPanel.

'display' attribute tells which layout manager will be used in tag's component. 'border' tells that it will be java.awt.BorderLayout.

Every direct child tag is placed in parent's component. Most layout's (BorderLayout, for example) place component using 'align' attribute as constraint. Default constraint for BorderLayout is center, so table will be placed in the center part of JPanel.

Also notice that tag <table> is used. It will produce JPanel, as <body>, but will set TableLayout as layout manager. After that, it will specially handle its children, placing all <td> contents in appropriate cells.

In a similar manner, <form> produces JPanel with MigLayout layout manager.

Now let's bind this form to the controller:

package ru.swing.html.example;
import org.jdom.JDOMException;
import ru.swing.html.Bind;
import ru.swing.html.Binder;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
public class LoginForm {

    @Bind("login")
    private JTextField login;

    @Bind("password")
    private JPasswordField password;

    @Bind("ok")
    private JButton okBtn;

    @Bind("cancel")
    private JButton cancelBtn;

    @Bind("rootPanel")
    private JPanel rootPanel;

    @Bind("result")
    private JLabel result;

    public LoginForm() {

        try {
            Binder.bind(this);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        init();
    }

    public void init() {

        okBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                result.setText("Logging in user "+login.getText());
            }
        });

        cancelBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                result.setText("Cancel clicked");
            }
        });
    }

    public JPanel getRootPanel() {
        return rootPanel;
    }

    public static void main(String[] args) throws JDOMException, IOException {
        LoginForm loginForm = new LoginForm();
        JFrame f = new JFrame("Test");
        f.setSize(400, 200);
        f.getContentPane().add(loginForm.getRootPanel());
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

Form's markup is loaded and binded to controller using:

        try {
            Binder.bind(this);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 

This call searches for file /ru/swing/html/example/LoginForm.html (as class is named ru.swing.html.example.LoginForm), loads it, builds swing components tree and than binds it to controller, so components whose tag's id is equal to the value of @Bind annotation is injected into the field.

The final result looks like:

loginform.jpg

Links

History

  • 24th November, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Penkov Vladimir

Russian Federation Russian Federation
No Biography provided

Comments and Discussions

 
GeneralPresentation layout design Pinmembersonnykwe1-Dec-10 5:56 
GeneralRe: Presentation layout design Pinmemberpapirosko1-Dec-10 20:42 
QuestionBenefits? PinmemberIgor Kushnarev24-Nov-10 22:42 
AnswerRe: Benefits? Pinmemberpapirosko24-Nov-10 23:10 
GeneralRe: Benefits? PinmemberIgor Kushnarev25-Nov-10 0:35 
GeneralRe: Benefits? Pinmemberpapirosko25-Nov-10 0:41 
GeneralRe: Benefits? PinmemberIgor Kushnarev25-Nov-10 1:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 24 Nov 2010
Article Copyright 2010 by Penkov Vladimir
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid