До GWT 2.5 написание пользовательского CellRenderer для представления данных определенным образом было очень сложным и очень труднодостижимым.
Весь пользовательский код пользовательского интерфейса должен был быть написан внутри класса Java, который наследуется от класса AbstractCell , с использованием конкатенации строк HTML, что является довольно неуклюжим решением. Если вам нужно что-то более чистое, вы можете использовать класс @Template , но все же его очень сложно писать и поддерживать.
Я всегда говорил, что если бы только Google добавил в GWT возможность определять пользовательский интерфейс настраиваемого CellRenderer с использованием XML, как это было с введением UiBinder, и иметь возможность связывать компоненты пользовательского интерфейса с помощью @UiField и перехватить обработку событий, используя @UiHandler ==> Hooraaahhhh !!!! Эта мечта сбылась с GWT 2.5, и она называется UiRenderer .
В этой статье я покажу некоторые фрагменты кода примера реального использования, чтобы изучить большинство функций, которые были нам предоставлены с UiRender. Сначала давайте опишем пользовательский CellRenderer, который мы реализуем.
Как видно из схемы, средство визуализации элемента ячейки состоит из изображения, текста и двух кнопок: одна для удаления элемента, а другая для открытия всплывающего окна для редактирования данных.
Чтобы создать пользовательский CellRenderer с помощью UiRenderer, нам нужно создать два файла, один из которых содержит декларативный код пользовательского интерфейса XML (подумайте о файлах MyView.ui.xml), а другой содержит связанный вид Java (представьте себе MyView.java). , Два файла должны иметь одинаковое имя.
Декларативный код пользовательского интерфейса MyCellRenderer.ui.xml:
Следует помнить, что разница между UiRenderer и UiBinder заключается в том, что в UiRenderer вы можете использовать только HTML-теги. Все пользовательские компоненты GWT здесь не будут работать. Я надеюсь, что Google добавит эту функцию в будущем выпуске.
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
<ui:with field='name' type='java.lang.String'/>
<ui:with field='image' type='java.lang.String'/>
<ui:style>
.imageWrapper {
float: left;
margin-right: 10px;
}
.imageWrapper img {
width: 64px;
height: 64px;
}
.infoWrapper {
float: left;
}
.infoWrapper div span {
display: inline-block;
marin-right: 5px;
text-decoration: underline;
cursor: pointer;
}
</ui:style>
<div>
<div class="imageWrapper">
<img alt="{name}" src="{image}" />
</div>
<div class="infoWrapper">
<h3><ui:text from="{name}"/></h3>
<div>
<span ui:field="remove">Remove</span>
<span ui:field="update">Update</span>
</div>
</div>
<div style="clear: both;"/>
</div>
</ui:UiBinder>
Пользовательский Java-файл CellRenderer MyCellRenderer.java:
Этот файл будет управлять логикой пользовательского интерфейса, например, передавая отображаемые данные, форматируя данные (преобразование даты, преобразование числа …), обработку событий …
В этом примере у нас есть два события для обработки (щелчок на кнопках «Удалить» и «Обновить»). Благодаря UiRenderer мы можем использовать поля ui: и аннотацию @UiHandler . Чтобы заставить его работать, нужно добавить еще один шаблонный код, например, обработчик события onBrowse (все это хорошо описано во фрагменте кода ниже).
public class MyCellRenderer extends AbstractCell {
// This can be compared to UiBinder --> here where all magic is done
public interface Renderer extends UiRenderer {
void render(SafeHtmlBuilder sb, String name, String image);
void onBrowserEvent(MyCellRenderer o, NativeEvent e, Element p, Person n);
}
private final Renderer uiRenderer;
@Inject
public MyCellRenderer(final Renderer uiRenderer) {
super(BrowserEvents.CLICK);
this.uiRenderer = uiRenderer;
}
@Override
public void onBrowserEvent(Context context, Element parent, Person value, NativeEvent event,
ValueUpdater valueUpdater) {
uiRenderer.onBrowserEvent(this, event, parent, value);
}
@Override
public void render(Context context, Person value, SafeHtmlBuilder safeHtmlBuilder) {
// All data extraction, transformation should be done in here
String name = value.getFirstName() + value.getLastName();
String image = value.getImage();
// We directly the uiRenderer and we pass the HtmlBuilder
uiRenderer.render(safeHtmlBuilder, name, image);
}
@UiHandler({"remove"})
void onRemovePersonClicked(ClickEvent event, Element parent, Person value) {
Window.alert("Do you want to remove : " + value.getFirstName());
}
@UiHandler({"update"})
void onUpdatePersonClicked(ClickEvent event, Element parent, Person value) {
//Maybe use the ActionCell.Delegate to process the action elsewhere...
Window.alert("Do you want to update : " + value.getFirstName());
}
}
Использование нового рендерера в CellList:
Теперь, когда мы закончили написание нашего собственного, сложного и красивого CellRenderer (: D), мы можем использовать его так же, как мы использовали старый устаревший Renderer. Я добавил ниже небольшой фрагмент, чтобы показать вам, как на случай, если вы забудете:
public class MyView extends Composite {
public interface Binder extends UiBinder<Widget, WebCartView> {
}
@UiField(provided = true)
CellList personList;
@Inject
public MyView(final Binder uiBinder, final MyCellRenderer myCellRenderer) {
personList = new CellList(myCellRenderer); // Same way as using old Renderers
.... // Continue what you always do...
}
}
Вот и все для этой статьи, я надеюсь, что это было полезно и поможет вам создавать более удивительные сложные приложения без необходимости писать много сложного кода. PS: этот новый UiRenderer можно использовать с любым виджетом GWT на основе ячеек.
Более подробную информацию можно найти по следующим ссылкам: http://goo.gl/2fePf (официальные документы GWT 2.5 UiRenderer), http://goo.gl/ogR3J (документы виджетов ячеек).
