com.google.gwt.sample.stockwatcher.uibinder.client.StockWatcherWidget.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.sample.stockwatcher.uibinder.client.StockWatcherWidget.java

Source

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

import java.util.ArrayList;
import java.util.Date;

import net.customware.gwt.dispatch.client.DefaultExceptionHandler;
import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.dispatch.client.standard.StandardDispatchAsync;

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.KeyDownEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.sample.stockwatcher.uibinder.shared.StockPrice;
import com.google.gwt.sample.stockwatcher.uibinder.shared.StockPriceAction;
import com.google.gwt.sample.stockwatcher.uibinder.shared.StockPriceResult;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
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;
import com.google.gwt.user.client.ui.Widget;

public class StockWatcherWidget extends Composite {

    private static StockWatcherWidgetUiBinder uiBinder = GWT.create(StockWatcherWidgetUiBinder.class);

    interface StockWatcherWidgetUiBinder extends UiBinder<Widget, StockWatcherWidget> {
    }

    private static final int REFRESH_INTERVAL = 5000; // ms

    private final DispatchAsync dispatchAsync = new StandardDispatchAsync(new DefaultExceptionHandler());

    @UiField
    VerticalPanel mainPanel;

    @UiField
    FlexTable stockFlexTable = new FlexTable();

    @UiField
    HorizontalPanel addPanel = new HorizontalPanel();

    @UiField
    TextBox newSymbolTextBox = new TextBox();

    @UiField
    Button addStockButton = new Button("Add");

    @UiField
    Label lastUpdatedLabel = new Label();

    private ArrayList<String> stocks = new ArrayList<String>();

    public StockWatcherWidget() {
        initWidget(uiBinder.createAndBindUi(this));
        initUI();
    }

    private void initUI() {
        stockFlexTable.setText(0, 0, "Symbol");
        stockFlexTable.setText(0, 1, "Price");
        stockFlexTable.setText(0, 2, "Change");
        stockFlexTable.setText(0, 3, "Remove");

        // Add styles
        stockFlexTable.setCellPadding(6);
        stockFlexTable.getRowFormatter().addStyleName(0, "watchListHeader");
        stockFlexTable.addStyleName("watchList");
        stockFlexTable.getCellFormatter().addStyleName(0, 1, "watchListNumericColumn");
        stockFlexTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn");
        stockFlexTable.getCellFormatter().addStyleName(0, 3, "watchListRemoveColumn");

        newSymbolTextBox.setFocus(true);

        // Setup timer to refresh list automatically.
        Timer refreshTimer = new Timer() {
            @Override
            public void run() {
                refreshWatchList();
            }
        };
        refreshTimer.scheduleRepeating(REFRESH_INTERVAL);
    }

    @UiHandler("addStockButton")
    void handleClick(final ClickEvent event) {
        addStock();
    }

    @UiHandler("newSymbolTextBox")
    void handleKeyDown(final KeyDownEvent event) {
        if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
            addStock();
        }
    }

    private void addStock() {
        final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
        newSymbolTextBox.setFocus(true);

        if (!symbol.matches("^[0-9A-Z&#92;&#92;.]{1,10}$")) {
            Window.alert("'" + symbol + "' is not a valid symbol.");
            newSymbolTextBox.selectAll();
            return;
        }

        newSymbolTextBox.setText("");

        // Don't add the stock if it's already in the table.
        if (stocks.contains(symbol)) {
            return;
        }

        // Add the stock to the table
        stocks.add(symbol);
        int row = stockFlexTable.getRowCount();
        stockFlexTable.setText(row, 0, symbol);
        stockFlexTable.setWidget(row, 2, new Label());
        stockFlexTable.getCellFormatter().addStyleName(row, 1, "watchListNumericColumn");
        stockFlexTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
        stockFlexTable.getCellFormatter().addStyleName(row, 3, "watchListRemoveColumn");

        // Add a button to remove this stock from the table.
        Button removeStockButton = new Button("x");
        removeStockButton.addStyleDependentName("remove");
        removeStockButton.addClickHandler(new ClickHandler() {
            public void onClick(final ClickEvent event) {
                int removedIndex = stocks.indexOf(symbol);
                stocks.remove(symbol);
                stockFlexTable.removeRow(removedIndex + 1);
            }
        });
        stockFlexTable.setWidget(row, 3, removeStockButton);

        // Get the stock price.
        refreshWatchList();
    }

    // Normal way to refresh
    // private void refreshWatchList() {
    // final double MAX_PRICE = 100.0;
    // final double MAX_PRICE_CHANGE = 0.02;
    // 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);
    // }

    // Use gwt-dispatch to refresh
    private void refreshWatchList() {
        for (int i = 0; i < stocks.size(); i++) {
            dispatchAsync.execute(new StockPriceAction(stocks.get(i)), new AsyncCallback<StockPriceResult>() {
                @Override
                public void onFailure(Throwable caught) {
                    Window.alert("Error: " + caught.getMessage());
                }

                @Override
                public void onSuccess(StockPriceResult result) {
                    updateTable(result.getStockPrice());
                }
            });
        }
        updateDateLabel();
    }

    private void updateDateLabel() {
        DateTimeFormat dateFormat = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_TIME_MEDIUM);
        lastUpdatedLabel.setText("Last update: " + dateFormat.format(new Date()));
    }

    private void updateTable(final StockPrice price) {
        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());

        stockFlexTable.setText(row, 1, priceText);
        // stockFlexTable.setText(row, 2, changeText + " (" + changePercentText + "%)");
        Label changeWidget = (Label) stockFlexTable.getWidget(row, 2);
        changeWidget.setText(changeText + " (" + changePercentText + "%)");

        // Change the color of text in the Change field based on its value.
        String changeStyleName = "noChange";
        if (price.getChangePercent() < -0.1f) {
            changeStyleName = "negativeChange";

        } else if (price.getChangePercent() > 0.1f) {
            changeStyleName = "positiveChange";
        }
        changeWidget.setStyleName(changeStyleName);
    }
}