【译自:https://developers.google.com/web-toolkit/doc/latest/tutorial/manageevents?hl=zh-CN】
到此,我们已经创建了所有需要的UI控件。和许多其他的用户界面框架一样,GWT也是基于事件驱动的,也就是说代码会在响应某此发生的事件时被执行。经常,这些事件是由用户触发的,例如使用键盘或鼠标。
这一节,我们要给我们的控件添加鼠标和键盘响应事件。
一、审视事件处理需求
首先我们检查一下StockWatcher中哪些事件需要处理是:
Task | UI Event (Trigger mechanism) | Response |
用户输入股票代码 | 点击Add按钮或在文本框中按回车 |
|
用户删除股票 | 按下Remove按钮 |
|
GWT提供了一系列的事件处理接口。为了处理Add和Remove按钮事件,我们需要使用ClickHandler 接口;为了处理键盘事件,我们需要使用KeyPressHandler接口。
注:从GWT1.6开始, ClickHandler,KeyDownHandler,KeyPressHandler和KeyUpHandler接口已经替换了旧的ClickListener和KeyBoardListener接口了。
二、监听事件
Event Handler 接口
GWT中的事件接口和其他事件框架类似。要监听某一事件,需要传递一个特定的事件接口对象到相应的控件上。一个事件接口定义了一个或多个方法,可以被控件调用来处理某一事件。
处理Mouse Events
StockWatcher中,用户添加股票的方法之一就是用鼠标点击Add按钮。
通过传递一个实现了ClickHandler接口的对象,用户可以处理Add 按钮的点击事件。可能使用一个匿名内部类去实现ClickHandler接口。ClickHandler接口有一个onClick方法,当用户点击了控件时会触发它。
当用户点击了Add按钮,作为响应,StockWatcher就应该添加一条股票代码到股票表格里。因此,调用addStock方法去响应事件。不过我们还不需要实现addStock方法,先给一个架子,在下一节里我们会给出实现。
-
添加Add按钮的事件处理来接收事件在Stockwatcher.java的onModuleLoad方法,剪切和复杂以"Listen for mouse events on the Add button."注释的代码部分,也就是下面的高亮部分。Eclipse在ClickHandler会提示一个标记建议你导入所需的声明。
-
导入ClickHandler 和 ClickEvent.
-
在StockWatcher.java里,创建addStock方法的框架。
package com.google.gwt.sample.stockwatcher.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; public class StockWatcher implements EntryPoint { private VerticalPanel mainPanel = new VerticalPanel(); private FlexTable stocksFlexTable = new FlexTable(); private HorizontalPanel addPanel = new HorizontalPanel(); private TextBox newSymbolTextBox = new TextBox(); private Button addStockButton = new Button("Add"); private Label lastUpdatedLabel = new Label(); /** * Entry point method. */ public void onModuleLoad() { // Create table for stock data. stocksFlexTable.setText(0, 0, "Symbol"); stocksFlexTable.setText(0, 1, "Price"); stocksFlexTable.setText(0, 2, "Change"); stocksFlexTable.setText(0, 3, "Remove"); // Assemble Add Stock panel. addPanel.add(newSymbolTextBox); addPanel.add(addStockButton); // Assemble Main panel. mainPanel.add(stocksFlexTable); mainPanel.add(addPanel); mainPanel.add(lastUpdatedLabel); // Associate the Main panel with the HTML host page. RootPanel.get("stockList").add(mainPanel); // Move cursor focus to the input box. newSymbolTextBox.setFocus(true); // Listen for mouse events on the Add button. addStockButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { addStock(); } }); } /** * Add stock to FlexTable. Executed when the user clicks the addStockButton or * presses enter in the newSymbolTextBox. */ private void addStock() { // TODO Auto-generated method stub } }
处理键盘事件
除了Add按钮,StockWatcher用户也可以通过按回车键添加一个股票代码,而不需要把手从键盘上移走。
为了订制一个键盘事件,我们需要调用addKeyPressHander(KeyPressHandler)方法,传入一个KeyPresshandler对象。
-
对输入框newSymbolTextBox添加keypress事件在onModuleLoad方法,复制和粘贴以"Listen for keyboard events in the input box."注释部分的代码。
// Listen for mouse events on the Add button. addStockButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { addStock(); } }); // Listen for keyboard events in the input box. newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() { public void onKeyPress(KeyPressEvent event) { if (event.getCharCode() == KeyCodes.KEY_ENTER) { addStock(); } } }); } /** * Add stock to FlexTable. Executed when the user clicks the addStockButton or * presses enter in the newSymbolTextBox. */ private void addStock() { // TODO Auto-generated method stub } }
- 添加导入声明
import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler;
声事件处理已经添加完成,下一步就是完成addStock()方法
三、响应用户事件
到此,StockWatcher已经监听了用户输入。一个鼠标或键盘事件标明用户输入了一个股票代码。接下来就是通过响应事件来测试这些事件处理接口:添加股票代码。
StockWatcher不需要发送请求到服务器端或重新加载页面来响应请求。
添加股票到列表中
在StockWatcher中,用户输入它想监控的股票代码到输入框中。当它按下回车键或点击了Add按钮时,我们需要:
- 验证输入
- 检查重复
- 添加代码
- 添加删除按钮
这一节,我们先实现第一步:验证输入,用于检测事件处理接口是不是工作,下一节 Coding Functionality on the Client,会完成剩下的部分。
在addStock方法里实现这些功能。
验证输入
这里我们只验证输入是不是有效,而不验证它是不是一个存在的股票id。因此我们只做一个简单的字母检测。
- 首先提取股票代码
通过TextBox的getText()方法取得输入值 - 确保字母串中不包含非法字符
取得输入值后,使用一个正则表达式去检查是不是一个合法的输入。正则表达式在java和javascript中有相同的意义。 - 最后,如果输入无效,提示一个对话框
-
验证在StockWatcher.java中,以以下代码替换addStock方法:
private void addStock() { final String symbol = newSymbolTextBox.getText().toUpperCase().trim(); newSymbolTextBox.setFocus(true); // Stock code must be between 1 and 10 chars that are numbers, letters, or dots. if (!symbol.matches("^[0-9A-Z\\.]{1,10}$")) { Window.alert("'" + symbol + "' is not a valid symbol."); newSymbolTextBox.selectAll(); return; } newSymbolTextBox.setText(""); // TODO Don't add the stock if it's already in the table. // TODO Add the stock to the table. // TODO Add a button to remove this stock from the table. // TODO Get the stock price. }
-
添加导入
import com.google.gwt.user.client.Window;
四、测试事件处理
到此,我们已经能够在输入框中输入,如果使用了非法字符,则会有一个提示框出现:
-
在Development模式下测试在已经打开的浏览器里刷新
-
测试两种事件处理都工作输入股票代码,测试回车键和鼠标点击Add按钮。
现在股票还不会添加到列表中,但是输入框会清除,用户可以重新输入 -
测试验证和错误信息输入一些非法值
Tip: 在Development模式下,你们代码修改会立即生效,只需要在浏览器上刷新即可。你不需要重新启动应用