Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Wicket.docx
Скачиваний:
7
Добавлен:
23.03.2015
Размер:
68.23 Кб
Скачать

Разработка повторно-используемых компонентов

Библиотека Wicket предоставляет иерархию классов, на базе которых можно создавать собственные повторно-используемые компоненты. Каждый компонент должен содержать класс-контроллер, а также может иметь собственный файл разметки и собственные ресурсные файлы. Для компонентов, не нуждающихся в файле разметки, достаточно расширить класс WebComponent и перекрыть метод onComponentTag(). Ниже приводится реализация компонента Spacer, позволяющего создать на странице пространство с высотой и шириной, задаваемой при помощи атрибутов width и height в файле разметки.

public class Spacer extends WebComponent

{

public Spacer(String s)

{

super(s);

setRenderBodyOnly(true);

}

protected void onComponentTag(ComponentTag componentTag)

{

String width = componentTag.getString("width");

String height = componentTag.getString("height");

StringBuffer buffer = new StringBuffer();

buffer.append(MessageFormat.format("<div style=\"width:{0}; height:{1};\">", width, height));

buffer.append(MessageFormat.format("<spacer type=\"block\" width=\"{0}\" height=\"{1}\">", width, height));

buffer.append("</div>");

replaceComponentTagBody(findMarkupStream(), componentTag, buffer.toString());

}

}

Объект componentTag содержит сведения о теге разметки, с которым связан компонент при помощи атрибута wicket:id (это может быть, например, тег вида <div wicket:id=”spacer” width=”10px” height=”1px” />), и позволяет использовать значения его атрибутов width и height при генерации кода, отображающего компонент.

В случае, когда разработчик желает снабдить компонент файлом разметки, в качестве базового класса должен быть использован класс Panel. Для примера создадим компонент, отображающий текущее время. Файл разметки TimePanel.html представлен ниже.

<html xmlns:wicket="http://wicket.sourceforge.net/">

<body>

<wicket:panel>

<div align="center" style="width:80px;height:20px;border:1px solid #000000">

<span wicket:id="timeLabel">00:00:00</span>

</div>

</wicket:panel>

</body>

</html>

Данный файл является полноценной HTML-страницей с тегами <html> и <body>. Однако для отображения компонента будет использована только та часть разметки, которая находится внутри специального тега <wicket:panel>.

Соответствующий класс-контроллер должен использовать стандартный компонент Label, передающий текущее время в динамически формируемый результат.

public class TimePanel extends Panel

{

public TimePanel(String s)

{

super(s);

add(new Label("timeLabel", new SimpleDateFormat("HH:mm:ss").format(new Date())));

}

}

Рассмотрим другую задачу: необходимо создать компонент, который отрисовывает рамку с заголовком вокруг формы на странице AddPersonPage из первого примера статьи. Для решения подобных задач лучше всего использовать компоненты-контейнеры. Создадим класс FormBorder, расширяющий класс Border из библиотеки Wicket.

public class FormBorder extends Border

{

public FormBorder(String s, String title)

{

super(s);

add(new Label("formTitle", title));

}

}

Далее, необходимо создать файл с разметкой FormBorder.html.

<html xmlns:wicket="http://wicket.sourceforge.net/">

<body>

<wicket:border>

<div align="center" style="border:1px solid #000000">

<span wicket:id="formTitle" style="font-weight: bold">Заголовок формы</span>

<wicket:body/>

</div>

</wicket:border>

</body>

</html>

Специальный тег <wicket:border> по смыслу аналогичен тегу <wicket:panel>. Он определяет ту часть HTML-разметки, которая будет использоваться для отображения компонента, остальные теги будут игнорированы. Тег <wicket:body/> указывает место, которое займет код, сгенерированный для отображения компонентов, вложенных в контейнер. Чтобы подключить компонент, необходимо изменить файл AddPersonPage.html таким образом, чтобы форма оказалась внутри блока с меткой wicket:id="border".

<html xmlns:wicket="http://wicket.sourceforge.net/">

<head>

<title>Сохранение персональных данных</title>

</head>

<body>

<div wicket:id="border">

<form wicket:id="form">

<span wicket:id="feedback"/>

<div>Имя: <input wicket:id="name" type="text" /></div>

<div>Адрес: <input wicket:id="email" type="text" /></div>

<input type="submit" name="submit" value="Сохранить"/>

</form>

</div>

</body>

</html>

Необходимо также изменить конструктор класса AddPersonPage; в нем должен создаваться экземпляр класса FormBorder.

public class AddPersonPage extends WebPage

{

public AddPersonPage()

{

FormBorder border = new FormBorder("border", "Введите данные");

border.setRenderBodyOnly(true);

border.add(new PersonForm("form"));

add(border);

}

}

Обратите внимание, что вложенность компонентов в точности соответствует вложенности тегов в файле разметки. Подключение компонента закончено. Если запустить приложение, то для страницы AddPersonPage будет сгенерирован примерно следующий HTML-код:

<html>

<head>

<title>Сохранение персональных данных</title>

</head>

<body>

<div align="center" style="border:1px solid #000000">

<span style="font-weight: bold">Введите данные</span>

<form action="/wdemo/app?path=0:border:form&interface=IFormSubmitListener" method="post">

<span></span>

<div>Имя: <input value="" type="text" name="name"/></div>

<div>Адрес: <input value="" type="text" name="email"/></div>

<input type="submit" name="submit" value="Сохранить"/>

</form>

</div>

</body>

</html>

Использование компонентно-ориентированного подхода открывает перед разработчиками грандиозные возможности для организации повторного использования кода. Очевидно, что, например, компонент FormBorder может быть использован при создании других Web-форм приложения. При этом изменения в файле FormBorder.html автоматически приведут к изменению в отображении всех страниц, в которых задействован данный компонент.