Java tutorial
package com.google.gwt.sample.stockwatcher.client.ui; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; 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.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.http.client.URL; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.sample.stockwatcher.client.StockData; import com.google.gwt.sample.stockwatcher.client.event.AddStockEvent; import com.google.gwt.sample.stockwatcher.client.event.DeleteStockEvent; 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.Command; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; 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.Label; import com.google.gwt.user.client.ui.MenuItem; import com.google.gwt.user.client.ui.RichTextArea; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Widget; public class StockWatcherViewImpl extends Composite implements StockWatcherView { private static UIBinderCompositeUiBinder uiBinder = GWT.create(UIBinderCompositeUiBinder.class); @UiField Button addStockButton; @UiField TextBox newSymbolTextBox; @UiField(provided = true) FlexTable stocksFlexTable; @UiField Label lastUpdatedLabel; @UiField Label errorMsgLabel; @UiField RichTextArea console; @UiField MenuItem helpMenuItem; @UiField MenuItem aboutMenuItem; private static final int REFRESH_INTERVAL = 5000; // ms private ArrayList<String> stocks = new ArrayList<String>(); private static final String JSON_URL = GWT.getModuleBaseURL() + "stockPrices?q="; private Presenter presenter; interface UIBinderCompositeUiBinder extends UiBinder<Widget, StockWatcherViewImpl> { } public StockWatcherViewImpl() { initFlexTable(); // Setup timer to refresh list automatically. Timer refreshTimer = new Timer() { @Override public void run() { refreshWatchList(); } }; refreshTimer.scheduleRepeating(REFRESH_INTERVAL); initWidget(uiBinder.createAndBindUi(this)); aboutMenuItem.setCommand(new Command() { @Override public void execute() { Window.alert("fuck..."); } }); } private void initFlexTable() { stocksFlexTable = new FlexTable(); // Create table for stock data. stocksFlexTable.setText(0, 0, "Symbol"); stocksFlexTable.setText(0, 1, "Price"); stocksFlexTable.setText(0, 2, "Change"); stocksFlexTable.setText(0, 3, "Remove"); // Add styles to elements in the stock list table. 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"); } @UiHandler("addStockButton") void onAddStockButtonClick(ClickEvent event) { this.presenter.onAddStockButtonClicked(new AddStockEvent(newSymbolTextBox.getText().toUpperCase().trim())); } @UiHandler("newSymbolTextBox") void onNewSymbolTextBoxKeyPress(KeyPressEvent event) { if (event.getCharCode() == KeyCodes.KEY_ENTER) { this.presenter .onAddStockButtonClicked(new AddStockEvent(newSymbolTextBox.getText().toUpperCase().trim())); } } /** * Add stock to FlexTable. Executed when the user clicks the addStockButton * or presses enter in the newSymbolTextBox. */ public void addStock() { final String symbol = newSymbolTextBox.getText().toUpperCase().trim(); newSymbolTextBox.setFocus(true); // Stock code must be between 1 and 10 chars that are numbers, letters, // or dots. if (!symbol.matches("^[0-9A-Z\\.]{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. int row = stocksFlexTable.getRowCount(); 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"); // 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(ClickEvent event) { presenter.onDeleteStockButtonClicked(new DeleteStockEvent(symbol)); } }); stocksFlexTable.setWidget(row, 3, removeStockButton); // Get the stock price. refreshWatchList(); } @Override public void removeStock(String stockName) { int removedIndex = stocks.indexOf(stockName); stocks.remove(removedIndex); stocksFlexTable.removeRow(removedIndex + 1); } /** * Generate random stock prices. */ private void refreshWatchList() { if (stocks.size() == 0) { return; } String url = JSON_URL; // Append watch list stock symbols to query URL. Iterator iter = stocks.iterator(); while (iter.hasNext()) { url += iter.next(); if (iter.hasNext()) { url += "+"; } } url = URL.encode(url); // Send request to server and catch any errors. RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url); try { Request request = builder.sendRequest(null, new RequestCallback() { public void onError(Request request, Throwable exception) { displayError("Couldn't retrieve JSON"); } public void onResponseReceived(Request request, Response response) { if (200 == response.getStatusCode()) { updateTable(asArrayOfStockData(response.getText())); } else { displayError("Couldn't retrieve JSON (" + response.getStatusText() + ")"); } } }); } catch (RequestException e) { displayError("Couldn't retrieve JSON"); } } /** * Update the Price and Change fields all the rows in the stock table. * * @param prices Stock data for all rows. */ private void updateTable(JsArray<StockData> prices) { for (int i = 0; i < prices.length(); i++) { updateTable(prices.get(i)); } // Display timestamp showing last refresh. lastUpdatedLabel.setText("Last update : " + DateTimeFormat.getMediumDateTimeFormat().format(new Date())); // Clear any errors. errorMsgLabel.setVisible(false); } /** * Update a single row in the stock table. * * @param price Stock data for a single row. */ private void updateTable(StockData price) { // Make sure the stock is still in the stock table. if (!stocks.contains(price.getSymbol())) { return; } int row = stocks.indexOf(price.getSymbol()) + 1; // Format the data in the Price and Change fields. 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()); // Populate the Price and Change fields with new data. stocksFlexTable.setText(row, 1, priceText); // stocksFlexTable.setText(row, 2, changeText + " (" + changePercentText // + "%)"); Label changeWidget = (Label) stocksFlexTable.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); } /** * If can't get JSON, display error message. * * @param error */ private void displayError(String error) { errorMsgLabel.setText("Error: " + error); errorMsgLabel.setVisible(true); } /** * Convert the string of JSON into JavaScript object. */ private final native JsArray<StockData> asArrayOfStockData(String json) /*-{ return eval(json); }-*/; @Override public void setPresenter(Presenter presenter) { this.presenter = presenter; } @Override public void logEvent(String message) { this.console.setText(message); } public ArrayList<String> getStocks() { return stocks; } public void setStocks(ArrayList<String> stocks) { this.stocks = stocks; } }