Symfoware

Symfowareについての考察blog

Google Web Toolkit 2.1 チュートリアル7 スタイルの適用

Google Web Toolkit 2.1のEclipseプラグインをインストールし、
チュートリアルを試しているところです。
Google Web Toolkit 2.1のEclipseプラグインをインストールする
Google Web Toolkit 2.1 チュートリアル1 GWTプロジェクトの作成
Google Web Toolkit 2.1 チュートリアル2 アプリケーションの設計
Google Web Toolkit 2.1 チュートリアル3 ユーザーインターフェースの作成
Google Web Toolkit 2.1 チュートリアル4 クライアントのイベント制御
Google Web Toolkit 2.1 チュートリアル5 クライアントでの処理実行
Google Web Toolkit 2.1 チュートリアル6 GWTアプリケーションのデバッグ

引き続き、チュートリアルを試します。

Step 7: Apply Style
こちらを参考に進めていきます。




1. Associating Style Sheets with a Project



株価の変動を監視するアプリケーションを作成しましたが、
見た目が若干寂しい感じです。

08_001_20101104234448.png


スタイルシートの適用や、ロゴの貼り付けを行っていい感じに仕上げていきます。


プロジェクト全体のスタイルの指定は、「StockWatcher.gwt.xml」で行います。
Eclipseのパッケージ・エクスプローラーでの場所はここ。

08_002_20101104234448.png


スタイルの指定を行っている箇所はここです。
デフォルトだと、「com.google.gwt.user.theme.standard.Standard」が
指定されていると思います。


    <!-- Inherit the default GWT style sheet. You can change     -->
    <!-- the theme of your GWT application by uncommenting         -->
    <!-- any one of the following lines.                            -->
    <inherits name='com.google.gwt.user.theme.standard.Standard'/>
    <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
    <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->







2. Changing the Theme



現在のスタイルをコメントアウトし、「com.google.gwt.user.theme.dark.Dark」という
スタイルの指定を有効にしてみます。


    <!-- Inherit the default GWT style sheet. You can change     -->
    <!-- the theme of your GWT application by uncommenting         -->
    <!-- any one of the following lines.                            -->
    <!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/>     -->
    <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
    <inherits name='com.google.gwt.user.theme.dark.Dark'/>




ブラウザをリロードしてみると・・・

08_003_20101104234448.png


テーマが変更されました。

StockWatcher.cssが表示用のスタイルシートなのですが、このファイルの
初期値を決定しているのが、StockWatcher.gwt.xmlの上記の箇所です。

また、「com.google.gwt.user.theme.standard.StandardRTL」のように
スタイル名の末尾に「RTL」をつけると、右から左に文字を表現する
国向けのスタイルが適用されます。

以下が「com.google.gwt.user.theme.dark.DarkRTL」を指定したときの例です。

08_004_20101104234445.png




3. Associating style rules with GWT-generated HTML elements



自動生成されたcssファイルを加工すれば、独自のスタイルが指定できそうですが、
プログラム中で追加しているボタンにはどんなクラス名が指定されているのかを
知らないとカスタマイズできないです。

生成ルールは以下のとおり。


HTMLべた書き
  生成されるHTML:<button>
  CSSセレクタ:button

プログラムから追加
  生成されるHTML:<button class="gwt-Button">
  CSSセレクタ:button.gwt-Button

自分で定義した部品をプログラムから追加
  生成されるHTML:<button class="gwt-Button my-button">
  CSSセレクタ:button.my-button





スタイルの適用方法ですが、
1.cssにスタイルを定義
2.プログラムで部品にcssで定義した名称を設定

という流れで行います。


参考にしているチュートリアルでは細かく解説されていますが、
ここでは一気に・・・
※普段、あまりcssを書かない人なので。


StockWatcher.cssに追記する内容は以下のとおり。


/* 以下の内容を「StockWatcher.css」に追記 */

body {
  padding: 10px;
}

/* テーブルのヘッダー */
.watchListHeader {
  background-color: #2062B8;
  color: white;
  font-style: italic;
}

/* テーブル全体 */
.watchList {
  border: 1px solid silver;
  padding: 2px;
  margin-bottom:6px;
}

/* 価格と変動列 */
.watchListNumericColumn {
  text-align: right;
  width:8em;
}

/* 削除列 */
.watchListRemoveColumn {
  text-align: center;
}

/* パネル */
.addPanel {
  margin: 10px 0px 15px 0px;
}






StockWatcher.javaは、以下のようになりました。


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;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
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.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Window;
import java.util.ArrayList;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Random;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.TimeZone;

import java.util.Date;

public class StockWatcher implements EntryPoint {
    
    // 更新間隔を指定
    private static final int REFRESH_INTERVAL = 5000; // ms
    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("追加");
    private Label lastUpdatedLabel = new Label();
    // テーブルに表示しているデータ保存用の変数
    private ArrayList<String> stocks = new ArrayList<String>();
    
    /**
     * Entry point method.
     */
    public void onModuleLoad() {
        // テーブルの作成
        stocksFlexTable.setText(0, 0, "銘柄");
        stocksFlexTable.setText(0, 1, "価格");
        stocksFlexTable.setText(0, 2, "変動");
        stocksFlexTable.setText(0, 3, "削除");
        
        
        
        // ========== 追加箇所 ここから==============
        // スタイルの指定を追加
        stocksFlexTable.getRowFormatter().addStyleName(0, "watchListHeader");
        stocksFlexTable.addStyleName("watchList");
        stocksFlexTable.getCellFormatter().addStyleName(0, 1, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(0, 3, "watchListRemoveColumn");
        // ========== 追加箇所 ここまで==============
        
        
        
        // 部品が横に並ぶパネルに、銘柄入力テキストとボタンを追加
        addPanel.add(newSymbolTextBox);
        addPanel.add(addStockButton);
        
        
        
        // ========== 追加箇所 ここから==============
        // スタイルの指定を追加
        addPanel.addStyleName("addPanel");
        // ========== 追加箇所 ここまで==============
        
        
        
        // 部品が縦に並ぶパネルに、テーブルと上記パネル、最終更新日ラベルを追加
        mainPanel.add(stocksFlexTable);
        mainPanel.add(addPanel);
        mainPanel.add(lastUpdatedLabel);
        
        // StockWatcher.htmlのid=stockListのdivを
        // ルートパネルとして取得し、mainPanelを設定する。
        RootPanel.get("stockList").add(mainPanel);
        
        // 起動時、銘柄入力のテキストボックスにフォーカスを設定する
        newSymbolTextBox.setFocus(true);
        
        // 追加ボタンにイベントリスナーを設定
        addStockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                addStock();
            }
        });
        
        // 銘柄入力テキストにイベントリスナーを設定
        newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
            public void onKeyPress(KeyPressEvent event) {
                // 入力されたキーが「Enter」だったら、追加処理を実行する
                if (event.getCharCode() == KeyCodes.KEY_ENTER) {
                    addStock();
                }
            }
        });
        
        // データの自動更新を行うために、onModuleLoadメソッドでタイマーを生成
        Timer refreshTimer = new Timer() {
            @Override
            public void run() {
                refreshWatchList();
            }
        };
        refreshTimer.scheduleRepeating(REFRESH_INTERVAL);
    }
    
    // 株式銘柄の追加処理
    private void addStock() {
        // テキストボックスから入力された文字列を取得
        final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
        newSymbolTextBox.setFocus(true);

        // 証券コードは、1文字以上10文字以下
        // 使える文字は数字・アルファベット・ドット(.)のみ
        if (!symbol.matches("^[0-9A-Z\\.]{1,10}$")) {
            // 入力された文字が証券コードではない場合は、エラーメッセージ表示
            Window.alert("'" + symbol + "' は不正な証券コードです。");
            newSymbolTextBox.selectAll();
            return;
        }

        newSymbolTextBox.setText("");
        
        // 証券コードの重複チェック処理
        // 追加予定の証券コードが既にリストに含まれていたら、追加処理を実行しない。
        if (stocks.contains(symbol)) {
            return;
        }
        // テーブルへの行追加処理
        // 現在のテーブルの行数を取得
        int row = stocksFlexTable.getRowCount();
        // ArrayListに追加した証券コードを退避
        stocks.add(symbol);
        // テーブルへ行の追加実行
        stocksFlexTable.setText(row, 0, symbol);
        
        
        
        // ========== 追加箇所 ここから==============
        // スタイルの指定を追加
        stocksFlexTable.getCellFormatter().addStyleName(row, 1, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(row, 3, "watchListRemoveColumn");
        // ========== 追加箇所 ここまで==============
        
        
        
        // 追加した行に削除ボタンを配置
        Button removeStockButton = new Button("x");
        // 削除ボタンが押されたときのイベントを定義
        removeStockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                // 削除する行のインデックスを取得
                int removedIndex = stocks.indexOf(symbol);
                // ArrayListから削除
                stocks.remove(removedIndex);
                // テーブルからも削除
                stocksFlexTable.removeRow(removedIndex + 1);
            }
        });
        
        // 削除ボタンをテーブルに追加
        stocksFlexTable.setWidget(row, 3, removeStockButton);
        
        // 証券の金額を取得
        refreshWatchList();
    }
    
    // 価格情報の更新を行う
    private void refreshWatchList() {
        // 価格情報の更新処理
        final double MAX_PRICE = 100.0; // $100.00
        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(stocks.get(i), price, change);
        }

        updateTable(prices);
        
    }
    
    private void updateTable(StockPrice[] prices) {
        // テーブルの更新処理
        for (int i = 0; i < prices.length; i++) {
            updateTable(prices[i]);
        }
        
        DateTimeFormat timeFormat = DateTimeFormat.getFormat("yyyy年MM月dd日 HH:mm:ss");
        
        // 最終更新時間を表示
        lastUpdatedLabel.setText("最終更新時間 : "
            + timeFormat.format(new Date(), TimeZone.createTimeZone(-60 * 9)));
    }
    
    private void updateTable(StockPrice price) {
        // ArrayListに指定された株式銘柄コードが存在しない場合は処理中断
        if (!stocks.contains(price.getSymbol())) {
            return;
        }

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

        // 価格表示用のフォーマット
        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());

        // 価格・変動率のテーブル表示を更新
        stocksFlexTable.setText(row, 1, priceText);
        stocksFlexTable.setText(row, 2, changeText + " (" + changePercentText
                + "%)");
    }
}






ブラウザを更新すると、以下のようにオシャレな感じになるはずです。

08_005_20101104234444.png







4. Creating secondary styles dependent on a primary style



プログラムで動的に追加している削除ボタンですが、
こんな感じのタグで生成されています。


<button class="gwt-Button tabindex="0" type="button">x</button>




デフォルトのgwt-Buttonのcssは以下のとおり。


.gwt-Button {
    background:transparent url(images/hborder.png) repeat-x scroll 0px -27px;
    border:1px outset #CCCCCC;
    cursor:pointer;
    font-size:small;
    margin:0pt;
    padding:3px 5px;
    text-decoration:none;
}




これを変更してみます。
StockWatcher.cssに以下の内容を追記。


/* 削除ボタン */
.gwt-Button-remove {
width: 50px;
}




StockWatcher.jaraで動的に削除ボタンを配置している箇所に
スタイルの指定を追加。


// 追加した行に削除ボタンを配置
Button removeStockButton = new Button("x");
removeStockButton.addStyleDependentName("remove");




上記の指定で、生成されるHTMLが以下のように変更となります。


<button class="gwt-Button gwt-Button-remove" tabindex="0" type="button">x</button>




ブラウザをリロードしてみると、削除ボタンの幅が
広がったことが確認できます。

08_006_20101104234444.png






5. Updating styles dynamically



価格の変動列に表示する文字の色を以下の条件で変更しようと思います。


増加:緑色
変化なし:黒色
減少:赤色




まず、スタイルシートに以下の内容を追記。


/* 変更なし */
.noChange {
  color: black;
}

/* 増加 */
.positiveChange {
  color: green;
}

/* 減少 */
.negativeChange {
  color: red;
}





StockWatcher.javaのaddStockメソッドにラベルを設定する
処理を追加します。


        // テーブルへ行の追加実行
        stocksFlexTable.setText(row, 0, symbol);
        
        
        // ====== 以下の処理を追加 ====
        // ラベルを追加
        stocksFlexTable.setWidget(row, 2, new Label());
        
        
        // スタイルの指定を追加
        stocksFlexTable.getCellFormatter().addStyleName(row, 1, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(row, 3, "watchListRemoveColumn");





updateTableメソッドで、変動率を表示している箇所を修正します。


        // 価格・変動率のテーブル表示を更新
        stocksFlexTable.setText(row, 1, priceText);
        
        // この処理をコメント
//        stocksFlexTable.setText(row, 2, changeText + " (" + changePercentText
//                + "%)");
        
        // 以下の処理を追加
        // ラベルに対してテキストを追加するようにする。
        Label changeWidget = (Label)stocksFlexTable.getWidget(row, 2);
        changeWidget.setText(changeText + " (" + changePercentText + "%)");
        
        // 変動率に応じて、適用するスタイルの名称を変更
        String changeStyleName = "noChange";
        if (price.getChangePercent() < -0.1f) {
         changeStyleName = "negativeChange";
        }
        else if (price.getChangePercent() > 0.1f) {
         changeStyleName = "positiveChange";
        }
        
        changeWidget.setStyleName(changeStyleName);






ブラウザをリロードすると、こんな表示になると思います。

08_007.png







6. Setting an element's HTML attributes



セルの間隔が詰まり過ぎているので、CellPaddingを指定して間隔をあけます。

StockWatcher.javaのonModuleLoadメソッドに処理を追加しました。



    public void onModuleLoad() {
        // テーブルの作成
        stocksFlexTable.setText(0, 0, "銘柄");
        stocksFlexTable.setText(0, 1, "価格");
        stocksFlexTable.setText(0, 2, "変動");
        stocksFlexTable.setText(0, 3, "削除");
        
        // 以下の処理を追加
        // CellPaddingを指定して、間隔をあける
        stocksFlexTable.setCellPadding(6);




ブラウザをリロードすると、こんな表示になるはずです。

08_008.png






7. Adding images or other static HTML elements



最後に、ロゴを貼り付けます。

GoogleCode.png


ロゴの画像をダウンロードして、プロジェクトのwarフォルダに
imagesというフォルダを作成し、その中に保存します。
パッケージ・エクスプローラーでの表示はこうなります。

08_009.png



StockWatcher.htmlにロゴを表示するためのタグを追記します。


<body>
    <!-- ロゴ画像を表示 -->
    <img src="images/GoogleCode.png" />
    
    <h1>StockWatcher</h1>
    <div id="stockList"></div>







これでスタイルの適用は完了です。
完成後のソースです。


【StockWatcher.java】


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;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
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.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Window;
import java.util.ArrayList;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Random;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.TimeZone;

import java.util.Date;

public class StockWatcher implements EntryPoint {
    
    // 更新間隔を指定
    private static final int REFRESH_INTERVAL = 5000; // ms
    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("追加");
    private Label lastUpdatedLabel = new Label();
    // テーブルに表示しているデータ保存用の変数
    private ArrayList<String> stocks = new ArrayList<String>();
    
    /**
     * Entry point method.
     */
    public void onModuleLoad() {
        // テーブルの作成
        stocksFlexTable.setText(0, 0, "銘柄");
        stocksFlexTable.setText(0, 1, "価格");
        stocksFlexTable.setText(0, 2, "変動");
        stocksFlexTable.setText(0, 3, "削除");
        
        // CellPaddingを指定して、間隔を
        stocksFlexTable.setCellPadding(6);
        
        // スタイルの指定を追加
        stocksFlexTable.getRowFormatter().addStyleName(0, "watchListHeader");
        stocksFlexTable.addStyleName("watchList");
        stocksFlexTable.getCellFormatter().addStyleName(0, 1, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(0, 3, "watchListRemoveColumn");
        
        // 部品が横に並ぶパネルに、銘柄入力テキストとボタンを追加
        addPanel.add(newSymbolTextBox);
        addPanel.add(addStockButton);
        // スタイルの指定を追加
        addPanel.addStyleName("addPanel");
        
        // 部品が縦に並ぶパネルに、テーブルと上記パネル、最終更新日ラベルを追加
        mainPanel.add(stocksFlexTable);
        mainPanel.add(addPanel);
        mainPanel.add(lastUpdatedLabel);
        
        // StockWatcher.htmlのid=stockListのdivを
        // ルートパネルとして取得し、mainPanelを設定する。
        RootPanel.get("stockList").add(mainPanel);
        
        // 起動時、銘柄入力のテキストボックスにフォーカスを設定する
        newSymbolTextBox.setFocus(true);
        
        // 追加ボタンにイベントリスナーを設定
        addStockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                addStock();
            }
        });
        
        // 銘柄入力テキストにイベントリスナーを設定
        newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
            public void onKeyPress(KeyPressEvent event) {
                // 入力されたキーが「Enter」だったら、追加処理を実行する
                if (event.getCharCode() == KeyCodes.KEY_ENTER) {
                    addStock();
                }
            }
        });
        
        // データの自動更新を行うために、onModuleLoadメソッドでタイマーを生成
        Timer refreshTimer = new Timer() {
            @Override
            public void run() {
                refreshWatchList();
            }
        };
        refreshTimer.scheduleRepeating(REFRESH_INTERVAL);
    }
    
    // 株式銘柄の追加処理
    private void addStock() {
        // テキストボックスから入力された文字列を取得
        final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
        newSymbolTextBox.setFocus(true);

        // 証券コードは、1文字以上10文字以下
        // 使える文字は数字・アルファベット・ドット(.)のみ
        if (!symbol.matches("^[0-9A-Z\\.]{1,10}$")) {
            // 入力された文字が証券コードではない場合は、エラーメッセージ表示
            Window.alert("'" + symbol + "' は不正な証券コードです。");
            newSymbolTextBox.selectAll();
            return;
        }

        newSymbolTextBox.setText("");
        
        // 証券コードの重複チェック処理
        // 追加予定の証券コードが既にリストに含まれていたら、追加処理を実行しない。
        if (stocks.contains(symbol)) {
            return;
        }
        // テーブルへの行追加処理
        // 現在のテーブルの行数を取得
        int row = stocksFlexTable.getRowCount();
        // ArrayListに追加した証券コードを退避
        stocks.add(symbol);
        // テーブルへ行の追加実行
        stocksFlexTable.setText(row, 0, symbol);
        // ラベルを追加
        stocksFlexTable.setWidget(row, 2, new Label());
        
        // スタイルの指定を追加
        stocksFlexTable.getCellFormatter().addStyleName(row, 1, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
        stocksFlexTable.getCellFormatter().addStyleName(row, 3, "watchListRemoveColumn");
        
        // 追加した行に削除ボタンを配置
        Button removeStockButton = new Button("x");
        removeStockButton.addStyleDependentName("remove");
        
        // 削除ボタンが押されたときのイベントを定義
        removeStockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                // 削除する行のインデックスを取得
                int removedIndex = stocks.indexOf(symbol);
                // ArrayListから削除
                stocks.remove(removedIndex);
                // テーブルからも削除
                stocksFlexTable.removeRow(removedIndex + 1);
            }
        });
        
        // 削除ボタンをテーブルに追加
        stocksFlexTable.setWidget(row, 3, removeStockButton);
        
        // 証券の金額を取得
        refreshWatchList();
    }
    
    // 価格情報の更新を行う
    private void refreshWatchList() {
        // 価格情報の更新処理
        final double MAX_PRICE = 100.0; // $100.00
        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(stocks.get(i), price, change);
        }

        updateTable(prices);
        
    }
    
    private void updateTable(StockPrice[] prices) {
        // テーブルの更新処理
        for (int i = 0; i < prices.length; i++) {
            updateTable(prices[i]);
        }
        
        DateTimeFormat timeFormat = DateTimeFormat.getFormat("yyyy年MM月dd日 HH:mm:ss");
        
        // 最終更新時間を表示
        lastUpdatedLabel.setText("最終更新時間 : "
            + timeFormat.format(new Date(), TimeZone.createTimeZone(-60 * 9)));
    }
    
    private void updateTable(StockPrice price) {
        // ArrayListに指定された株式銘柄コードが存在しない場合は処理中断
        if (!stocks.contains(price.getSymbol())) {
            return;
        }

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

        // 価格表示用のフォーマット
        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());

        // 価格・変動率のテーブル表示を更新
        stocksFlexTable.setText(row, 1, priceText);
        // ラベルに対してテキストを追加するようにする。
        Label changeWidget = (Label)stocksFlexTable.getWidget(row, 2);
        changeWidget.setText(changeText + " (" + changePercentText + "%)");
        
        // 変動率に応じて、適用するスタイルの名称を変更
        String changeStyleName = "noChange";
        if (price.getChangePercent() < -0.1f) {
         changeStyleName = "negativeChange";
        }
        else if (price.getChangePercent() > 0.1f) {
         changeStyleName = "positiveChange";
        }
        
        changeWidget.setStyleName(changeStyleName);
        
    }
}






【StockPrice.java】


package com.google.gwt.sample.stockwatcher.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 this.symbol;
    }

    public double getPrice() {
        return this.price;
    }

    public double getChange() {
        return this.change;
    }

    public double getChangePercent() {
        return 100.0 * this.change / this.price;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void setChange(double change) {
        this.change = change;
    }
}






【StockWatcher.css】


body {
  padding: 10px;
}

/* テーブルのヘッダー */
.watchListHeader {
  background-color: #2062B8;
  color: white;
  font-style: italic;
}

/* テーブル全体 */
.watchList {
  border: 1px solid silver;
  padding: 2px;
  margin-bottom:6px;
}

/* 価格と変動列 */
.watchListNumericColumn {
  text-align: right;
  width:8em;
}

/* 削除列 */
.watchListRemoveColumn {
  text-align: center;
}

/* パネル */
.addPanel {
  margin: 10px 0px 15px 0px;
}

/* 削除ボタン */
.gwt-Button-remove {
  width: 50px;
}


/* 変更なし */
.noChange {
  color: black;
}

/* 増加 */
.positiveChange {
  color: green;
}

/* 減少 */
.negativeChange {
  color: red;
}






【StockWatcher.html】


<!doctype html>
<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>
    <!-- ロゴ画像を表示 -->
    <img src="images/GoogleCode.png" />
    <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>






ブラウザをリロードすると、こんな表示になります。

08_010.png




関連記事



Google Web Toolkit 2.1 チュートリアル8 GWTアプリケーションのコンパイル
Google Web Toolkit に関する記事の一覧









関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2010/11/04(木) 23:49:26|
  2. Google Web Toolkit
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Google Web Toolkit 2.1 チュートリアル8 GWTアプリケーションのコンパイル | ホーム | Google Web Toolkit 2.1 チュートリアル6 GWTアプリケーションのデバッグ>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
https://symfoware.blog.fc2.com/tb.php/637-d99200e3
この記事にトラックバックする(FC2ブログユーザー)