GWT中UiBinder是用来管理界面结构和样式的技术,下面是google开发文档中的实例
这是一个最简单的UiBinder构建界面的例子,只有html,没有widget,是一个xml文件
<!-- HelloWorld.ui.xml --> <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'> <div> Hello, <span ui:field='nameSpan'/>. </div> </ui:UiBinder>
与其相对应的有一个java类
public class HelloWorld extends UIObject { interface MyUiBinder extends UiBinder<DivElement, HelloWorld> {} private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); @UiField SpanElement nameSpan; public HelloWorld() { setElement(uiBinder.createAndBindUi(this)); } public void setName(String name) { nameSpan.setInnerText(name); } }
创建一个HelloWorld实例,并执行setName方法,向nameSpan中插入数据
HelloWorld helloWorld = new HelloWorld(); // Don't forget, this is DOM only; will not work with GWT widgets Document.get().getBody().appendChild(helloWorld.getElement()); helloWorld.setName("World");
这里解释一下UiBinder的用法:
1. UiBinder是用GWT工厂模式创建的,接口UiBinder<U,O>声明了两个参数:U指的是ui.xml中声明的根元素;O是指对应的java类名。
2. 任何一个在ui.xml文件中申明的object都可以利用fieldname在对应的Java文件中被使用。在这个例子中,<span>有个ui:field属性,在Java文件中,对应表现为用@Uifield注释,变量名为ui:field的值。
3. 这个HelloWorld实例继承了UIObject类,它还可以继承Widget,Composite等。注意,被标识注释@UiField的域默认是可视的,如果他们被binder创建实例了,他们不可以是private的。
下面是一个使用了Widget的UiBinder的实例
<!-- HelloWidgetWorld.ui.xml --> <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'> <g:HTMLPanel> Hello, <g:ListBox ui:field='listBox' visibleItemCount='1'/>. </g:HTMLPanel> </ui:UiBinder>
对应的Java类
public class HelloWidgetWorld extends Composite { interface MyUiBinder extends UiBinder<Widget, HelloWidgetWorld> {} private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); @UiField ListBox listBox; public HelloWidgetWorld(String... names) { // sets listBox initWidget(uiBinder.createAndBindUi(this)); for (String name : names) { listBox.addItem(name); } } }
new一个实例
// Use: HelloWidgetWorld helloWorld = new HelloWidgetWorld("able", "baker", "charlie");
分析上面的例子:
1. 利用 ”g='urn:import:com.google.gwt.user.client.ui'" import gwt的包,用g标识
2. 根元素为HTMLPanel , 继承了Widget
3. uiBinder.createAndBindUi(this)创建根元素的实例
4. visibleItemCount属性对应ListBox中setVisibleItemCount(int)方法
接下来是一个使用Panel的例子
任何一个Panel(理论上,任何继承了HasWidgets接口的类)可以在uiBinder模板中使用,并且可以包含其他Panel
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'> <g:HorizontalPanel> <g:Label>Keep your ducks</g:Label> <g:Label>in a row</g:Label> </g:HorizontalPanel> </ui:UiBinder>
有些GWT的Widget需要特殊的标记,这是一个DockLayoutPanel的例子
<g:DockLayoutPanel unit='EM'> <g:north size='5'> <g:Label>Top</g:Label> </g:north> <g:center> <g:Label>Body</g:Label> </g:center> <g:west size='10'> <g:HTML> <ul> <li>Sidebar</li> <li>Sidebar</li> <li>Sidebar</li> </ul> </g:HTML> </g:west> </g:DockLayoutPanel>
1. DockLayoutPanel 的子元素<g:north size='5'>, <g:center>, 他们不可以有ui:field属性,因为在java类中是没有这些域的。
2. 需要注意的是,大多数的Panel都不可以将HTML直接放入,但是可以放入Widget中
下面是绑定Event Handlers的实例
一般情况下在java代码中写Event Handler是这样的:
public class MyFoo extends Composite { Button button = new Button(); public MyFoo() { button.addClickHandler(new ClickHandler() { public void onClick ClickEvent event) { handleClick(); } }); initWidget(button); } void handleClick() { Window.alert("Hello, AJAX"); } }
在UiBinder模板对应的Java文件中,我们可以利用@UiHandler
public class MyFoo extends Composite { @UiField Button button; public MyFoo() { initWidget(button); } @UiHandler("button") void handleClick(ClickEvent e) { Window.alert("Hello, AJAX"); } }
Composite是一种可以包含其他Widget的Widget,具体可参考google-web-toolkit.googlecode