package demo.app.client.client;
import demo.app.client.shared.FieldVerifier;
import com.google.gwt.core.client.EntryPoint;
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.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
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;
/**
* 入口点的类定义的<code> onModuleLoad()</code>。
*/
public class App implements EntryPoint {
/**
*消息显示给用户,当服务器不能达到或
*返回一个错误。
*/
private static final String SERVER_ERROR = "时发生错误 "
+ "试图联系服务器. 请检查你的网络服务器 "
+ "连接,然后再试一次.";
/**
*创建一个远程服务代理 与 服务器端的异步服务。
*GWT.create 延迟绑定实例化的类。
*创建参数类必须是一个 类的名称
*参数:
*类 ,类的名字指定基类被实例化
*返回:
*新的实例,必须强制转换为所请求的类。
*
*异步GreetingService接口
*com.google.gwt.core.client.GWT
*支持的核心功能,在某些情况下需要直接从编译器和运行时系统,如运行时类型信息和延迟绑定的支持。
*
*/
private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
/**
* 只是入口点方法
*/
public void onModuleLoad() {
//创建一个发送按钮
final Button sendButton = new Button("Send");//[发送]
//创建一个文本框
final TextBox nameField = new TextBox();
//为文本框的标题赋值
nameField.setText("GWT User");
// 创建一个显示错误提示的文本标签
final Label errorLabel = new Label();
// We can add style names to widgets
// 我们可以添加样式名称部件 下面为BUTTON添加固定样式 样式表见API
sendButton.addStyleName("sendButton");
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
// 添加nameField和sendButton的RootPanel
// 使用RootPanel.get() nameFieldContainer=文本框集装箱, 把nameField添加到 nameField集装箱里面
RootPanel.get("nameFieldContainer").add(nameField);
RootPanel.get("sendButtonContainer").add(sendButton);//同上
RootPanel.get("errorLabelContainer").add(errorLabel);//同上
// Focus the cursor on the name field when the app loads
// 当应用程序加载时,让文本框获得焦点(光标停留在文本框上)
nameField.setFocus(true);
// 让文本框的文本处于全选状态
nameField.selectAll();
// Create the popup dialog box
// 创建弹出对话框
//创建一个不关闭,不能操作页面其他元素的对话框
final DialogBox dialogBox = new DialogBox();
//为对话框标题赋值
dialogBox.setText("Remote Procedure Call[远端程序呼叫]");
//添加对话框弹出动画效果
dialogBox.setAnimationEnabled(true);
//添加一个关闭按钮
final Button closeButton = new Button("Close");//[关闭]
// We can set the id of a widget by accessing its Element
// 我们可以通过访问它的元素的一个部件的ID
// 获取一个处理对象的底层DOM元素。
closeButton.getElement().setId("closeButton");
//显示当前服务器标签
final Label textToServerLabel = new Label();
//HTML 是 一个小部件,它可以包含任意的HTML。这个小工具使用<div>元素,使其与块布局显示。
final HTML serverResponseLabel = new HTML();
//VerticalPanel 是一个面板,作为一个单一的垂直列的基础部件,它的所有部件。【所有其他部件都放在他的上面】
VerticalPanel dialogVPanel = new VerticalPanel();
//为版面上添加 固定的版面样式 其他样式 详细见API
dialogVPanel.addStyleName("dialogVPanel");
//在版面上输出一个HTML文本 文字内容加粗
dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
//为版面上添加 label标签
dialogVPanel.add(textToServerLabel);
//同上
dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
//为版面上添加 HTML小部件
dialogVPanel.add(serverResponseLabel);
//为版面指定布局方式为 ALIGN_RIGHT 向右靠齐
//setHorizontalAlignment 方法设置的默认水平对齐方式添加到本小组的部件。它仅适用于添加后,设置此属性的部件
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
//为版面 添加关闭按钮
dialogVPanel.add(closeButton);
//对话框弹出的时候清空版面
dialogBox.setWidget(dialogVPanel);
// Add a handler to close the DialogBox
// / /添加[或者理解为绑定]一个处理程序【或者理解为事件】来关闭DialogBox [类似Extjs的事件绑定原理]
closeButton.addClickHandler(new ClickHandler() {
//添加一个用户单击鼠标左键的事件 【Click】触发时调用。
public void onClick(ClickEvent event) {
//隐藏对话框
dialogBox.hide();
//让发送按钮 为激活状态
sendButton.setEnabled(true);
//让发送按钮获得焦点
sendButton.setFocus(true);
}
});
// Create a handler for the sendButton and nameField
// 为sendButton和nameField创建一个处理程序【其实就是创建一个AJAX应用,当你点击的时候,或者键盘弹起的时候动态加载内容】
// 创建一个 受保护的 内部类 名字为【我的处理器】 他继承了ClickHandler【本地的单击事件】, KeyUpHandler 【代表了本地的KeyUp事件,按键抬起时候执行】
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired【翻译为调用最合适】 when the user clicks on the sendButton.
* 当用户点击上面的sendButton时候调用。
* ClickEvent=代表了本地的Click事件。
* 继承于 ClickHandler类
*/
public void onClick(ClickEvent event) {
//从nameField发送 内容 到 服务器,并等待响应。
sendNameToServer();
}
/**
* Fired when the user types in the nameField.
* 当用户在nameField文本框按键抬起的时候触发。
* 继承于 ClickHandler类
*/
public void onKeyUp(KeyUpEvent event) {
// 如果按键是回车键 就做里面的提交操作 //KEY_ENTER = 13 [0xd]
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
//从nameField发送 内容 到 服务器,并等待响应。
sendNameToServer();
}
}
/**
* Send the name from the nameField to the server and wait for a response.
* 从nameField发送服务器的名称,并等待响应。
*/
private void sendNameToServer() {
// First, we validate the input.
// / /首先,我们验证输入。
errorLabel.setText("");
//发送到服务器的文本 =文本框输入的文本
String textToServer = nameField.getText();
//FieldVerifier验证用户输入的名称是有效的。如果验证通过返回true,失败返回false isValidName方法 参数为需要验证的对象名称
// public static boolean isValidName(String name) {
// if (name == null) {
// return false;
// }
// return name.length() > 3;
// }
//从上面的方法可以看出这里的验证来源于 FieldVerifier类的静态方法 验证输入的文本必须长度至少是4个字符
// 在这个例子中,我们只需要该名称是至少4个字符。在您的应用程序,您可以使用更复杂的检查,
// 以确保该用户名,密码,电子邮件地址,网址,以及其他领域有正确的语法。
if (!FieldVerifier.isValidName(textToServer)) {
//在先前创建的错误提示 lable上面打印错误提示
errorLabel.setText("Please enter at least four characters[请输入至少4个字符]");
return;
}
// Then, we send the input to the server.
// / /然后,我们发送输入到服务器。
//通俗的理解为点击按钮后即将执行发送到服务器的操作,逻辑上应该让发送按钮处于禁用状态【灰色不可用状态】
sendButton.setEnabled(false);
//在提交到服务器的文本标签上面添加textToServer文本内容
textToServerLabel.setText(textToServer);
//清空serverResponseLabel 【HTML】组件的内容
serverResponseLabel.setText("");
//因为AsyncCallback是一个接口所以需要new一下 new了就实现了这个接口 以下是接口里面的 方法
greetingService.greetServer(textToServer, new AsyncCallback<String>() {
//失败时执行
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
// / /显示RPC错误讯息给使用者
//弹出一个对话框提示
dialogBox.setText("Remote Procedure Call - Failure 【远端无响应】");
// 为serverResponseLabel添加写好的错误样式
serverResponseLabel.addStyleName("serverResponseLabelError");
//添加捕获的错误提示
serverResponseLabel.setHTML(SERVER_ERROR);
//在浏览器中心窗口弹出,并显示它。如果在已经显示的组件中弹出,则在组件的中心弹出窗口。
dialogBox.center();
//使错误提示的关闭按钮获得焦点
closeButton.setFocus(true);
}
//成功时执行 翻译同上
public void onSuccess(String result) {
dialogBox.setText("Remote Procedure Call[远端呼叫中]");
serverResponseLabel.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(result);
dialogBox.center();
closeButton.setFocus(true);
}
});
//通俗理解为 成功就返回想得到的东西,失败就抛出异常,让异常处理捕获
}
}
// Add a handler to send the name to the server
// / /添加一个处理程序发送到服务器的名称
//实例化一个处理器
MyHandler handler = new MyHandler();
//为提交按钮绑定这个处理器
sendButton.addClickHandler(handler);
//为输入框绑定这个处理器
nameField.addKeyUpHandler(handler);
}
}