分類: 程式設計

StockWatcher:Google Web Toolkit(GWT) 入門 (二)

StockWatcher -- Google Web Toolkit(GWT) 入門 (一) 中我們已經建立了基本的 StockWatcher 專案,接下來要開始建立使用者介面。

選取 GWT widgets 實做使用者介面

首先瀏覽 Widget Gallery 選擇網頁中所需要的使用者介面元件。

在 Widget Gallery 中選擇使用者介面元件時,暫時不必考慮其樣式,現在只需要考慮其功能,隨後會使用 CSS 讓設計者自訂樣式。

Stock 資料表格(Data Table)

GWT 提供了一個特別的元件 FlexTable,它會依照使用者的要求產生表格的欄位,因為我們不曉得使用者會加入多少 stock 的資料,所以使用 FlexTable,當使用者新增或刪除 stock 資料時,FlexTable 會自動將表格擴充或刪減。

FlexTable

按鈕(Buttons)

GWT 會盡可能的使用瀏覽器本身內建的元件來建立使用者介面,例如按鈕(Button)元件就會使用 <button> 來實做,而不使用 <div>
另外創造一個新的按鈕,這樣的好處是可以提供一個使用者熟悉的界面,並且在執行效率上也會比較好。

Button

Input Box

GWT 提供了幾個可以讓使用者輸入資料的元件:

  • TextBox:單行的文字輸入區域。
  • PassWordTextBox:一個隱藏輸入字元的 TextBox,主要用於輸入密碼。
  • TextArea:多行的文字輸入區域。
  • SuggestBox:一個可以顯示選項的文字區域。
TextBox
PassWordTextBox
TextArea
SuggestBox

StockWatcher 中使用者會需要輸入 stock code,因此需要加入一個 TextBox。

標籤(Label)

GWT 的 Label 元件式直接使用 <div> 實做的,其實做的方式是:

<div class="gwt-Label">Last update : Oct 1, 2008 1:31:48 PM</div>

選擇 Panel 排版使用者介面元件

現在我們已經決定好要使用哪些元件了,接下來要使用 panel 將這些元件排版在網頁上。

Horizontal Panel

Horizontal Panel 可以將元件以水平並排的方式呈現,這裡我們使用此 panel 將輸入的 TextBox 與 Add Button 並排。

Vertical Panel

Virttical Panel 可以將元件以垂直並排的方式呈現,這裡用於除了輸入的 TextBox 與 Add Button 以外的元件。

Root Panel

在 GWT 中有一個隱藏的 root panel,所有在網頁中的動態原件都放在這個 panel 中,它是最上層的 panel,要使用 root panel 有兩種方式,一種是產生整個網頁 body:

RootPanel.get();  // Default. Wraps the HTML body element.

另一種是產生特定的網頁元件內嵌至網頁 body 中:

RootPanel.get("stockList");  // Wraps any HTML element with an id of "stockList"

一個 host page 可以包含多個 root panels,例如將多個 GWT 元件內嵌至一個 host page 中,每個 GWT 元件都各自獨立,並且將其 root panel 內嵌至一個 host page 之中。

將應用程式內嵌至 Host Page

要讓我們開發的應用程式在網頁上運作,必須先將其內嵌至網頁中,也就是 host page,這裡的 host page 就是 StockWatcher.html,預設上 host page 的 body 是空的,也就是說 root panel 會產生所有 body 的內容,包含 input box、文字標籤(“Please enter your name:”) 與 Send 按鈕,若是您的應用程式沒有任何靜態的元件,則您可以不需要更動 host page 的內容。

但是在 StockWatcher 中有一些靜態元件,例如一些 header 文字、圖片等,與其他的動態元件,靜態元件可以直接加進 host page 中;而動態的元件則是使用 placeholder 的方式加入:在網頁中加入一個 <div> 元件,將其 id 設為 “stockList”,這樣的方式可以很方便的將 GWT 程式內嵌至其他的網頁中。

接下來示範詳細的使用方式與程式碼:

  1. 將 war 中的 StockWatcher.html 打開。
  2. 在 head 中更改 title 的內容,設成 StockWatcher。
  3. 在 body 中更改 <h1> 內容,設為 StockWatcher。
  4. 在 body 中增加一個 <div> 元件,並將 id 設為 “stockList”。
  5. 刪除其餘不必要的部分。
  6. 儲存 tockWatcher.html。

更改好的程式碼如下(不含註解):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="StockWatcher.css">
    <title>StockWatcher</title>
    <script type="text/javascript" language="javascript" src="stockwatcher/stockwatcher.nocache.js"></script>
  </head>
  <body>
    <h1>StockWatcher</h1>
    <div id="stockList"></div>
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
    <noscript>
      <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
        Your web browser must have JavaScript enabled
        in order for this application to display correctly.
      </div>
    </noscript>
  </body>
</html>

實做元件與 Panel

接下來我們會使用 GWT 元件與 panel 實做使用用者介面。

若是您希望使用者介面在網頁一開始載入時就顯示,則必須將程式碼寫在 onModuleLoad 方法中。

建立元件與 panel

開啟 com.google.gwt.sample.stockWatcher.client 中的 StockWatcher.java,將其內容以下面的程式取代:

package com.google.gwt.sample.stockwatcher.client;

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() {
    // TODO Create table for stock data.
    // TODO Assemble Add Stock panel.
    // TODO Assemble Main panel.
    // TODO Associate the Main panel with the HTML host page.
    // TODO Move cursor focus to the input box.

  }

}

在 Eclipse 中程式碼的左邊應該會出現一些錯誤警告,這是因為這些類別還沒有定義。

點選左邊第一個錯誤圖示,選擇 Import EntryPoint (com.google.gwt.core.client.EntryPoint)。其餘的錯誤圖示也是使用類似的方式處理。處理完成後,上方會多出一些 import 的程式碼:

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.core.client.EntryPoint; // Added by Eclipse
import com.google.gwt.user.client.ui.Button; // Added by Eclipse
import com.google.gwt.user.client.ui.FlexTable; // Added by Eclipse
import com.google.gwt.user.client.ui.HorizontalPanel; // Added by Eclipse
import com.google.gwt.user.client.ui.Label; // Added by Eclipse
import com.google.gwt.user.client.ui.TextBox; // Added by Eclipse
import com.google.gwt.user.client.ui.VerticalPanel; // Added by Eclipse

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() {
    // TODO Create table for stock data.
    // TODO Assemble Add Stock panel.
    // TODO Assemble Main panel.
    // TODO Associate the Main panel with the HTML host page.
    // TODO Move cursor focus to the input box.

  }

}

建立 stock 資料表

增加一個可以存放 stock 的資料的 Table。使用 setText() 方法設定 table 的標題列:

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.core.client.EntryPoint;
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.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(00"Symbol"); // Added
    stocksFlexTable.setText(01"Price");  // Added
    stocksFlexTable.setText(02"Change"); // Added
    stocksFlexTable.setText(03"Remove"); // Added

    // TODO Assemble Add Stock panel.
    // TODO Assemble Main panel.
    // TODO Associate the Main panel with the HTML host page.
    // TODO Move cursor focus to the input box.

  }

}

要加入新的資料到表格中可以使用 setText() 方法,第一個參數是列,第二個參數是行,第三個參數則是要加入的資料。

元件排版

接下來將組合兩個 panel 與各種元件:

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.core.client.EntryPoint;
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.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(00"Symbol");
    stocksFlexTable.setText(01"Price");
    stocksFlexTable.setText(02"Change");
    stocksFlexTable.setText(03"Remove");

    // Assemble Add Stock panel.
    addPanel.add(newSymbolTextBox); // Added
    addPanel.add(addStockButton); // Added

    // Assemble Main panel.
    mainPanel.add(stocksFlexTable); // Added
    mainPanel.add(addPanel); // Added
    mainPanel.add(lastUpdatedLabel); // Added

    // TODO Associate the Main panel with the HTML host page.
    // TODO Move cursor focus to the input box.

  }

}

結合 Root Panel

mainPanel 放進 root panel 中,並設定 focus 在 newSymboxTextBox 中。

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.core.client.EntryPoint;
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; // Added
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(00"Symbol");
    stocksFlexTable.setText(01"Price");
    stocksFlexTable.setText(02"Change");
    stocksFlexTable.setText(03"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); // Added

    // TODO Move cursor focus to the input box.
    newSymbolTextBox.setFocus(true); // Added
  }

}

測試排版

  1. 將 StockWatcher.java 存檔。
  2. 若您的 StockWatcher 程式還在執行,請先將其停止:在 Eclipse 下方籤頁上有一個紅色的方塊按鈕,按下去就可以停止。
  3. 以 development mode 執行:在專案上點選右鍵選擇 Debug As > Web Application 執行。
  4. 瀏覽器中應該可以看到目前排版的結果。
  5. 讓 StockWatcher 繼續保持在 development mode 狀態執行,接下來我們會在 development mode 直接修改程式並察看修改結果。

在 development mode 中當更動程式碼之後,只需要重新整理網頁即可看到最新的結果,通常不必重新執行應用程式。

繼續閱讀:StockWatcher:Google Web Toolkit(GWT) 入門 (三)

G. T. Wang

個人使用 Linux 經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。

Share
Published by
G. T. Wang

Recent Posts

光陽 KYMCO GP 125 機車接電發動、更換電瓶記錄

本篇記錄我的光陽 KYMCO ...

2 年 ago

[開箱] YubiKey 5C NFC 實體金鑰

本篇是 YubiKey 5C ...

2 年 ago

[DIY] 自製竹火把

本篇記錄我拿竹子加上過期的苦茶...

3 年 ago