Статьи

Написание собственного CellRenderer с использованием декларативного нового GWT 2.5 UiRenderer

До 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 (документы виджетов ячеек).