You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2010/03/06 02:33:57 UTC
svn commit: r919683 - in /pivot/trunk/tutorials: .settings/
src/org/apache/pivot/tutorials/stocktracker/
Author: gbrown
Date: Sat Mar 6 01:33:57 2010
New Revision: 919683
URL: http://svn.apache.org/viewvc?rev=919683&view=rev
Log:
Update Stock Tracker to use Bindable.
Added:
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/DetailPane.java
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.java
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.json
- copied, changed from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.json
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_fr.json
- copied, changed from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_fr.json
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_it.json
- copied, changed from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_it.json
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/detail_pane.wtkx
- copied, changed from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.detail.wtkx
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker_window.wtkx
- copied, changed from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.wtkx
Removed:
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockQuoteView.java
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.json
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_fr.json
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_it.json
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.detail.wtkx
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.wtkx
Modified:
pivot/trunk/tutorials/.settings/org.eclipse.core.resources.prefs
pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.java
Modified: pivot/trunk/tutorials/.settings/org.eclipse.core.resources.prefs
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/.settings/org.eclipse.core.resources.prefs?rev=919683&r1=919682&r2=919683&view=diff
==============================================================================
--- pivot/trunk/tutorials/.settings/org.eclipse.core.resources.prefs (original)
+++ pivot/trunk/tutorials/.settings/org.eclipse.core.resources.prefs Sat Mar 6 01:33:57 2010
@@ -1,7 +1,7 @@
-#Sat Feb 13 10:53:04 EST 2010
+#Fri Mar 05 20:12:02 EST 2010
eclipse.preferences.version=1
encoding//src/org/apache/pivot/tutorials/localization/Localization.json=UTF-8
encoding//src/org/apache/pivot/tutorials/localization/Localization_de.json=UTF-8
-encoding//src/org/apache/pivot/tutorials/stocktracker/StockTracker.json=UTF-8
-encoding//src/org/apache/pivot/tutorials/stocktracker/StockTracker_fr.json=UTF-8
+encoding//src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.json=UTF-8
+encoding//src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_fr.json=UTF-8
encoding/<project>=UTF-8
Added: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/DetailPane.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/DetailPane.java?rev=919683&view=auto
==============================================================================
--- pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/DetailPane.java (added)
+++ pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/DetailPane.java Sat Mar 6 01:33:57 2010
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.tutorials.stocktracker;
+
+import java.text.DecimalFormat;
+
+import org.apache.pivot.collections.Dictionary;
+import org.apache.pivot.serialization.JSONSerializer;
+import org.apache.pivot.util.Resources;
+import org.apache.pivot.wtk.BoxPane;
+import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtkx.Bindable;
+import org.apache.pivot.wtkx.WTKX;
+
+public class DetailPane extends BoxPane implements Bindable {
+ @WTKX private Label valueLabel = null;
+ @WTKX private Label changeLabel = null;
+ @WTKX private Label openingValueLabel = null;
+ @WTKX private Label highValueLabel = null;
+ @WTKX private Label lowValueLabel = null;
+ @WTKX private Label volumeLabel = null;
+
+ private Resources resources = null;
+
+ private DecimalFormat valueFormat = new DecimalFormat("$0.00");
+ private DecimalFormat changeFormat = new DecimalFormat("+0.00;-0.00");
+ private DecimalFormat volumeFormat = new DecimalFormat();
+
+ @Override
+ public void initialize(Resources resources) {
+ this.resources = resources;
+ }
+
+ @Override
+ public void load(Dictionary<String, ?> context) {
+ super.load(context);
+
+ String notApplicable = resources.getString("notApplicable");
+
+ float value = JSONSerializer.getFloat(context, "value");
+ valueLabel.setText(Float.isNaN(value) ? notApplicable : valueFormat.format(value));
+
+ float openingValue = JSONSerializer.getFloat(context, "openingValue");
+ openingValueLabel.setText(Float.isNaN(openingValue) ? notApplicable : valueFormat.format(openingValue));
+
+ float highValue = JSONSerializer.getFloat(context, "highValue");
+ highValueLabel.setText(Float.isNaN(highValue) ? notApplicable : valueFormat.format(highValue));
+
+ float lowValue = JSONSerializer.getFloat(context, "lowValue");
+ lowValueLabel.setText(Float.isNaN(lowValue) ? notApplicable : valueFormat.format(lowValue));
+
+ float change = JSONSerializer.getFloat(context, "change");
+ changeLabel.setText(changeFormat.format(change));
+
+ int volume = JSONSerializer.getInteger(context, "volume");
+ volumeLabel.setText(volumeFormat.format(volume));
+ }
+}
Modified: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.java?rev=919683&r1=919682&r2=919683&view=diff
==============================================================================
--- pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.java (original)
+++ pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.java Sat Mar 6 01:33:57 2010
@@ -16,208 +16,31 @@
*/
package org.apache.pivot.tutorials.stocktracker;
-import java.awt.Desktop;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.text.DateFormat;
-import java.util.Comparator;
-import java.util.Date;
import java.util.Locale;
-import org.apache.pivot.web.GetQuery;
-
-import org.apache.pivot.collections.ArrayList;
-import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Map;
-import org.apache.pivot.collections.Sequence;
-import org.apache.pivot.serialization.CSVSerializer;
import org.apache.pivot.util.Resources;
-import org.apache.pivot.util.concurrent.Task;
-import org.apache.pivot.util.concurrent.TaskListener;
import org.apache.pivot.wtk.Application;
-import org.apache.pivot.wtk.ApplicationContext;
-import org.apache.pivot.wtk.Button;
-import org.apache.pivot.wtk.ButtonPressListener;
-import org.apache.pivot.wtk.Component;
-import org.apache.pivot.wtk.ComponentKeyListener;
-import org.apache.pivot.wtk.Container;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
-import org.apache.pivot.wtk.Form;
-import org.apache.pivot.wtk.Keyboard;
-import org.apache.pivot.wtk.Label;
-import org.apache.pivot.wtk.MessageType;
-import org.apache.pivot.wtk.Span;
-import org.apache.pivot.wtk.TableView;
-import org.apache.pivot.wtk.TableViewRowListener;
-import org.apache.pivot.wtk.TableViewSelectionListener;
-import org.apache.pivot.wtk.TableViewSortListener;
-import org.apache.pivot.wtk.TaskAdapter;
-import org.apache.pivot.wtk.TextInput;
-import org.apache.pivot.wtk.TextInputTextListener;
-import org.apache.pivot.wtk.Window;
-import org.apache.pivot.wtk.content.TableViewRowComparator;
-import org.apache.pivot.wtk.text.TextNode;
-import org.apache.pivot.wtkx.WTKX;
import org.apache.pivot.wtkx.WTKXSerializer;
public class StockTracker implements Application {
- private ArrayList<String> symbols = new ArrayList<String>();
-
- private Window window = null;
-
- @WTKX private TableView stocksTableView;
- @WTKX private TextInput symbolTextInput;
- @WTKX private Button addSymbolButton;
- @WTKX private Button removeSymbolsButton;
- @WTKX private Label lastUpdateLabel;
- @WTKX private Button yahooFinanceButton;
- @WTKX(id="detail.rootPane") private Container detailRootPane;
- @WTKX(id="detail.changeLabel") private Label detailChangeLabel;
-
- private GetQuery getQuery = null;
+ private StockTrackerWindow window = null;
public static final String LANGUAGE_PROPERTY_NAME = "language";
- public static final String SERVICE_HOSTNAME = "download.finance.yahoo.com";
- public static final String SERVICE_PATH = "/d/quotes.csv";
- public static final long REFRESH_INTERVAL = 15000;
- public static final String YAHOO_FINANCE_HOME = "http://finance.yahoo.com";
-
- public StockTracker() {
- symbols.setComparator(new Comparator<String>() {
- @Override
- public int compare(String s1, String s2) {
- return s1.compareTo(s2);
- }
- });
-
- symbols.add("EBAY");
- symbols.add("AAPL");
- symbols.add("MSFT");
- symbols.add("AMZN");
- symbols.add("GOOG");
- symbols.add("ORCL");
- symbols.add("IBM");
- }
@Override
- public void startup(Display display, Map<String, String> properties)
- throws Exception {
- // Set the locale
+ public void startup(Display display, Map<String, String> properties) throws Exception {
String language = properties.get(LANGUAGE_PROPERTY_NAME);
if (language != null) {
Locale.setDefault(new Locale(language));
}
- // Load and bind to the WTKX source
- Resources resources = new Resources(getClass().getName());
+ Resources resources = new Resources(StockTrackerWindow.class.getName());
WTKXSerializer wtkxSerializer = new WTKXSerializer(resources);
- window = (Window)wtkxSerializer.readObject(this, "stocktracker.wtkx");
- wtkxSerializer.bind(this, StockTracker.class);
-
- // Wire up event handlers
- stocksTableView.getTableViewRowListeners().add(new TableViewRowListener.Adapter() {
- @Override
- public void rowsSorted(TableView tableView) {
- List<?> tableData = stocksTableView.getTableData();
- if (tableData.getLength() > 0) {
- stocksTableView.setSelectedIndex(0);
- }
- }
- });
-
- stocksTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener.Adapter() {
- @Override
- public void selectedRangesChanged(TableView tableView, Sequence<Span> previousSelectedRanges) {
- refreshDetail();
- }
- });
-
- stocksTableView.getTableViewSortListeners().add(new TableViewSortListener.Adapter() {
- @Override
- @SuppressWarnings("unchecked")
- public void sortChanged(TableView tableView) {
- List<Object> tableData = (List<Object>)tableView.getTableData();
- tableData.setComparator(new TableViewRowComparator(tableView));
- }
- });
-
- stocksTableView.getComponentKeyListeners().add(new ComponentKeyListener.Adapter() {
- @Override
- public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
- if (keyCode == Keyboard.KeyCode.DELETE) {
- removeSelectedSymbols();
- }
-
- return false;
- }
- });
-
- symbolTextInput.getTextInputTextListeners().add(new TextInputTextListener() {
- @Override
- public void textChanged(TextInput textInput) {
- TextNode textNode = textInput.getTextNode();
- addSymbolButton.setEnabled(textNode.getCharacterCount() > 0);
- }
- });
-
- symbolTextInput.getComponentKeyListeners().add(new ComponentKeyListener.Adapter() {
- @Override
- public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
- if (keyCode == Keyboard.KeyCode.ENTER) {
- addSymbol();
- }
-
- return false;
- }
- });
-
- addSymbolButton.getButtonPressListeners().add(new ButtonPressListener() {
- @Override
- public void buttonPressed(Button button) {
- addSymbol();
- }
- });
-
- removeSymbolsButton.getButtonPressListeners().add(new ButtonPressListener() {
- @Override
- public void buttonPressed(Button button) {
- removeSelectedSymbols();
- }
- });
-
- yahooFinanceButton.getButtonPressListeners().add(new ButtonPressListener() {
- @Override
- public void buttonPressed(Button button) {
- Desktop desktop = Desktop.getDesktop();
-
- try {
- desktop.browse(new URL(YAHOO_FINANCE_HOME).toURI());
- } catch(MalformedURLException exception) {
- throw new RuntimeException(exception);
- } catch(URISyntaxException exception) {
- throw new RuntimeException(exception);
- } catch(IOException exception) {
- System.out.println("Unable to open "
- + YAHOO_FINANCE_HOME + " in default browser.");
- }
- }
- });
-
+ window = (StockTrackerWindow)wtkxSerializer.readObject(this, "stocktracker_window.wtkx");
window.open(display);
-
- refreshTable();
-
- ApplicationContext.scheduleRecurringCallback(new Runnable() {
- @Override
- public void run() {
- refreshTable();
- }
- }, REFRESH_INTERVAL);
-
- symbolTextInput.requestFocus();
}
@Override
@@ -237,168 +60,6 @@
public void resume() {
}
- @SuppressWarnings("unchecked")
- private void refreshTable() {
- getQuery = new GetQuery(SERVICE_HOSTNAME, SERVICE_PATH);
-
- StringBuilder symbolsArgumentBuilder = new StringBuilder();
- for (int i = 0, n = symbols.getLength(); i < n; i++) {
- if (i > 0) {
- symbolsArgumentBuilder.append(",");
- }
-
- symbolsArgumentBuilder.append(symbols.get(i));
- }
-
- // Format:
- // s - symbol
- // n - company name
- // l1 - most recent value
- // o - opening value
- // h - high value
- // g - low value
- // c1 - change percentage
- // v - volume
- String symbolsArgument = symbolsArgumentBuilder.toString();
- getQuery.getParameters().put("s", symbolsArgument);
- getQuery.getParameters().put("f", "snl1ohgc1v");
-
- CSVSerializer quoteSerializer = new CSVSerializer();
- quoteSerializer.getKeys().add("symbol");
- quoteSerializer.getKeys().add("companyName");
- quoteSerializer.getKeys().add("value");
- quoteSerializer.getKeys().add("openingValue");
- quoteSerializer.getKeys().add("highValue");
- quoteSerializer.getKeys().add("lowValue");
- quoteSerializer.getKeys().add("change");
- quoteSerializer.getKeys().add("volume");
-
- quoteSerializer.setItemClass(StockQuote.class);
- getQuery.setSerializer(quoteSerializer);
-
- getQuery.execute(new TaskAdapter<Object>(new TaskListener<Object>() {
- @Override
- public void taskExecuted(Task<Object> task) {
- if (task == getQuery) {
- List<Object> quotes = (List<Object>)task.getResult();
-
- // Preserve any existing sort and selection
- Sequence<?> selectedStocks = stocksTableView.getSelectedRows();
-
- List<Object> tableData = (List<Object>)stocksTableView.getTableData();
- Comparator<Object> comparator = tableData.getComparator();
- quotes.setComparator(comparator);
-
- stocksTableView.setTableData(quotes);
-
- if (selectedStocks.getLength() > 0) {
- // Select current indexes of selected stocks
- for (int i = 0, n = selectedStocks.getLength(); i < n; i++) {
- StockQuote selectedStock = (StockQuote)selectedStocks.get(i);
-
- int index = 0;
- for (StockQuote stock : (List<StockQuote>)stocksTableView.getTableData()) {
- if (stock.getSymbol().equals(selectedStock.getSymbol())) {
- stocksTableView.addSelectedIndex(index);
- break;
- }
-
- index++;
- }
- }
- } else {
- if (quotes.getLength() > 0) {
- stocksTableView.setSelectedIndex(0);
- }
- }
-
- refreshDetail();
-
- DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
- DateFormat.MEDIUM, Locale.getDefault());
- lastUpdateLabel.setText(dateFormat.format(new Date()));
-
- getQuery = null;
- }
- }
-
- @Override
- public void executeFailed(Task<Object> task) {
- if (task == getQuery) {
- System.err.println(task.getFault());
- getQuery = null;
- }
- }
- }));
- }
-
- @SuppressWarnings("unchecked")
- private void refreshDetail() {
- int firstSelectedIndex = stocksTableView.getFirstSelectedIndex();
- removeSymbolsButton.setEnabled(firstSelectedIndex != -1);
-
- StockQuote stockQuote = null;
-
- if (firstSelectedIndex != -1) {
- int lastSelectedIndex = stocksTableView.getLastSelectedIndex();
-
- if (firstSelectedIndex == lastSelectedIndex) {
- List<StockQuote> tableData = (List<StockQuote>)stocksTableView.getTableData();
- stockQuote = tableData.get(firstSelectedIndex);
- } else {
- stockQuote = new StockQuote();
- }
- } else {
- stockQuote = new StockQuote();
- }
-
- StockQuoteView stockQuoteView = new StockQuoteView(stockQuote);
- detailRootPane.load(stockQuoteView);
-
- float change = stockQuote.getChange();
- if (!Float.isNaN(change)
- && change < 0) {
- Form.setFlag(detailChangeLabel, new Form.Flag(MessageType.ERROR));
- } else {
- Form.setFlag(detailChangeLabel, (Form.Flag)null);
- }
- }
-
- @SuppressWarnings("unchecked")
- private void addSymbol() {
- String symbol = symbolTextInput.getText().toUpperCase();
- if (symbols.indexOf(symbol) == -1) {
- symbols.add(symbol);
-
- List<StockQuote> tableData = (List<StockQuote>)stocksTableView.getTableData();
- StockQuote stockQuote = new StockQuote();
- stockQuote.setSymbol(symbol);
- int index = tableData.add(stockQuote);
-
- stocksTableView.setSelectedIndex(index);
- }
-
- symbolTextInput.setText("");
- refreshTable();
- }
-
- private void removeSelectedSymbols() {
- int selectedIndex = stocksTableView.getFirstSelectedIndex();
- int selectionLength = stocksTableView.getLastSelectedIndex() - selectedIndex + 1;
- stocksTableView.getTableData().remove(selectedIndex, selectionLength);
- symbols.remove(selectedIndex, selectionLength);
-
- if (selectedIndex >= symbols.getLength()) {
- selectedIndex = symbols.getLength() - 1;
- }
-
- stocksTableView.setSelectedIndex(selectedIndex);
-
- if (selectedIndex == -1) {
- refreshDetail();
- }
- }
-
public static void main(String[] args) {
DesktopApplicationContext.main(StockTracker.class, args);
}
Added: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.java?rev=919683&view=auto
==============================================================================
--- pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.java (added)
+++ pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.java Sat Mar 6 01:33:57 2010
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.tutorials.stocktracker;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.DateFormat;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.List;
+import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.serialization.CSVSerializer;
+import org.apache.pivot.serialization.JSONSerializer;
+import org.apache.pivot.util.Resources;
+import org.apache.pivot.util.concurrent.Task;
+import org.apache.pivot.util.concurrent.TaskListener;
+import org.apache.pivot.web.GetQuery;
+import org.apache.pivot.wtk.ApplicationContext;
+import org.apache.pivot.wtk.Button;
+import org.apache.pivot.wtk.ButtonPressListener;
+import org.apache.pivot.wtk.Component;
+import org.apache.pivot.wtk.ComponentKeyListener;
+import org.apache.pivot.wtk.Display;
+import org.apache.pivot.wtk.Keyboard;
+import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.Span;
+import org.apache.pivot.wtk.TableView;
+import org.apache.pivot.wtk.TableViewRowListener;
+import org.apache.pivot.wtk.TableViewSelectionListener;
+import org.apache.pivot.wtk.TableViewSortListener;
+import org.apache.pivot.wtk.TaskAdapter;
+import org.apache.pivot.wtk.TextInput;
+import org.apache.pivot.wtk.TextInputTextListener;
+import org.apache.pivot.wtk.Window;
+import org.apache.pivot.wtk.content.TableViewRowComparator;
+import org.apache.pivot.wtkx.Bindable;
+import org.apache.pivot.wtkx.WTKX;
+
+public class StockTrackerWindow extends Window implements Bindable {
+ @WTKX private TableView stocksTableView = null;
+ @WTKX private TextInput symbolTextInput = null;
+ @WTKX private Button addSymbolButton = null;
+ @WTKX private Button removeSymbolsButton = null;
+ @WTKX private DetailPane detailPane = null;
+ @WTKX private Label lastUpdateLabel = null;
+ @WTKX private Button yahooFinanceButton = null;
+
+ private ArrayList<String> symbols = new ArrayList<String>();
+ private GetQuery getQuery = null;
+
+ public static final String SERVICE_HOSTNAME = "download.finance.yahoo.com";
+ public static final String SERVICE_PATH = "/d/quotes.csv";
+ public static final long REFRESH_INTERVAL = 15000;
+ public static final String YAHOO_FINANCE_HOME = "http://finance.yahoo.com";
+
+ public StockTrackerWindow() {
+ symbols.setComparator(new Comparator<String>() {
+ @Override
+ public int compare(String s1, String s2) {
+ return s1.compareTo(s2);
+ }
+ });
+
+ symbols.add("EBAY");
+ symbols.add("AAPL");
+ symbols.add("MSFT");
+ symbols.add("AMZN");
+ symbols.add("GOOG");
+ symbols.add("ORCL");
+ symbols.add("IBM");
+ }
+
+ @Override
+ public void initialize(Resources resources) {
+ // Wire up event handlers
+ stocksTableView.getTableViewRowListeners().add(new TableViewRowListener.Adapter() {
+ @Override
+ public void rowsSorted(TableView tableView) {
+ List<?> tableData = stocksTableView.getTableData();
+ if (tableData.getLength() > 0) {
+ stocksTableView.setSelectedIndex(0);
+ }
+ }
+ });
+
+ stocksTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener.Adapter() {
+ @Override
+ public void selectedRangesChanged(TableView tableView, Sequence<Span> previousSelectedRanges) {
+ refreshDetail();
+ }
+ });
+
+ stocksTableView.getTableViewSortListeners().add(new TableViewSortListener.Adapter() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void sortChanged(TableView tableView) {
+ List<Object> tableData = (List<Object>)tableView.getTableData();
+ tableData.setComparator(new TableViewRowComparator(tableView));
+ }
+ });
+
+ stocksTableView.getComponentKeyListeners().add(new ComponentKeyListener.Adapter() {
+ @Override
+ public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ if (keyCode == Keyboard.KeyCode.DELETE) {
+ removeSelectedSymbols();
+ }
+
+ return false;
+ }
+ });
+
+ symbolTextInput.getTextInputTextListeners().add(new TextInputTextListener() {
+ @Override
+ public void textChanged(TextInput textInput) {
+ addSymbolButton.setEnabled(textInput.getTextLength() > 0);
+ }
+ });
+
+ symbolTextInput.getComponentKeyListeners().add(new ComponentKeyListener.Adapter() {
+ @Override
+ public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ if (keyCode == Keyboard.KeyCode.ENTER) {
+ addSymbol();
+ }
+
+ return false;
+ }
+ });
+
+ addSymbolButton.getButtonPressListeners().add(new ButtonPressListener() {
+ @Override
+ public void buttonPressed(Button button) {
+ addSymbol();
+ }
+ });
+
+ removeSymbolsButton.getButtonPressListeners().add(new ButtonPressListener() {
+ @Override
+ public void buttonPressed(Button button) {
+ removeSelectedSymbols();
+ }
+ });
+
+ yahooFinanceButton.getButtonPressListeners().add(new ButtonPressListener() {
+ @Override
+ public void buttonPressed(Button button) {
+ Desktop desktop = Desktop.getDesktop();
+
+ try {
+ desktop.browse(new URL(YAHOO_FINANCE_HOME).toURI());
+ } catch(MalformedURLException exception) {
+ throw new RuntimeException(exception);
+ } catch(URISyntaxException exception) {
+ throw new RuntimeException(exception);
+ } catch(IOException exception) {
+ System.out.println("Unable to open "
+ + YAHOO_FINANCE_HOME + " in default browser.");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void open(Display display, Window owner) {
+ super.open(display, owner);
+
+ refreshTable();
+
+ ApplicationContext.scheduleRecurringCallback(new Runnable() {
+ @Override
+ public void run() {
+ refreshTable();
+ }
+ }, REFRESH_INTERVAL);
+
+ symbolTextInput.requestFocus();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void refreshTable() {
+ getQuery = new GetQuery(SERVICE_HOSTNAME, SERVICE_PATH);
+
+ StringBuilder symbolsArgumentBuilder = new StringBuilder();
+ for (int i = 0, n = symbols.getLength(); i < n; i++) {
+ if (i > 0) {
+ symbolsArgumentBuilder.append(",");
+ }
+
+ symbolsArgumentBuilder.append(symbols.get(i));
+ }
+
+ // Format:
+ // s - symbol
+ // n - company name
+ // l1 - most recent value
+ // o - opening value
+ // h - high value
+ // g - low value
+ // c1 - change percentage
+ // v - volume
+ String symbolsArgument = symbolsArgumentBuilder.toString();
+ getQuery.getParameters().put("s", symbolsArgument);
+ getQuery.getParameters().put("f", "snl1ohgc1v");
+
+ CSVSerializer quoteSerializer = new CSVSerializer();
+ quoteSerializer.setItemClass(StockQuote.class);
+
+ quoteSerializer.getKeys().add("symbol");
+ quoteSerializer.getKeys().add("companyName");
+ quoteSerializer.getKeys().add("value");
+ quoteSerializer.getKeys().add("openingValue");
+ quoteSerializer.getKeys().add("highValue");
+ quoteSerializer.getKeys().add("lowValue");
+ quoteSerializer.getKeys().add("change");
+ quoteSerializer.getKeys().add("volume");
+
+ getQuery.setSerializer(quoteSerializer);
+
+ getQuery.execute(new TaskAdapter<Object>(new TaskListener<Object>() {
+ @Override
+ public void taskExecuted(Task<Object> task) {
+ if (task == getQuery) {
+ List<Object> quotes = (List<Object>)task.getResult();
+
+ // Preserve any existing sort and selection
+ Sequence<?> selectedStocks = stocksTableView.getSelectedRows();
+
+ List<Object> tableData = (List<Object>)stocksTableView.getTableData();
+ Comparator<Object> comparator = tableData.getComparator();
+ quotes.setComparator(comparator);
+
+ stocksTableView.setTableData(quotes);
+
+ if (selectedStocks.getLength() > 0) {
+ // Select current indexes of selected stocks
+ for (int i = 0, n = selectedStocks.getLength(); i < n; i++) {
+ Object selectedStock = selectedStocks.get(i);
+
+ int index = 0;
+ for (Object stock : stocksTableView.getTableData()) {
+ String symbol = JSONSerializer.getString(stock, "symbol");
+ String selectedSymbol = JSONSerializer.getString(selectedStock, "symbol");
+
+ if (symbol.equals(selectedSymbol)) {
+ stocksTableView.addSelectedIndex(index);
+ break;
+ }
+
+ index++;
+ }
+ }
+ } else {
+ if (quotes.getLength() > 0) {
+ stocksTableView.setSelectedIndex(0);
+ }
+ }
+
+ refreshDetail();
+
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
+ DateFormat.MEDIUM, Locale.getDefault());
+ lastUpdateLabel.setText(dateFormat.format(new Date()));
+
+ getQuery = null;
+ }
+ }
+
+ @Override
+ public void executeFailed(Task<Object> task) {
+ if (task == getQuery) {
+ System.err.println(task.getFault());
+ getQuery = null;
+ }
+ }
+ }));
+ }
+
+ @SuppressWarnings("unchecked")
+ private void refreshDetail() {
+ int firstSelectedIndex = stocksTableView.getFirstSelectedIndex();
+ removeSymbolsButton.setEnabled(firstSelectedIndex != -1);
+
+ StockQuote stockQuote = null;
+
+ if (firstSelectedIndex != -1) {
+ int lastSelectedIndex = stocksTableView.getLastSelectedIndex();
+
+ if (firstSelectedIndex == lastSelectedIndex) {
+ List<StockQuote> tableData = (List<StockQuote>)stocksTableView.getTableData();
+ stockQuote = tableData.get(firstSelectedIndex);
+ } else {
+ stockQuote = new StockQuote();
+ }
+ } else {
+ stockQuote = new StockQuote();
+ }
+
+ detailPane.load(stockQuote);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void addSymbol() {
+ String symbol = symbolTextInput.getText().toUpperCase();
+ if (symbols.indexOf(symbol) == -1) {
+ symbols.add(symbol);
+
+ List<StockQuote> tableData = (List<StockQuote>)stocksTableView.getTableData();
+ StockQuote stockQuote = new StockQuote();
+ stockQuote.setSymbol(symbol);
+ int index = tableData.add(stockQuote);
+
+ stocksTableView.setSelectedIndex(index);
+ }
+
+ symbolTextInput.setText("");
+ refreshTable();
+ }
+
+ private void removeSelectedSymbols() {
+ int selectedIndex = stocksTableView.getFirstSelectedIndex();
+ int selectionLength = stocksTableView.getLastSelectedIndex() - selectedIndex + 1;
+ stocksTableView.getTableData().remove(selectedIndex, selectionLength);
+ symbols.remove(selectedIndex, selectionLength);
+
+ if (selectedIndex >= symbols.getLength()) {
+ selectedIndex = symbols.getLength() - 1;
+ }
+
+ stocksTableView.setSelectedIndex(selectedIndex);
+
+ if (selectedIndex == -1) {
+ refreshDetail();
+ }
+ }
+}
Copied: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.json (from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.json)
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.json?p2=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow.json&p1=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker.json&r1=918971&r2=919683&rev=919683&view=diff
==============================================================================
Binary files - no diff available.
Copied: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_fr.json (from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_fr.json)
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_fr.json?p2=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_fr.json&p1=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_fr.json&r1=918971&r2=919683&rev=919683&view=diff
==============================================================================
Binary files - no diff available.
Copied: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_it.json (from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_it.json)
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_it.json?p2=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTrackerWindow_it.json&p1=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/StockTracker_it.json&r1=918971&r2=919683&rev=919683&view=diff
==============================================================================
Binary files - no diff available.
Copied: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/detail_pane.wtkx (from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.detail.wtkx)
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/detail_pane.wtkx?p2=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/detail_pane.wtkx&p1=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.detail.wtkx&r1=918971&r2=919683&rev=919683&view=diff
==============================================================================
--- pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.detail.wtkx (original)
+++ pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/detail_pane.wtkx Sat Mar 6 01:33:57 2010
@@ -16,8 +16,9 @@
limitations under the License.
-->
-<BoxPane wtkx:id="rootPane" orientation="vertical" styles="{fill:true}"
+<stocktracker:DetailPane orientation="vertical" styles="{fill:true}"
xmlns:wtkx="http://pivot.apache.org/wtkx"
+ xmlns:stocktracker="org.apache.pivot.tutorials.stocktracker"
xmlns="org.apache.pivot.wtk">
<Label textKey="companyName" styles="{font:{size:12, bold:true}}"/>
<Separator/>
@@ -25,19 +26,19 @@
leftAlignLabels:true}">
<sections>
<Form.Section>
- <Label Form.label="%value" textKey="value"
+ <Label wtkx:id="valueLabel" Form.label="%value"
styles="{horizontalAlignment:'right'}"/>
- <Label wtkx:id="changeLabel" Form.label="%change" textKey="change"
+ <Label wtkx:id="changeLabel" Form.label="%change"
styles="{horizontalAlignment:'right'}"/>
- <Label Form.label="%openingValue" textKey="openingValue"
+ <Label wtkx:id="openingValueLabel" Form.label="%openingValue"
styles="{horizontalAlignment:'right'}"/>
- <Label Form.label="%highValue" textKey="highValue"
+ <Label wtkx:id="highValueLabel" Form.label="%highValue"
styles="{horizontalAlignment:'right'}"/>
- <Label Form.label="%lowValue" textKey="lowValue"
+ <Label wtkx:id="lowValueLabel" Form.label="%lowValue"
styles="{horizontalAlignment:'right'}"/>
- <Label Form.label="%volume" textKey="volume"
+ <Label wtkx:id="volumeLabel" Form.label="%volume"
styles="{horizontalAlignment:'right'}"/>
</Form.Section>
</sections>
</Form>
-</BoxPane>
+</stocktracker:DetailPane>
Copied: pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker_window.wtkx (from r918971, pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.wtkx)
URL: http://svn.apache.org/viewvc/pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker_window.wtkx?p2=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker_window.wtkx&p1=pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.wtkx&r1=918971&r2=919683&rev=919683&view=diff
==============================================================================
--- pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker.wtkx (original)
+++ pivot/trunk/tutorials/src/org/apache/pivot/tutorials/stocktracker/stocktracker_window.wtkx Sat Mar 6 01:33:57 2010
@@ -16,7 +16,7 @@
limitations under the License.
-->
-<Window title="%stockTracker" maximized="true"
+<stocktracker:StockTrackerWindow title="%stockTracker" maximized="true"
xmlns:wtkx="http://pivot.apache.org/wtkx"
xmlns:content="org.apache.pivot.wtk.content"
xmlns:stocktracker="org.apache.pivot.tutorials.stocktracker"
@@ -72,7 +72,7 @@
<right>
<Border styles="{padding:6, color:10}">
<content>
- <wtkx:include wtkx:id="detail" src="stocktracker.detail.wtkx"/>
+ <wtkx:include wtkx:id="detailPane" src="detail_pane.wtkx"/>
</content>
</Border>
</right>
@@ -124,4 +124,4 @@
</rows>
</TablePane>
</content>
-</Window>
+</stocktracker:StockTrackerWindow>