Поиск по этому блогу

понедельник, 26 мая 2014 г.

GWT. How to create and use custom widget

Как в GWT создать собственный виджет и использовать его после этого как при помощи Java кода так и при помощи uiBinder. Прежде всего создадим два файла - java класс для нашего виджета и xml-файл, в котором опишем структуру нашего виджета.

ModalDialogWidget.java
ModalDialogWidget.ui.xml

Наш виджет будет наследоваться от класса Composite.
public class ModalDialogWidget extends Composite

Внутри нашего виджета создадим интерфейс, который будет расширять UiBinder. После этого создадим статическую переменную типа созданного интерфейса (переменная uiBinder). Она нам понадобится в дальнейшем для связывания xml описания файла с Java кодом.
interface ModalDialogWidgetUiBinder extends
  UiBinder<Widget, ModalDialogWidget> {
}
 
private static ModalDialogWidgetUiBinder uiBinder = GWT
  .create(ModalDialogWidgetUiBinder.class);


XML описание виджета


Теперь опишем сам виджет в xml-файле.
В моем видждете я выделил три основных контейнера
1. header
2. body
3. footer
И добавил к этим контейнерам атрибут ui:field, чтобы использовать потом в Java коде.
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" 
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:FlowPanel styleName='modal fade blue' ui:field="dialog">
  <g:FlowPanel styleName='modal-dialog medium'>
    <g:FlowPanel styleName='modal-content'>
      <g:FlowPanel styleName='modal-header' ui:field="header">
      </g:FlowPanel>
      <g:FlowPanel styleName='modal-body' ui:field="body">
      </g:FlowPanel>
      <g:FlowPanel styleName='modal-footer' ui:field="footer">
        <g:Button ui:field="cancelButton" 
          styleName='btn btn-default btn-cancel'>CANCEL
        </g:Button>
        <g:Button ui:field="okButton" 
          styleName='btn btn-primary btn-save'>OK
        </g:Button>
      </g:FlowPanel>
    </g:FlowPanel>
  </g:FlowPanel>
</g:FlowPanel>
</ui:UiBinder>

Java класс для виджета


Чтобы наш виджет можно было подключать через uiBinder добавим к конструктору аннотацию @UiConstructor. В конструкторе также проинициализируем виджет при помощи uiBinder, для этого вызовем метод initWidget(uiBinder.createAndBindUi(this)).  Для того чтобы добавлять в контейнеры нашего виджета дочерние элементы необходимо в Java код добавить следующие методы, обязательно с аннотацией @UiChild и параметром tagname с указанием имени контейнера, в который будет добавляться дочерний виджет.

Если мы напишем вот так
@UiChild(tagname = "body")
    public void addBody(Widget widget) {
      if (body == null) {
        body.clear();
      } else {
        body.add(widget);
      }
    }

то потом сможем делать вот так
<da:body>
      <g:HTMLPanel>
        <div style="width:300px; height:300px">
          <da:FilteredListDropdownWidget 
            ui:field="filteredList"> 
          </da:FilteredListDropdownWidget>
        </div>
      </g:HTMLPanel>
</da:body>

Javа-класс полностью


package com.danilov.gwt.widgets;
 
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiChild;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
 
public class ModalDialogWidget extends Composite {
 
  private static ModalDialogWidgetUiBinder uiBinder = GWT
    .create(ModalDialogWidgetUiBinder.class);
 
  interface ModalDialogWidgetUiBinder extends 
    UiBinder<Widget, ModalDialogWidget> {
 }
 
  private String dialogId;
 
  public @UiConstructor
  ModalDialogWidget(String dialogId) {
    initWidget(uiBinder.createAndBindUi(this));
    this.dialogId = dialogId;
    dialog.getElement().setAttribute("id", dialogId);
    dialog.getElement().setAttribute("role", "dialog");
    dialog.getElement().setAttribute("aria-hidden", "true");
    dialog.getElement().setAttribute("tabindex", "-1");
    dialog.getElement().setAttribute("style", "display: none");
    cancelButton.addClickHandler(new ClickHandler() {
 
      @Override
      public void onClick(final ClickEvent event) {
        // some actions on click cancel button 
      }
 
    @UiField
    FlowPanel header;
 
    @UiField
    FlowPanel body;
 
    @UiField
    FlowPanel footer;
 
    @UiField
    Button cancelButton;
 
    @UiField
    Button okButton;
 
    @UiField
    FlowPanel dialog;
 
    private ClickHandler cancelButtonClickHandler;
 
    @UiChild(tagname = "body")
    public void addBody(Widget widget) {
      if (body == null) {
        body.clear();
      } else {
        body.add(widget);
      }
    }
 
  @UiChild(tagname = "header")
  public void addHeader(Widget widget) {
    header.add(widget);
  }
 
  public void setCancelButtonTitle(String title) {
    cancelButton.setText(title);
  }
 
  public void setOkButtonTitle(String title) {
    okButton.setText(title);
  }
 
  public void setCancelButtonClickHandler(ClickHandler handler) {
    this.cancelButtonClickHandler = handler;
  }
 
  public void setOkButtonClickHandler(ClickHandler handler) {
    okButton.addClickHandler(handler);
  }
 
  public void setOkButtonColor(String color) {
    okButton.setStyleName(color);
  }
 
  public void show() {
    modelJs("show", dialogId);
  }
 
  public void hide() {
    modelJs("hide", dialogId);
  }
 
  public static native void modelJs(String param, String dialogId) /*-{
    $wnd.$('#' + dialogId).modal(param);
  }-*/;
 
}
 


Как использовать созданный виджет


<!-- Modal Dialog Widget -->
<g:HTMLPanel>
  <da:ModalDialogWidget dialogId="modalDialog" 
    cancelButtonTitle="Cancel" okButtonTitle="OK">
    <da:header>
     <da:EditableHeader title="TEST-TITLE"
       placeholder="TEST">
     </da:EditableHeader>
    </da:header>
    <da:body>
      <g:HTMLPanel>
        <div style="width:300px; height:300px">
          <da:FilteredListDropdownWidget 
            ui:field="filteredList"> 
          </da:FilteredListDropdownWidget>
        </div>
      </g:HTMLPanel>
    </da:body>
  </da:ModalDialogWidget>
</g:HTMLPanel>

Результат


Вот такой виджет мы в итоге получили.


Комментариев нет:

Отправить комментарий