GWT - GWT Designer开发Ajax应用 (03)

前篇:http://blog.youkuaiyun.com/pathuang68/archive/2009/04/25/4117352.aspx

目标:利用GWT和GWT Designer创建一个股票查看器。

注意:如果看不到完整的图片,可以鼠标右键->“图片另存为”的方法,存到本地看即可。


1. 新建一个GWT Java Project

1

2

点击Next按钮,如下图将项目名称设定为“StockWatcher”:

3

点击Next按钮。如下图,选择Create GWT Module复选框,并指定Module NameStockWatcherPackage Namecom.pnft.ajax

4

点击Finish按钮,

5

上图是GWT Designer自动为我们产生的一些代码,点击左下角Design tab并双击上边的Tab - StockWatcher.java以放大,

6

删除Click me!按钮,以删除自动产生boilerplate code

7

点击Source tab,可以看到现在StockWatcher.java的代码变成了:

8

到此,项目建立完成。


2. UI设计

我们希望最终的参考界面如下图所示:

9

现在我们来设计图形界面:

a. rootPanel中放置一个VerticalPanel

10

11

将刚才添加的VerticalPanel放置到rootPanel的左上角,并拖动其Anchor使之放大到合适的大小,并将其variable属性改为mainPanel,如下图所示:

12

b. 如下图所示,在mainPanel中增加一个FlexTable,并将其variables户型改为stocksFlexTable

13

c. 如下图所示,在mainPanel中,stocksFlexTable之下,增加一个HorizontalPanel,并使其variable属性为“addPanel

14

d. addPanel中增加两个widget,如下图所示:

- 一个文本框,使其variable属性为“newSymbolTextBox”;

- 一个按钮,使其variable属性为“addButton”,其Text属性为“Add

15

e. addPanel下面增加一个Label,修改其属性,使其variable属性为“lastUpdatedLabel”:

16

f. Convert local to field。选中最上层的mainPanel,然后点击Covert local to field按钮:

17

对于其他widgetFlexTableTextBoxButton以及Label均使用同样方法进行Convert local to field

下图就是我们前面所做的工作的代码结果:

18

g. 将文本框newSymbolTextBoxfocus属性设定为true,这样当进入到该页面是,文本框newSymbolTextBox将自动获得输入焦点。


3. 代码设计

- a. 切换到Source,并找到下面高亮的语句。

19

插入代码,使其如下:

20

到目前为止,我们前面所做的工作结果类似:

21

b. 给按钮增加onClick事件处理函数:

22

自动生成代码如下:

addButton.addClickListener(new ClickListener()

{

public void onClick(final Widget sender)

{

}

});

onClick函数中增加如下一行,使之如下(注意addStock()目前还不存在)

addButton.addClickListener(new ClickListener()

{

public void onClick(final Widget sender)

{

addStock();

}

});

c. 给文本框增加一个keyDown处理函数:

23

自动生成的代码如下:

newSymbolTextBox.addKeyboardListener(new KeyboardListenerAdapter()

{

public void onKeyDown(final Widget sender, final char keyCode, final int modifiers)

{

}

});

onKeyDown函数中增加如下一行,使之如下(注意addStock()目前还不存在)

newSymbolTextBox.addKeyboardListener(new KeyboardListenerAdapter()

{

public void onKeyDown(final Widget sender, final char keyCode, final int modifiers)

{

addStock();

}

});

d. 增加addStock方法:

24

选择Create method ‘addStock()’ in type ‘StockWatcher’(注意,此处所谓type即为class之别称),修改addStock的的代码如下:

protected void addStock()

{

final String symbol = newSymbolTextBox.getText().toUpperCase().trim();

newSymbolTextBox.setFocus(true);

// validation

// symbol must be between 1 and 10 chars that are numbers, letters, or dots

// the matches method takes a parameter of regular expression like the following code

if(!symbol.matches("^[0-9a-zA-Z//.]{1,10}$"))

{

Window.alert("'" + symbol + "' is not a valid symbol.");

newSymbolTextBox.selectAll();

return;

}

newSymbolTextBox.setText("");

// here we need to add the stock to the list...

}

e. 修改onKeyDown代码如下,判断是否有回车键按下,如果是,则调用addStock方法:

public void onKeyDown(final Widget sender, final char keyCode, final int modifiers)

{

if(keyCode == KEY_ENTER)

{

addStock();

}

}

f. 增加一个ArrayList如下:

25

g. 修改addStock方法,使之如下:

protected void addStock()

{

final String symbol = newSymbolTextBox.getText().toUpperCase().trim();

newSymbolTextBox.setFocus(true);

// validation

// symbol must be between 1 and 10 chars that are numbers, letters, or dots

// matches method takes a parameter of regular expression like the following code

if(!symbol.matches("^[0-9a-zA-Z//.]{1,10}$"))

{

Window.alert("'" + symbol + "' is not a valid symbol.");

newSymbolTextBox.selectAll();

return;

}

newSymbolTextBox.setText("");

// here we need to add the stock to the list...

if(stocks.contains(symbol)) return;

// add the stock to the list

int row = stocksFlexTable.getRowCount();

stocks.add(symbol);

stocksFlexTable.setText(row, 0, symbol);

// add button to remove this stock from the list

Button removeStock = new Button("x");

removeStock.addClickListener(new ClickListener()

{

public void onClick(Widget sender)

{

int removedIndex = stocks.indexOf(symbol);

stocks.remove(removedIndex);

stocksFlexTable.removeRow(removedIndex + 1);

}

});

stocksFlexTable.setWidget(row, 3, removeStock);

}

注意:

// here we need to add the stock to the list...后面的代码是新加的。

h. 阶段性结果:

26

i. 增加一个计时器,用来模拟股票价格在一天中的变化。为此,我们必须

import com.google.gwt.user.client.Timer;

在类StockWatcher最开始处增加以下代码,用来确定多长时间间隔可进行一次刷新:

private static final int REFRESH_INTERVAL = 5000;

并在onModuleLoad()方法的最后处,增加以下代码:

Timer refreshTimer = new Timer()

{

public void run() // 注意:以内部类的形式出现

{

refreshWatchList(); // 注意:此时refreshWatchList方法尚不存在

}

};

refreshTimer.scheduleRepeating(REFRESH_INTERVAL);

j. 增加refreshWatchList方法,和增加addStock方法的过程类似。

k. 新增一个类StockPrice

27

28

点击Finish按钮。

修改类StockPrice的代码,使之如下:

package com.pnft.ajax.client;

public class StockPrice

{

private String symbol;

private double price;

private double change;

public StockPrice()

{

}

public StockPrice(String symbol, double price, double change)

{

this.symbol = symbol;

this.price = price;

this.change = change;

}

public String getSymbol() {

return symbol;

}

public void setSymbol(String symbol) {

this.symbol = symbol;

}

public double getChangePercent()

{

return 100.0 * this.change / this.price;

}

public double getPrice() {

return price;

}

public void setPrice(double price) {

this.price = price;

}

public double getChange() {

return change;

}

public void setChange(double change) {

this.change = change;

}

}

l. 回到StockWatcher源代码,修改在步骤j中增加的方法refreshWatchList,并引入相关的包,使得方法refreshWatchList的代码如下:

protected void refreshWatchList()

{

final double MAX_PRICE = 100.0;

final double MAX_PRICE_CHANGE = 0.02; // +/- 2%

StockPrice[] prices = new StockPrice[stocks.size()];

for(int i = 0; i < stocks.size(); i++)

{

double price = Random.nextDouble() * MAX_PRICE;

double change = price * MAX_PRICE_CHANGE * (Random.nextDouble() * 2.0 - 1.0);

prices[i] = new StockPrice((String)stocks.get(i), price, change);

}

updateTable(prices); // 注意此时updateTable方法尚不存在

}

m. 增加updateTable方法,过程与步骤d(增加addStock方法)类似。修改updateTable方法的代码,使之如下:

private void updateTable(StockPrice[] prices)

{

for(int i = 0; i < prices.length; i++)

{

updateTable(prices[i]);

}

// change the last update timestamp

lastUpdatedLabel.setText("Last update : " + DateTimeFormat.

getMediumDateFormat().format(new Date()));

}

private void updateTable(StockPrice price)

{

// make sure the stock is still in our watch list

if (!stocks.contains(price.getSymbol()))

{

return;

}

int row = stocks.indexOf(price.getSymbol()) + 1;

// apply nice formatting to price and change

String priceText = NumberFormat.getFormat("#,##0.00").format(

price.getPrice());

NumberFormat changeFormat = NumberFormat

.getFormat("+#,##0.00;-#,##0.00");

String changeText = changeFormat.format(price.getChange());

String changePercentText = changeFormat

.format(price.getChangePercent());

// update the watch list with the new values

stocksFlexTable.setText(row, 1, priceText);

stocksFlexTable.setText(row, 2, changeText + " (" + changePercentText + "%)");

}

n. 如以下图形所表明的步骤,增加Googlelogo

29

30

点击Next按钮,

31

点击Finish按钮。图片已经被import进来:

32

回到StockWatcher.javaDesign状态,在FlexTable之上,增加一个Image widget,然后将该Image widgetURL属性设置为图片所在的位置。

33

34

指定ImageURL属性为googlecode.png,得到:

35

o. 在图片下面增加一个Label,使其Text属性为“Stock Watcher”,并做相应的微调,得到结果如下:

36

p. 试运行

37

q. 增加一些颜色

38

r. 部署

39

40

选择Tomcat6的路径,点击OK按钮。

41

部署成功。在Tomcat6/webapps目录下多出了一个StockWatcher.war文件:

42

s. 启动Tomcat6

t. 最后结果:

43

后篇:http://blog.youkuaiyun.com/pathuang68/archive/2009/04/27/4130429.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值