Apache Pivot WTKX入门

WTKX是用于创建Pivot应用程序的基于XML的标记语言。虽然,通常是用于定义用户界面的结构,但是也可以用于声明创建Java对象。

本节主要介绍WTKX和解释如何使用WTKX创建和配置java对象集合。假定你已经熟悉掌握了Pivot和Java程序设计语言。

元素(element)

在WTKX中,一个XML元素可能表示一下其一:

  • 一个类的实例

  • 一个类实例的特性(属性)

  • WTKX串行化处理指令

如果一个元素的标签名称以大写字母开头,被认为是一个类实例。其它当做类实例的属性处理,除非标签名称以保留名称空间前缀"wtkx"开始。以wtkx名称空间前缀开始的元素属于串行化指令,在后面的章节会详细的描述。

类实例元素(Class Instance Elements)

当WTK串行化(org.apache.pivot.wtkx.WTKXSerializer的一个实例, 后面会描述) 遇到一个元素的标签是以大写字母开头时,它认为标签的名字是一个Java的类并创建一个该类的实例。元素名称空间指定类名所属的Java包。

例如,下面的WTKX展示了org.apache.pivot.wtk.Label类的一个实例,并显示text"Hello,World"(和特性一个,属性也是可以用于设置特性的值,在下节讨论):

1<Label text="Hello, World!"
2    xmlns="org.apache.pivot.wtk" />

注意:默认的名称空间被定义为 org.apache.pivot.wtk. 在Pivot开发中,这是一个非常常见的惯例,因为WTKX经使用定义在该包的类来构造用户界面。

更复杂的例子可能使用定义于其它包的类和使用多个名称空间。名称空间前缀可以使用于此目的。例如,下面的WTKX给包 org.apache.pivot.wtk.charts 分配了名称空间前缀charts , 并且设置org.apache.pivot.wtk.charts.BarChartView 的实例为Window的内容:

1<Window xmlns="org.apache.pivot.wtk"
2    xmlns:charts="org.apache.pivot.wtk.charts">
3    <content>
4        <charts:BarChartView/>
5    </content>
6</Window>
字典 vs.Bean字典(Dictionary vs. BeanDictionary)

通常情况下,WTKX文件中以大写字母开头的元素代表的是一个JavaBean类的实例,在WTKX系列化内部使用org.apache.pivot.beans.BeanDictionary 来封装类的实例,并调用它的Set方法。然而如果名称所代表的对象的类实现了接口org.apache.pivot.collections.Dictionary (比如 org.apache.pivot.collections.HashMap),就不使用JavaBean封装,而是使用dictionary的方法直接存取。例如,下面的WTKX创建了一个 org.apache.pivot.collections.HashMap 的实例,并设置 "foo" 和"bar" 的值分别为 "123" 和"456":

1<HashMap foo="123" bar="456"
2    xmlns="org.apache.pivot.collections"/>

实例特性元素(Instance Property Elements)

那些标签以小写字母开始的元素代表了一个实例的特性。一个特性可能表示下面的其一情况:

  • 一个标准JavaBean特性的setter

  • 一个只读的序列

  • 一个只读的字典

  • 一个事件监听者列表

WTKX串行化使用bean字典获得的信息可以知道特性的类型和正确的处理元素的内容。

JavaBean特性Setters(JavaBean Property Setters)

如果一个元素表示一个JavaBean特性setter,元素的内容就会被当做值传递给特性的setter。例如,下面的WTKX创建了Label类的一个实例,并且设置label的text特性的值为"Hello,World!":

1<Label xmlns="org.apache.pivot.wtk">
2    <text>Hello, World!</text>
3</Label>

下面展示了一个具有相同结果的实例,使用属性设置text的特性:

1<Label text="Hello, World!"
2    xmlns="org.apache.pivot.wtk"/>

下面的事例创建了一个ListView的实例,并且设置listData特性的值为一个org.apache.pivot.collections.ArrayList 对象,一个具有多个 org.apache.pivot.wtk.content.ListItem 对象的类型:

01<ListView xmlns="org.apache.pivot.wtk"
02    xmlns:collections="org.apache.pivot.collections"
03    xmlns:content="org.apache.pivot.wtk.content">
04    <listData>
05        <collections:ArrayList>
06            <content:ListItem text="A"/>
07            <content:ListItem text="B"/>
08            <content:ListItem text="C"/>
09        </collections:ArrayList>
10    </listData>
11</ListView>
只读序列(Read-Only Sequences)

如果特性代表的是一个只读序列(一个bean特性的getter返回一个org.apache.pivot.collections.Sequence 对象并且没有相应的setter方法),元素的内容被添加到序列。例如, org.apache.pivot.wtk.TabPane类的tabs特性返回 TabSequence的实例

1<TabPane xmlns="org.apache.pivot.wtk">
2    <tabs>
3        <Label text="Foo"/>
4        <Label text="Bar"/>
5    </tabs>
6</TabPane>
只读字典(Read-Only Dictionaries)

一个特性属性可能代表一个只读字典(一个bean特性的getter方法返回一个org.apache.pivot.collections.Dictionary 实例,但是没有相应的setter方法)。例如 org.apache.pivot.wtk.Component 的userData特性代表一个只读字典特性:

1<Label text="Hello, World!"
2    xmlns="org.apache.pivot.wtk">
3    <userData foo="123" bar="456"/>
4</Label>

uaserData特性的属性值被放入到字典,使用属性的名字作为键,属性值为键的值。

监听者列表(Listener Lists)

最后属性可能代表一个事件监听者列表(org.apache.pivot.util.ListenerList的一个实例)。如果是这样,子元素代表了适当的监听者并被添加到监听者列表。 在脚本一章节详细描述。

属性(Attributes)

WTKX的熟悉可能代表下面情况之一:

  • 一个标准的JavaBean特性的setter方法

  • 一个静态的特性setter方法

  • 一个事件监听者

JavaBean特性Setter方法(JavaBean Property Setters)

如果一个属性代表一个bean特性的setter,属性值会被当做参数传递给setter方法。如果属性的类型为strng,值按原样传递;然而,如果属性类型是其它简单类型(boolean, char, byte, short, int, long, float, or double)或者简单类型的封装类型,在调用setter方法之前会被转换为适当的类型。例如,下面给出一个简单的bean类:

1package com.foo;
2public class MyBean {
3    public String getFoo() { ... }
4    public void setFoo(String foo) { ... }
5    public int getBar() { ... }
6    public void setBar(int bar) { ... }
7}

下面的WTKX实例化了bean,并调用foo和bar setters方法,并且传递string给setFoo和setBar:

1<MyBean foo="hello" bar="123"
2    xmlns="com.foo"/>

然而,如果一个元素表示的对象的类已经实现了Dictionary接口(如HasmMap),属性的类型就无法决定,也不会有类型转换发生,值简单的按strng传递。

静态特性Setters方法(Static Property Setters)

属性可能摆式"静态setters" (有些时候"附加特性")。附加特性就是那些只有在特定上下文才出现的特性(属性)。当类被调用时,他们并不是类内定义的属性,而是在其它的类定义(一般的,比如父容器或者组件)。

下面的WTKX为TabPane 类的label特性调用了静态setter:

1<TabPane xmlns="org.apache.pivot.wtk">
2    <tabs>
3        <Label TabPane.label="First Tab" text="Tab 1"/>
4    <tabs>
5</TabPane>

上面的WTKX代码可以转换为下面对应的Javad代码:

1TabPane tabPane = new TabPane();
2Label label = new Label();
3label.setText("Tab 1");
4tabPane.getTabs().add(label);
5TabPane.setLabel(label, "First Tab");

调用TabPane.setLabel()把"name"特性和Label实例关联在一起。tab pane随后使用特性的值作为出现在pane按钮栏的按钮的数据。TabPane同样也为tab的图标定义了一个静态setter。其它容器,包含Accordion和TablePane也定义了类似的setters。

注意:虽然在WTKX中静态setter属性定义在最前面,但事实上是在setter(text)特性后调用(就像Label的实例被添加到tab pane一样)。 因为静态setter是将一个实例添加到其父类对象(组件)中,在实例为创建之前,静态setter是不能被调用的。添加一个对象到父对象时使得关联的特性生效。相反的,从父对象删除一个对象时,先前关联的特性也被移除。

事件监听者(Event Listeners)

最后,属性可能代表一个事件监听者。属性值包含的脚本代码用于在响应事件时被执行。详细的描述在脚本一章节。

操作符解析(Resolution Operators)

WTKX的Setter属性支持几种操作符解析的处理能力:

  • 对象解引用 Object dereference

  • 资源解析Resource resolution

  • URL定位解析 URL resolution

对象解引用(Object Dereference)

对象解引用操作允许属性相应的setter函数调用前使用一个先前定义的命名对象替换属性的值。任何属性其值以$开头时都被认为是对象解引用。

例如,一个table view header必须与一个TableView对象关联。在Java,痛过使用setTableView方法实现。在WTKX,对象解引用操作被使用。下面的WTKX定义了一个ScrollPane对象,设置TableView为组建的view,并且使用TableViewHeader作为列头。table view 痛过tableView属性关联列头:

01<ScrollPane xmlns="org.apache.pivot.wtk"
02    xmlns:wtkx="http://pivot.apache.org/wtkx">
03    <view>
04        <TableView wtkx:id="tableView">
05            ...
06        </TableView>
07    </view>
08    <columnHeader>
09        <TableViewHeader tableView="$tableView"/>
10    </columnHeader>
11</ScrollPane>

注意:上面的例子使用了"wtkx"名称空间前缀。这是一个由WTKX串行化对象解析的特别的名称空间。如上所示,定义了元素的id,用于给类的实例分配一个名称。除了解引用之外,该ID也可以用于在Java代码系列化WTKX或者脚本代码包含WTKX文件时获得被实例化的元素的引用。I

其它特别的元素也被定义于wtkx名称空间中,在后面的章节在详细描述。

资源解析(Resource Resolution)

在WTKX中,为了本地化的目的,资源的替代在加载时才被执行。当给出一个.org.apache.pivot.util.Resources实例时, WTKXSerializer 会使用指定的值替换资源的名称. 资源名称使用%前缀定义,如下所示:

1<Label text="%myText"/
2    xmlns="org.apache.pivot.wtk">

与之关联的本地资源文件可能包含如下所示的内容:

1{   myText:"This is my text!"
2}

显示lable的文本是 "This is my text!".

WTKXSerializer 在后面会详细的讨论。

URL解析(URL Resolution)

属性也可以用来指定URLs。一个值以'@'字符开始的属性被转换为URL,该URL的地址相对于WTKX源文件所在的地址。例如,下面的WTKX从与WTKX文件相同的目录加载图像。WTKX转换为调用ImageView#setImage(java.net.URL)方法:

1<ImageView image="@foo.png"
2    xmlns="org.apache.pivot.wtk"/>

如果没有 "@" 操作符bean属性就没有相关的上下文可以解析资源的路径。

包含(Includes)

<wtkx:include>标签允许WTKX文件嵌入一个外部定义的WTKX文件为其内容。 这个对于组织文件的多个部分是非常用于的。

下面的WTKX定义了Windows的内容包含一个外部文件content.wtkx文件:

1<Window xmlns="org.apache.pivot.wtk"
2    xmlns:wtkx="http://pivot.apache.org/wtkx">
3    <content>
4        <wtkx:include src="content.wtkx"/>
5    </content>
6</Window>

包含文件的内容使用一个嵌套的WTKXSerializer实例进行加载。如果给包含标签分配一个ID,定义于该包含文件内的对象可以通过名称调用WTKXSerializer#get获得。例如,下面给如的WTKX,调用者可以在随后使用"content.label"取得Label的实例:

1<-- window.wtkx -->
2<Window xmlns="org.apache.pivot.wtk"
3    xmlns:wtkx="http://pivot.apache.org/wtkx">
4    <content>
5        <wtkx:include wtkx:id="content" src="content.wtkx"/>
6    </content>
7</Window>
1<-- content.wtkx -->
2<Label xmlns="org.apache.pivot.wtk"
3    xmlns:wtkx="http://pivot.apache.org/wtkx"
4    wtkx:id="label" text="Hello, World!"/>

Java 代码:

1Label label = (Label)wtkxSerializer.get("content.label");

定义(Defines

通常情况下WTKX中定义的类实例元素都期望自己有一个父标签。然而,某些时候声明的对象并不需要一个直接的父对象。<wtkx:define>标签可以用于实现该目的。

例如,下面的WTKX实例化了一个 login对话框对象,通过include实现。对话框实例被分配了一个ID,可以用于在脚本或者Java代码中定义与之相关的事件处理器:

1<Window xmlns:wtkx="http://pivot.apache.org/wtkx"
2    xmlns="org.apache.pivot.wtk">
3    <wtkx:define>
4        <wtkx:include wtkx:id="loginDialog" src="login_dialog.wtkx"/>
5    </wtkx:define>
6    <content>
7        ...
8    </content>
9</Window>

脚本(Scripting

 <wtkx:script>标签允许调用者导入脚本代码或者嵌入包含脚本代码的WTKX文件。 任何JVM脚本语言都可以被使用。.The name of the scripting language is passed to the WTKXSerializer instance that is used to load the WTKX file. WTKXSerializer is discussed in more detail below.

例如,下面的WTKX定义了一个JavaScript代码,并在JavaScript中定义了一个名称为foo的变量。该变量的值被用于展现定义在Windows content 的Label实例:

1<Window xmlns:wtkx="http://pivot.apache.org/wtkx"
2    xmlns="org.apache.pivot.wtk">
3    <wtkx:script>
4    var foo = "Hello, World!";
5    </wtkx:script>
6    <content>
7        <Label text="$foo"/>
8    </content>
9</Window>

脚本代码也可以被定义于外部文件:

1<Window xmlns:wtkx="http://pivot.apache.org/wtkx"
2    xmlns="org.apache.pivot.wtk">
3    <wtkx:script src="foo.js"/>
4    <content>
5        <Label text="$foo"/>
6    </content>
7</Window>

任何在脚本中被声明为global的变量都被添加到WTKX文件名称空间内,并且可以用于对象解引用操作和通过WTKXSerializer#get获得对象的引用。

监听者列表元素(Listener List Elements)

WTKX中的脚本代码可能被用于定义事件处理器。每一个事件处理器定义于脚本会比定义于Java代码更加方便。例如,下面给出的WTKX:

1<PushButton xmlns="org.apache.pivot.wtk"
2    xmlns:wtkx="http://pivot.apache.org/wtkx"
3    wtkx:id="pushButton" buttonData="Click Me!"/>

Java代码获得PushButton的引用和关联按钮的press监听者的代码可能如下:

1PushButton pushButton = (PushButton)wtkxSerializer.get("pushButton");
2pushButton.getButtonPressListeners().add(new ButtonPressListener() {
3    public void buttonPressed(Button button) {
4        // Handle event
5    }
6});

然而可以更加简单的完成这个事情,一个相似的脚本代码可能如下:

01<PushButton xmlns="org.apache.pivot.wtk"
02    xmlns:wtkx="http://pivot.apache.org/wtkx"
03    buttonData="Click Me!">
04    <buttonPressListeners>
05        <wtkx:script>
06        function buttonPressed(button) {
07            // Handle event
08        }
09        </wtkx:script>
10    </buttonPressListeners>
11</PushButton>

This version is quite a bit easier to read, and creates a much stronger association between the button and the handler. It doesn't even require the button to be given an ID.

当脚本被定义于监听者列表元素内时,WTKXSerializer创建了一个局部范围的本地处理器。其结果就是,任何出现在脚本块中定义的变量和函数只有在块内可见。

基于脚本的事件处理器没有必要实现监听者接口的所有方法,可以忽略掉方法,会被简单的处理为 no-op处理器。

事件监听者属性(Event Listener Attributes)

事件监听者也可以被定义为属性,使用于静态特性setter相似的语法。属性的名称包含事件处理器的接口和其名称,通过·分隔。 和监听者列表元素一样,一个局部范围的代码被创建。 任何定义于处理器内的变量只有在处理器内可见。

例如,上面的按钮press监听者可以被定义为一个属性,如下:

1<PushButton xmlns="org.apache.pivot.wtk"
2    xmlns:wtkx="http://pivot.apache.org/wtkx"
3    buttonData="Click Me!"
4    ButtonPressListener.buttonPressed="// Handle event"/>

基于属性事件处理器主要使用于短小代码的处理器,通常适合于只有单行代码的处理器。长代码的事件处理器最好是使用基于元素的监听者列表或者使用Java代码实现。

WTKX串行化(WTKXSerializer)

org.apache.pivot.wtkx.WTKXSerializer类主要用于加载和处理WTKX文件和关联脚本与包含文件。实现了 org.apache.pivot.serialization.Serializer 接口,和返回了定义于WTKX文件中的对应的对象层次结构。.定义重载了 readObject()方法:

1public Object readObject(String resourceName) { ... }
2public Object readObject(URL location) { ... }
3public Object readObject(InputStream inputStream) { ... }

第一个版本,在应用程序的路径下加载WTKX文件资源。第二个版本的函数从一个URL中加载。

1<Window xmlns="org.apache.pivot.wtk"
2    xmlns:wtkx="http://pivot.apache.org/wtkx">
3    <content>
4        <Label wtkx:id="label" text="Hello, World!"/>
5    </content>
6<Window>

 

1public void startup(Display display, Map<String, String> properties)
2    throws Exception {
3    WTKXSerializer wtkxSerializer = new WTKXSerializer();
4    Window window =
5        (Window)wtkxSerializer.readObject(getClass().getResource("window.wtkx"));
6    window.open(display);
7}

访问命名对象(Accessing Named Objects)

当WTKX文件的跟对象被加载以后,WTKXSerializer#get()方法允许调用者取得一个在WTKX中命名对象的实例readObject()方法会处理命名对象ID和对象实例之间的映射,使得调用者随后可以引用到这些对象。

继续上一个例子,下面的代码取得了Lable实例,并且改变text为 "Welcome to Pivot"!:

1public void startup(Display display, Map<String, String> properties)
2    throws Exception {
3    WTKXSerializer wtkxSerializer = new WTKXSerializer();
4    Window window =
5        (Window)wtkxSerializer.readObject(getClass().getResource("window.wtkx"));
6    Label label = wtkxSerializer.getObjectByID("label");
7    label.setText("Welcome to Pivot!");
8    window.open(display);
9}

WTKXSerializer 实现了Dictionary接口,所以调用者可以使用put和remove方法修改serializer's 名称空间,在加载之前。

嵌套包含(Nested Includes)

定义于WTKX包含的对象可以通过get()方法取得。包含文件的ID定义了改包含的名传空间,调用者可以使用点分隔的名称空间路径访问嵌套对象:

1Label label = (Label)wtkxSerializer.get("content.label")

 "content" 是包含Label实例的包含文件的ID, "label"是 label本身的ID。

WTKX绑定(WTKX Binding)

org.apache.pivot.wtkx包包含的注解可以用于简单的映射命名对象到java程序。   @WTKX注解可以用于标记一个成员变量,会自动映射WTKX文件中的命名对象。WTKXSerializer 的bin() 方法用于执行实际的映射:

1<Window xmlns="org.apache.pivot.wtk"
2    xmlns:wtkx="http://pivot.apache.org/wtkx">
3    <content>
4        <Label wtkx:id="label" text="Hello, World!"/>
5    </content>
6<Window>

WTKXSerializer#bind() 被调用时,下面的代码被自动添加:

1@WTKX private Label label;

总结(Summary)

WTKX 提供了一系列特性用于帮助构建用户接口。可以用于实例化对象、设置成员的值和定义逻辑脚本等。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值