欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Google App Engine for Java: 第 2 部分:構建殺手級應用程序



級別: 初級

Richard Hightower, 首席技術(shù)官, Mammatus Inc.

2009 年 8 月 31 日

諸 如 Google App Engine for Java? 這樣的云平臺的關(guān)鍵在于能夠設計、構建和部署專(zhuān)業(yè)級的應用程序 —— 可以非常容易地進(jìn)行伸縮。在這個(gè)包含三部分的 Google App Engine for Java 系列文章第二篇中,Rick Hightower 將通過(guò)一個(gè)分步指南,使用 Google App Engine for Java 來(lái)編寫(xiě)和部署一個(gè)簡(jiǎn)單的聯(lián)系人管理應用程序,從而超越 第 1 部分 中提供的現成示例。

在介紹使用 App Engine for Java 構建可伸縮 Java 應用程序的 第 1 部分 中,您了解了 Google 云計算平臺(即 PAAS)為 Java 開(kāi)發(fā)人員提供的 Eclipse 工具和基礎設施。該文章中的示例都是預先準備的,這樣您可以將精力集中到 App Engine for Java 與 Eclipse 的集成中,并快速構建和部署不同類(lèi)型的應用程序 — 即使用 Google Web Toolkit (GWT) 構建的應用程序和基于 servlet 的應用程序。本文將在此基礎上展開(kāi),并且在本系列第 3 部分中提供了更加高級的編程實(shí)踐。

您將構建的聯(lián)系人管理應用程序允許用戶(hù)存儲基本的聯(lián)系人信息,比如名稱(chēng)、電子郵件地址和電話(huà)號碼。要創(chuàng )建這個(gè)應用程序,將需要使用 Eclipse GWT 項目創(chuàng )建向導。

云計算空間

您是否希望隨時(shí)獲取最新的云計算消息?是否想得到云計算相關(guān)的技術(shù)知識?developerWorks 云計算空間就是這樣一個(gè)云計算信息資源的門(mén)戶(hù),在這里您可以了解來(lái)自 IBM 和業(yè)界其他媒體的最新信息,并且得到如何在云環(huán)境中使用 IBM 軟件的入門(mén)知識。

IBM 在 Amazon EC2 云計算環(huán)境中提供了 DB2、Informix、Lotus、WebSphere 等方面的 AMI 鏡像資源。您只需按使用量支付少量費用,就可以使用到云上的數據、門(mén)戶(hù)、Web 內容管理、情景應用等服務(wù)。歡迎您隨時(shí)訪(fǎng)問(wèn) 云計算空間,獲取更多信息。

從 CRUD 到聯(lián)系人應用程序

正如目前您已經(jīng)了解到的一樣,在 App Engine for Java 中構建新應用程序的第一步就是在 Eclipse 啟動(dòng)項目創(chuàng )建向導。之后,您可以打開(kāi) GWT 項目啟動(dòng)向導來(lái)創(chuàng )建 GWT 項目(本文 第 1 部分 給出了在 App Engine for Java 中創(chuàng )建 GWT 項目的詳細說(shuō)明)。

對于這個(gè)練習,您將啟動(dòng)一個(gè)簡(jiǎn)單的 CRUD 應用程序,并稍后添加實(shí)際的存儲。我們將使用一個(gè)具有模擬實(shí)現的數據訪(fǎng)問(wèn)對象(DAO),如清單 1 所示:


清單 1. ContactDAO 接口
                    package gaej.example.contact.server;                    import java.util.List;                    import gaej.example.contact.client.Contact;                    public interface ContactDAO {                    void addContact(Contact contact);                    void removeContact(Contact contact);                    void updateContact(Contact contact);                    List<Contact> listContacts();                    }                    

ContactDAO 添加了各種方法,可以添加聯(lián)系人、刪除聯(lián)系人、更新聯(lián)系人,并返回一個(gè)所有聯(lián)系人的列表。它是一個(gè)非?;镜?CRUD 接口,可以管理聯(lián)系人。Contact 類(lèi)是您的域對象,如清單 2 所示:


清單 2. 聯(lián)系人域對象(gaej.example.contact.client.Contact)
                    package gaej.example.contact.client;                    import java.io.Serializable;                    public class Contact implements Serializable {                    private static final long serialVersionUID = 1L;                    private String name;                    private String email;                    private String phone;                    public Contact() {                    }                    public Contact(String name, String email, String phone) {                    super();                    this.name = name;                    this.email = email;                    this.phone = phone;                    }                    public String getName() {                    return name;                    }                    public void setName(String name) {                    this.name = name;                    }                    public String getEmail() {                    return email;                    }                    public void setEmail(String email) {                    this.email = email;                    }                    public String getPhone() {                    return phone;                    }                    public void setPhone(String phone) {                    this.phone = phone;                    }                    }                    

對于這個(gè)應用程序的第一個(gè)版本,您將使用一個(gè)模擬對象將聯(lián)系人存儲在一個(gè)內存集合中,如清單 3 所示:


清單 3. Mock DAO 類(lèi)
                    package gaej.example.contact.server;                    import gaej.example.contact.client.Contact;                    import java.util.ArrayList;                    import java.util.Collections;                    import java.util.LinkedHashMap;                    import java.util.List;                    import java.util.Map;                    public class ContactDAOMock implements ContactDAO {                    Map<String, Contact> map = new LinkedHashMap<String, Contact>();                    {                    map.put("rhightower@mammatus.com",                    new Contact("Rick Hightower", "rhightower@mammatus.com", "520-555-1212"));                    map.put("scott@mammatus.com",                    new Contact("Scott Fauerbach", "scott@mammatus.com", "520-555-1213"));                    map.put("bob@mammatus.com",                    new Contact("Bob Dean", "bob@mammatus.com", "520-555-1214"));                    }                    public void addContact(Contact contact) {                    String email = contact.getEmail();                    map.put(email, contact);                    }                    public List<Contact> listContacts() {                    return Collections.unmodifiableList(new ArrayList<Contact>(map.values()));                    }                    public void removeContact(Contact contact) {                    map.remove(contact.getEmail());                    }                    public void updateContact(Contact contact) {                    map.put(contact.getEmail(), contact);                    }                    }                    

創(chuàng )建遠程服務(wù)

您現在的目標是創(chuàng )建一個(gè)允許您使用 DAO 的 GWT GUI。將使用 ContactDAO 接口上的所有方法。第一步是將 DAP 類(lèi)(未來(lái)版本將直接與服務(wù)器端的數據存儲通信,因此必須位于服務(wù)器中)的功能封裝到一個(gè)服務(wù)中,如清單 4 所示:


清單 4. ContactServiceImpl
                    package gaej.example.contact.server;                    import java.util.ArrayList;                    import java.util.List;                    import gaej.example.contact.client.Contact;                    import gaej.example.contact.client.ContactService;                    import com.google.gwt.user.server.rpc.RemoteServiceServlet;                    public class ContactServiceImpl extends RemoteServiceServlet implements ContactService {                    private static final long serialVersionUID = 1L;                    private ContactDAO contactDAO = new ContactDAOMock();                    public void addContact(Contact contact) {                    contactDAO.addContact(contact);                    }                    public List<Contact> listContacts() {                    List<Contact> listContacts = contactDAO.listContacts();                    return new ArrayList<Contact> (listContacts);                    }                    public void removeContact(Contact contact) {                    contactDAO.removeContact(contact);                    }                    public void updateContact(Contact contact) {                    contactDAO.updateContact(contact);                    }                    }                    

注意,ContactServiceImpl 實(shí)現了 RemoteServiceServlet,隨后定義方法來(lái)添加聯(lián)系人、列出聯(lián)系人、刪除聯(lián)系人,以及更新聯(lián)系人。它將所有這些操作委托給 ContactDAOMock。ContactServiceImpl 不過(guò)是一個(gè)圍繞 ContactDAO 的包裝器,后者將 ContactDAO 功能公開(kāi)給 GWT GUI。ContactServiceImpl 在 web.xml 文件中被映射到 URI /contactlist/contacts,如清單 5 所示:


清單 5. web.xml 中的 ContactService
                    <servlet>                    <servlet-name>contacts</servlet-name>                    <servlet-class>gaej.example.contact.server.ContactServiceImpl</servlet-class>                    </servlet>                    <servlet-mapping>                    <servlet-name>contacts</servlet-name>                    <url-pattern>/contactlist/contacts</url-pattern>                    </servlet-mapping>                    

要使 GUI 前端訪(fǎng)問(wèn)該服務(wù),需要定義一個(gè)遠程服務(wù)接口和一個(gè)異步遠程服務(wù)接口,如清單 6 和 7 所示:


清單 6. ContactService
                    package gaej.example.contact.client;                    import java.util.List;                    import com.google.gwt.user.client.rpc.RemoteService;                    import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;                    @RemoteServiceRelativePath("contacts")                    public interface ContactService extends RemoteService {                    List<Contact> listContacts();                    void addContact(Contact contact);                    void removeContact(Contact contact);                    void updateContact(Contact contact);                    }                    


清單 7. ContactServiceAsync
                    package gaej.example.contact.client;                    import java.util.List;                    import com.google.gwt.user.client.rpc.AsyncCallback;                    public interface ContactServiceAsync  {                    void listContacts(AsyncCallback<List <Contact>> callback);                    void addContact(Contact contact, AsyncCallback<Void> callback);                    void removeContact(Contact contact, AsyncCallback<Void> callback);                    void updateContact(Contact contact, AsyncCallback<Void> callback);                    }                    

注意,ContactService 實(shí)現了 RemoteService 接口并定義了一個(gè) @RemoteServiceRelativePath,指定了 “聯(lián)系人” 的相對路徑。相對路徑與您在 web.xml 文件中為服務(wù)定義的路徑是對應的(必須匹配)。ContactServiceAsync 包含回調對象,因此 GWT GUI 可以收到來(lái)自服務(wù)器的調用的通知,而不會(huì )阻塞其他客戶(hù)機行為。

避免編寫(xiě)雜亂的代碼

我 并不喜歡編寫(xiě)雜亂的代碼,因此在可能的情況下會(huì )盡量避免編寫(xiě)這類(lèi)代碼。這類(lèi)代碼的一個(gè)例子就是一組匿名內部類(lèi),這些類(lèi)的方法定義匿名內部類(lèi)。這些內部類(lèi)反 過(guò)來(lái)執行回調,調用在某個(gè)內部類(lèi)中以?xún)嚷?lián)方式定義的方法。坦白說(shuō),我無(wú)法閱讀或是理解這些糾纏在一起的代碼,即使是我自己編寫(xiě)的!因此,為了將代碼稍微簡(jiǎn) 單化,我建議將 GWT GUI 分解為三個(gè)部分:

  • ContactListEntryPoint
  • ContactServiceDelegate
  • ContactListGUI

ContactListEntryPoint 是主要的入口點(diǎn);它執行 GUI 事件連接。ContactServiceDelegate 封裝 ContactService 功能并隱藏內部類(lèi)回調連接。ContactListGUI 管理所有 GUI 組件并處理來(lái)自 GUIService 的事件。ContactListGUI 使用 ContactServiceDelegate 發(fā)出 ContactService 請求。

ContactList.gwt.xml 文件(位于 gaej.example.contact 下的一個(gè)資源)使用 entry-point 元素將 ContactListEntryPoint 指定為應用程序的主要入口點(diǎn),如清單 8 所示:


清單 8. ContactList.gwt.xml
                    <entry-point class='gaej.example.contact.client.ContactListEntryPoint'/>                    

ContactListEntryPoint 類(lèi)實(shí)現了 GWT 的 EntryPoint 接口(com.google.gwt.core.client.EntryPoint),并指定將調用該類(lèi)來(lái)初始化 GUI。ContactListEntryPoint 所做的工作并不多。它創(chuàng )建一個(gè) ContactListGUI 實(shí)例和一個(gè) ContactServiceDelegate 實(shí)例,然后讓它們彼此了解對方,這樣就可以展開(kāi)協(xié)作。ContactListEntryPoint 然后執行 GUI 事件連接。ContactListEntryPoint 如清單 9 所示:


清單 9. ContactListEntryPoint
                    package gaej.example.contact.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.HTMLTable.Cell;                    /**                    * Entry point classes define onModuleLoad().                    */                    public class ContactListEntryPoint implements EntryPoint {                    private ContactListGUI gui;                    private ContactServiceDelegate delegate;                    /**                    * This is the entry point method.                    */                    public void onModuleLoad() {                    gui = new ContactListGUI();                    delegate = new ContactServiceDelegate();                    gui.contactService = delegate;                    delegate.gui = gui;                    gui.init();                    delegate.listContacts();                    wireGUIEvents();                    }                    private void wireGUIEvents() {                    gui.contactGrid.addClickHandler(new ClickHandler(){                    public void onClick(ClickEvent event) {                    Cell cellForEvent = gui.contactGrid.getCellForEvent(event);                    gui.gui_eventContactGridClicked(cellForEvent);                    }});                    gui.addButton.addClickHandler(new ClickHandler(){                    public void onClick(ClickEvent event) {                    gui.gui_eventAddButtonClicked();                    }});                    gui.updateButton.addClickHandler(new ClickHandler(){                    public void onClick(ClickEvent event) {                    gui.gui_eventUpdateButtonClicked();                    }});                    gui.addNewButton.addClickHandler(new ClickHandler(){                    public void onClick(ClickEvent event) {                    gui.gui_eventAddNewButtonClicked();                    }});                    }                    }                    

注意,ContactListEntryPointaddButton、updateButton、contactGridaddNewButton 連接事件。具體做法是注冊為小部件事件實(shí)現偵聽(tīng)器接口的匿名內部類(lèi)。這與 Swing 中的事件處理非常相似。這些小部件事件來(lái)自由 GUI 創(chuàng )建的小部件(ContactListGUI),我將稍后進(jìn)行討論。注意,GUI 類(lèi)包含 gui_eventXXX 方法來(lái)響應 GUI 事件。

ContactListGUI 創(chuàng )建了 GUI 小部件并響應來(lái)自它們的事件。ContactListGUI 將 GUI 事件轉換為用戶(hù)希望對 ContactsService 執行的操作。ContactListGUI 使用 ContactServiceDelegateContactService 調用方法。ContactServiceDelegateContactService 創(chuàng )建一個(gè)異步接口并使用它發(fā)出異步 Ajax 調用。ContactServiceDelegateContactListGUI 通知來(lái)自服務(wù)的事件(成功或失?。?。ContactServiceDelegate 如清單 10 所示:


清單 10. ContactServiceDelegatepackage gaej.example.contact.client;
                    import java.util.List;                    import com.google.gwt.core.client.GWT;                    import com.google.gwt.user.client.rpc.AsyncCallback;                    public class ContactServiceDelegate {                    private ContactServiceAsync contactService = GWT.create(ContactService.class);                    ContactListGUI gui;                    void listContacts() {                    contactService.listContacts(new AsyncCallback<List<Contact>> () {                    public void onFailure(Throwable caught) {                    gui.service_eventListContactsFailed(caught);                    }                    public void onSuccess(List<Contact> result) {                    gui.service_eventListRetrievedFromService(result);                    }                    }//end of inner class                    );//end of listContacts method call.                    }                    void addContact(final Contact contact) {                    contactService.addContact(contact, new AsyncCallback<Void> () {                    public void onFailure(Throwable caught) {                    gui.service_eventAddContactFailed(caught);                    }                    public void onSuccess(Void result) {                    gui.service_eventAddContactSuccessful();                    }                    }//end of inner class                    );//end of addContact method call.                    }                    void updateContact(final Contact contact) {                    contactService.updateContact(contact, new AsyncCallback<Void> () {                    public void onFailure(Throwable caught) {                    gui.service_eventUpdateContactFailed(caught);                    }                    public void onSuccess(Void result) {                    gui.service_eventUpdateSuccessful();                    }                    }//end of inner class                    );//end of updateContact method call.                    }                    void removeContact(final Contact contact) {                    contactService.removeContact(contact, new AsyncCallback<Void> () {                    public void onFailure(Throwable caught) {                    gui.service_eventRemoveContactFailed(caught);                    }                    public void onSuccess(Void result) {                    gui.service_eventRemoveContactSuccessful();                    }                    }//end of inner class                    );//end of updateContact method call.                    }                    }                    

注意,ContactServiceDelegate 通過(guò)以 service_eventXXX 開(kāi)頭的方法向 ContactListGUI 發(fā)出有關(guān)服務(wù)事件的通知。如前所述,我編寫(xiě) ContactListGUI 的目標之一就是避免嵌套的內部類(lèi)并創(chuàng )建一個(gè)相對扁平的 GUI 類(lèi)(我可以非常方便地閱讀和理解的類(lèi))。ContactListGUI 只有 186 行,因此非常簡(jiǎn)單。ContactListGUI 管理 9 個(gè) GUI 小部件并與 ContactServiceDelegate 協(xié)作來(lái)管理一個(gè) CRUD 清單,如清單 11 所示:


清單 11. ContactListGUI 的實(shí)際使用
                    package gaej.example.contact.client;                    import java.util.List;                    import com.google.gwt.user.client.ui.Button;                    import com.google.gwt.user.client.ui.Grid;                    import com.google.gwt.user.client.ui.Hyperlink;                    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.HTMLTable.Cell;                    public class ContactListGUI {                    /* Constants. */                    private static final String CONTACT_LISTING_ROOT_PANEL = "contactListing";                    private static final String CONTACT_FORM_ROOT_PANEL = "contactForm";                    private static final String CONTACT_STATUS_ROOT_PANEL = "contactStatus";                    private static final String CONTACT_TOOL_BAR_ROOT_PANEL = "contactToolBar";                    private static final int EDIT_LINK = 3;                    private static final int REMOVE_LINK = 4;                    /* GUI Widgets */                    protected Button addButton;                    protected Button updateButton;                    protected Button addNewButton;                    protected TextBox nameField;                    protected TextBox emailField;                    protected TextBox phoneField;                    protected Label status;                    protected Grid contactGrid;                    protected Grid formGrid;                    /* Data model */                    private List<Contact> contacts;                    private Contact currentContact;                    protected ContactServiceDelegate contactService;                    

注意,ContactListGUI 跟蹤表單中加載的當前聯(lián)系人(currentContact)和清單中的聯(lián)系人列表(contacts)。圖 1 展示了小部件如何對應于創(chuàng )建的 GUI:


圖 1. 聯(lián)系人管理 GUI 中活動(dòng)的小部件

清單 12 展示了 ContactListGUI 如何創(chuàng )建小部件和聯(lián)系人表單,并將小部件放到表單中:


清單 12. ContactListGUI 創(chuàng )建并放置小部件
                    public class ContactListGUI {                    /* Constants. */                    private static final String CONTACT_LISTING_ROOT_PANEL = "contactListing";                    private static final String CONTACT_FORM_ROOT_PANEL = "contactForm";                    private static final String CONTACT_STATUS_ROOT_PANEL = "contactStatus";                    private static final String CONTACT_TOOL_BAR_ROOT_PANEL = "contactToolBar";                    ...                    public void init() {                    addButton = new Button("Add new contact");                    addNewButton = new Button("Add new contact");                    updateButton = new Button("Update contact");                    nameField = new TextBox();                    emailField = new TextBox();                    phoneField = new TextBox();                    status = new Label();                    contactGrid = new Grid(2,5);                    buildForm();                    placeWidgets();                    }                    private void buildForm() {                    formGrid = new Grid(4,3);                    formGrid.setVisible(false);                    formGrid.setWidget(0, 0, new Label("Name"));                    formGrid.setWidget(0, 1, nameField);                    formGrid.setWidget(1, 0, new Label("email"));                    formGrid.setWidget(1, 1, emailField);                    formGrid.setWidget(2, 0, new Label("phone"));                    formGrid.setWidget(2, 1, phoneField);                    formGrid.setWidget(3, 0, updateButton);                    formGrid.setWidget(3, 1, addButton);                    }                    private void placeWidgets() {                    RootPanel.get(CONTACT_LISTING_ROOT_PANEL).add(contactGrid);                    RootPanel.get(CONTACT_FORM_ROOT_PANEL).add(formGrid);                    RootPanel.get(CONTACT_STATUS_ROOT_PANEL).add(status);                    RootPanel.get(CONTACT_TOOL_BAR_ROOT_PANEL).add(addNewButton);                    }                    

ContactListGUI init 方法由 ContactListEntryPoint.onModuleLoad 方法創(chuàng )建。init 方法調用 buildForm 方法來(lái)創(chuàng )建新的表單網(wǎng)格并使用字段填充,以編輯聯(lián)系人數據。init 方法隨后調用 placeWidgets 方法,隨后將 contactGrid、formGrid、statusaddNewButton 小部件放到 HTML 頁(yè)面中定義的插槽中,這個(gè) HTML 頁(yè)面托管了清單 13 中定義的 GUI 應用程序:


清單 13. ContactList.html 定義了用于小部件的插槽
                    <h1>Contact List Example</h1>                    <table align="center">                    <tr>                    <td id="contactStatus"></td> <td id="contactToolBar"></td>                    </tr>                    <tr>                    <td id="contactForm"></td>                    </tr>                    <tr>                    <td id="contactListing"></td>                    </tr>                    </table>                    

常量(比如 CONTACT_LISTING_ROOT_PANEL="contactListing")對應于 HTML 頁(yè)面中定義的元素的 ID(類(lèi)似 id="contactListing")。這允許頁(yè)面設計師進(jìn)一步控制應用程序小部件的布局。

對于基本的應用程序構建,讓我們了解幾個(gè)常見(jiàn)的使用場(chǎng)景。

展示一個(gè)有關(guān)頁(yè)面加載的鏈接

當聯(lián)系人管理應用程序的頁(yè)面首次加載時(shí),它將調用 ContactListEntryPointonModuleLoad 方法。onModuleLoad 調用 ContactServiceDelegatelistContacts 方法,后者異步調用服務(wù)的 listContact 方法。當 listContact 方法返回時(shí),ContactServiceDelegate 中定義的匿名內部類(lèi)將調用名為 service_eventListRetrievedFromService 的服務(wù)事件處理器方法,如清單 14 所示:


清單 14. 調用 listContact 事件處理器
                    public class ContactListGUI {                    ...                    public void service_eventListRetrievedFromService(List<Contact> result) {                    status.setText("Retrieved contact list");                    this.contacts = result;                    this.contactGrid.clear();                    this.contactGrid.resizeRows(this.contacts.size());                    int row = 0;                    for (Contact contact : result) {                    this.contactGrid.setWidget(row, 0, new Label(contact.getName()));                    this.contactGrid.setWidget(row, 1, new Label (contact.getPhone()));                    this.contactGrid.setWidget(row, 2, new Label (contact.getEmail()));                    this.contactGrid.setWidget(row, EDIT_LINK, new Hyperlink("Edit", null));                    this.contactGrid.setWidget(row, REMOVE_LINK, new Hyperlink("Remove", null));                    row ++;                    }                    }                    

service_eventListRetrievedFromService 事件處理器方法存儲由服務(wù)器發(fā)送的聯(lián)系人列表。然后它將清空顯示聯(lián)系人列表的 contactGrid。它將重新調整行數,以匹配服務(wù)器返回的聯(lián)系人列表的大小。隨后遍歷聯(lián)系人列表,將每個(gè)聯(lián)系人的姓名、電話(huà)、電子郵件數據放到每一行的前三個(gè)列中。它還為每個(gè)聯(lián)系人提供了 Edit 鏈接和一個(gè) Remove 鏈接,使用戶(hù)能夠輕松地刪除和編輯聯(lián)系人。

用戶(hù)編輯現有的聯(lián)系人

當用戶(hù)單擊聯(lián)系人列表中的 Edit 鏈接時(shí),gui_eventContactGridClicked 將得到調用,如清單 15 所示:


清單 15. ContactListGUI 的 gui_eventContactGridClicked 事件處理器方法
                    public class ContactListGUI {                    ...                    public void gui_eventContactGridClicked(Cell cellClicked) {                    int row = cellClicked.getRowIndex();                    int col = cellClicked.getCellIndex();                    Contact contact = this.contacts.get(row);                    this.status.setText("Name was " + contact.getName() + " clicked ");                    if (col==EDIT_LINK) {                    this.addNewButton.setVisible(false);                    this.updateButton.setVisible(true);                    this.addButton.setVisible(false);                    this.emailField.setReadOnly(true);                    loadForm(contact);                    } else if (col==REMOVE_LINK) {                    this.contactService.removeContact(contact);                    }                    }                    ...                    private void loadForm(Contact contact) {                    this.formGrid.setVisible(true);                    currentContact = contact;                    this.emailField.setText(contact.getEmail());                    this.phoneField.setText(contact.getPhone());                    this.nameField.setText(contact.getName());                    }                    

gui_eventContactGridClicked 方法必須確定 Edit 鏈接或 Remove 鏈接是否被單擊。具體做法是找到那個(gè)列被單擊。隨后隱藏 addNewButtonaddButton,并使 updateButton 可見(jiàn)。updateButton 顯示在 formGrid 中,允許用戶(hù)將更新信息發(fā)送回 ContactService。它還使 emailField 變?yōu)橹蛔x,這樣用戶(hù)就不能編輯電子郵件字段。接下來(lái),gui_eventContactGridClicked 調用 loadForm(如 清單 15 所示),后者將 formGrid 設置為可見(jiàn),設置正在被編輯的聯(lián)系人,然后將聯(lián)系人屬性復制到 emailField、phoneFieldnameField 小部件中。

當用戶(hù)單擊 updateButton 時(shí),gui_eventUpdateButtonClicked 事件處理器方法被調用,如清單 16 所示。這個(gè)方法使 addNewButton 變?yōu)榭梢?jiàn)(這樣用戶(hù)就可以編輯新的聯(lián)系人)并隱藏了 formGrid。它隨后調用 copyFieldDateToContact,后者將來(lái)自 emailField、phoneFieldnameField 小部件的文本復制回 currentContact 的屬性。隨后調用 ContactServiceDelegate updateContact 方法來(lái)將新更新的聯(lián)系人傳遞回服務(wù)。


清單 16. ContactListGUI 的 gui_eventUpdateButtonClicked 事件處理器方法
                    public class ContactListGUI {                    ...                    public void gui_eventUpdateButtonClicked() {                    addNewButton.setVisible(true);                    formGrid.setVisible(false);                    copyFieldDateToContact();                    this.contactService.updateContact(currentContact);                    }                    private void copyFieldDateToContact() {                    currentContact.setEmail(emailField.getText());                    currentContact.setName(nameField.getText());                    currentContact.setPhone(phoneField.getText());                    }                    

這兩個(gè)場(chǎng)景應當使您了解到應用程序是如何工作的,以及它如何依賴(lài)于 App Engine for Java 提供的基礎設施。ContactListGUI 的完整代碼如清單 17 所示:


清單 17. ContactListGUI 的完整代碼
                    package gaej.example.contact.client;                    import java.util.List;                    import com.google.gwt.user.client.ui.Button;                    import com.google.gwt.user.client.ui.Grid;                    import com.google.gwt.user.client.ui.Hyperlink;                    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.HTMLTable.Cell;                    public class ContactListGUI {                    /* Constants. */                    private static final String CONTACT_LISTING_ROOT_PANEL = "contactListing";                    private static final String CONTACT_FORM_ROOT_PANEL = "contactForm";                    private static final String CONTACT_STATUS_ROOT_PANEL = "contactStatus";                    private static final String CONTACT_TOOL_BAR_ROOT_PANEL = "contactToolBar";                    private static final int EDIT_LINK = 3;                    private static final int REMOVE_LINK = 4;                    /* GUI Widgets */                    protected Button addButton;                    protected Button updateButton;                    protected Button addNewButton;                    protected TextBox nameField;                    protected TextBox emailField;                    protected TextBox phoneField;                    protected Label status;                    protected Grid contactGrid;                    protected Grid formGrid;                    /* Data model */                    private List<Contact> contacts;                    private Contact currentContact;                    protected ContactServiceDelegate contactService;                    public void init() {                    addButton = new Button("Add new contact");                    addNewButton = new Button("Add new contact");                    updateButton = new Button("Update contact");                    nameField = new TextBox();                    emailField = new TextBox();                    phoneField = new TextBox();                    status = new Label();                    contactGrid = new Grid(2,5);                    buildForm();                    placeWidgets();                    }                    private void buildForm() {                    formGrid = new Grid(4,3);                    formGrid.setVisible(false);                    formGrid.setWidget(0, 0, new Label("Name"));                    formGrid.setWidget(0, 1, nameField);                    formGrid.setWidget(1, 0, new Label("email"));                    formGrid.setWidget(1, 1, emailField);                    formGrid.setWidget(2, 0, new Label("phone"));                    formGrid.setWidget(2, 1, phoneField);                    formGrid.setWidget(3, 0, updateButton);                    formGrid.setWidget(3, 1, addButton);                    }                    private void placeWidgets() {                    RootPanel.get(CONTACT_LISTING_ROOT_PANEL).add(contactGrid);                    RootPanel.get(CONTACT_FORM_ROOT_PANEL).add(formGrid);                    RootPanel.get(CONTACT_STATUS_ROOT_PANEL).add(status);                    RootPanel.get(CONTACT_TOOL_BAR_ROOT_PANEL).add(addNewButton);                    }                    private void loadForm(Contact contact) {                    this.formGrid.setVisible(true);                    currentContact = contact;                    this.emailField.setText(contact.getEmail());                    this.phoneField.setText(contact.getPhone());                    this.nameField.setText(contact.getName());                    }                    private void copyFieldDateToContact() {                    currentContact.setEmail(emailField.getText());                    currentContact.setName(nameField.getText());                    currentContact.setPhone(phoneField.getText());                    }                    public void gui_eventContactGridClicked(Cell cellClicked) {                    int row = cellClicked.getRowIndex();                    int col = cellClicked.getCellIndex();                    Contact contact = this.contacts.get(row);                    this.status.setText("Name was " + contact.getName() + " clicked ");                    if (col==EDIT_LINK) {                    this.addNewButton.setVisible(false);                    this.updateButton.setVisible(true);                    this.addButton.setVisible(false);                    this.emailField.setReadOnly(true);                    loadForm(contact);                    } else if (col==REMOVE_LINK) {                    this.contactService.removeContact(contact);                    }                    }                    public void gui_eventAddButtonClicked() {                    addNewButton.setVisible(true);                    formGrid.setVisible(false);                    copyFieldDateToContact();                    this.phoneField.getText();                    this.contactService.addContact(currentContact);                    }                    public void gui_eventUpdateButtonClicked() {                    addNewButton.setVisible(true);                    formGrid.setVisible(false);                    copyFieldDateToContact();                    this.contactService.updateContact(currentContact);                    }                    public void gui_eventAddNewButtonClicked() {                    this.addNewButton.setVisible(false);                    this.updateButton.setVisible(false);                    this.addButton.setVisible(true);                    this.emailField.setReadOnly(false);                    loadForm(new Contact());                    }                    public void service_eventListRetrievedFromService(List<Contact> result) {                    status.setText("Retrieved contact list");                    this.contacts = result;                    this.contactGrid.clear();                    this.contactGrid.resizeRows(this.contacts.size());                    int row = 0;                    for (Contact contact : result) {                    this.contactGrid.setWidget(row, 0, new Label(contact.getName()));                    this.contactGrid.setWidget(row, 1, new Label (contact.getPhone()));                    this.contactGrid.setWidget(row, 2, new Label (contact.getEmail()));                    this.contactGrid.setWidget(row, EDIT_LINK, new Hyperlink("Edit", null));                    this.contactGrid.setWidget(row, REMOVE_LINK, new Hyperlink("Remove", null));                    row ++;                    }                    }                    public void service_eventAddContactSuccessful() {                    status.setText("Contact was successfully added");                    this.contactService.listContacts();                    }                    public void service_eventUpdateSuccessful() {                    status.setText("Contact was successfully updated");                    this.contactService.listContacts();                    }                    public void service_eventRemoveContactSuccessful() {                    status.setText("Contact was removed");                    this.contactService.listContacts();                    }                    public void service_eventUpdateContactFailed(Throwable caught) {                    status.setText("Update contact failed");                    }                    public void service_eventAddContactFailed(Throwable caught) {                    status.setText("Unable to update contact");                    }                    public void service_eventRemoveContactFailed(Throwable caught) {                    status.setText("Remove contact failed");                    }                    public void service_eventListContactsFailed(Throwable caught) {                    status.setText("Unable to get contact list");                    }                    }                    





回頁(yè)首


結束語(yǔ)

這 個(gè)共包含三部分的 Google App Engine for Java 系列文章的第二部分向您介紹了如何使用 App Engine for Java 的 Eclipse 插件工具創(chuàng )建定制 GWT 應用程序。在構建簡(jiǎn)單的聯(lián)系人管理應用程序的過(guò)程中,您學(xué)會(huì )了以下內容:

  • 構建可以異步工作的遠程服務(wù)
  • 組織 GUI 代碼以避免嵌套的內部類(lèi)聲明
  • 利用 GWT 為兩個(gè)關(guān)鍵用例實(shí)現功能

敬請期待本文的第 3 部分,您將對聯(lián)系人管理應用程序進(jìn)行優(yōu)化,并通過(guò) App Engine for Java 數據存儲功能添加對持久化 Contact 對象的支持。



參考資料

學(xué)習

獲得產(chǎn)品和技術(shù)

討論


關(guān)于作者

 

Rick Hightower 是 Mammatus Inc. 的首席技術(shù)官,Mammatus Inc. 是一家從事云計算、GWT、Java EE、Spring 和 Hibernate 開(kāi)發(fā)的培訓公司。他是暢銷(xiāo)書(shū) Java Tools for Extreme Programming 的合著(zhù)者,并且撰寫(xiě)了 Struts Live 的第一版 — 該書(shū)多年來(lái)在 TheServerSide.com 上的下載次數一直位列第一。他還為 IBM developerWorks 撰寫(xiě)文章和教程,并且是 Java Developer's Journal 的編委會(huì )的成員,他還經(jīng)常在 DZone 上針對 Java 和 Groovy 主題發(fā)表文章。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
android中使用HTML作布局文件以及調用Javascript
參照GWT文檔實(shí)現的StockWatcher例子,在hosted mode下,定時(shí)作業(yè)無(wú)法...
《GWT揭秘》連載3/4
面向方面編程
跳躍思維:用java開(kāi)發(fā)Ajax - 玩的收件箱 [ norasun‘s blog ] - IT中國吧博客系統---千人工程博客大賽火熱進(jìn)行中
使用G4JSF集成 Google Web Toolkit 和 JSF
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久