Разметка swing форм с помощью html

29 апреля 2011 г.

Создание swing форм с помощью кода в JAVA — довольно трудоемкое занятие. Обычно код по созданию и размещению форм выглядит примерно так:

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

В данном примере в панель добавляется надпись и текстовое поле. Теперь представьте, что полей — 15 штук. Для упрощения размещения компонентов были разработаны менеджеры компоновки TableLayout и
MigLayout, но даже используя их приходится писать java код.

Давайте сравним это с Delphi (знакомым большинству программистов). В Delphi обычно заботиться о коде разметки не надо вообще. Сама разметка хранится в отдельном файле и линкуется IDE.

Похожий подход используется в Jetbrains IDEA. Разметка хранится в файле .form и преобразуется в java код самой средой. Также есть возможность присваивать полям формы (класса контроллера) значения созданных на форме компонентов.

Я разрабатываю библиотеку, позволяющую хранить код разметки в отдельном файле и динамически подгружать его.

Рассмотрим пример:

/ru/swing/html/example/LoginForm.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>

Это html код, описывающий форму. Практически каждый html тег преобразуется в соответствующий swing компонент. Например, преобразуется в javax.swing.JPanel.

Значение атрибута display указывает какой менеджер компоновки следует использовать для компонента. Значение border соответствует java.awt.BorderLayout.

Каждый компонент дочернего тега размещается в родительском компоненте. Большинство менеджеров компоновки (в том числе и BorderLayout) размещают дочерний компонент, используя значение атрибута align дочернего компонента в качестве ограничения (см. LayoutManager.add()). Значение ограничения по умолчанию для BorderLayout - это center, т.о. таблица будет размещена в центре панели.

Также следует обратить внимание на использование тега . Он преобразуется в панель с менеджером компоновки TableLayout. После создания он особым образом обрабатывает свои дочерние теги, размещая содержимое тегов в нужных ячейках.

Аналогичным образом тег преобразуется в панель с MigLayout в качестве менеджера компоновки.

Теперь свяжем форму с контроллером:

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);
    }
}

Разметка формы загружается и подключается к контроллеру с помощью данного вызова:
Binder.bind(this);

В момент вызова происходит поиск файла /ru/swing/html/example/LoginForm.html (так как класс называется ru.swing.html.example.LoginForm), из файла загружается разметка, преобразуется в дерево swing компонент и присоединяется к контроллеру. Присоединение происходит с помощью аннотации @Bind: ее значение - это идентификатор компонента.

Итоговый результат:
Форма входа

Ссылки:

Сайт проекта: http://code.google.com/p/swinghtmltemplate/
Документация: http://code.google.com/p/swinghtmltemplate/wiki/Documentation_0_3

Теги: рубрика Сайтостроение
 
©  2009 – 2024 «Korzh.net»