import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.text.DateFormat;
/** An instance allows one to query for and record stock-quote info */
public class StockQuoteGUI extends JFrame implements ActionListener {
/** where the user enters desired ticker symbol*/
private JTextField symbolEntry= new JTextField(10);
/** box to display symbol textfield and prompt */
private Box simBox= new Box(BoxLayout.X_AXIS);
/** price and date (in intuitive format) to display */
private JTextField lastQuoteDisplay= new JTextField();
/** box to display instructions and the last quote price/time */
private Box quoteBox= new Box(BoxLayout.X_AXIS);
/** button to add current quote to record */
private JButton recordButton= new JButton("record quote");
/** button to clear the record */
private JButton clearButton= new JButton("clear record");
/** box to hold the buttons */
private Box buttonBox= new Box(BoxLayout.X_AXIS);
/** stores the recorded stock quotes */
private JTextArea records= new JTextArea(6, 25);
/** box for lhs (stuff not dealing with the recorded quotes) */
private Box leftBox= new Box(BoxLayout.Y_AXIS);
/** box for the list of recorded quotes on the rhs */
private Box rightBox= new Box(BoxLayout.Y_AXIS);
/** indicates update involving a valid stock quote */
private static final int UPDATE_VALID= 1;
/** indicates update involving the Yahoo! finance webpg being inaccessible */
private static final int UPDATE_NOACCESS= 2;
/** indicates update involving the Yahoo! finance webpg being inaccessible */
private static final int UPDATE_PARSEFAILED= 3;
/** indicates update is for when the GUI is first created */
private static final int UPDATE_INIT= 4;
/** indicates update is for when the GUI should indicate it's trying to fetch data*/
private static final int UPDATE_FETCHING= 5;
/** Constructor: a new StockQuoteGUI, as described in lecture */
public StockQuoteGUI() {
super("Stock Quote GUI, using exceptions");
simBox.add(new JLabel(" enter a stock ticker symbol and hit return "));
simBox.add(symbolEntry);
symbolEntry.addActionListener(this);
leftBox.add(simBox);
lastQuoteDisplay.setEditable(false);
lastQuoteDisplay.setOpaque(false);
quoteBox.add(new JLabel(" last quote: "));
updateQuote(UPDATE_INIT, null, 0.0, null);
quoteBox.add(lastQuoteDisplay);
leftBox.add(quoteBox);
buttonBox.add(recordButton);
buttonBox.add(clearButton);
clearButton.addActionListener(this);
recordButton.addActionListener(this);
leftBox.add(buttonBox);
JLabel rjl= new JLabel("record"); rjl.setAlignmentX(Component.CENTER_ALIGNMENT);
rightBox.add(rjl);
records.setEditable(false);
rightBox.add(new JScrollPane(records));
Container cp= this.getContentPane();
cp.add(leftBox, BorderLayout.WEST);
cp.add(rightBox, BorderLayout.EAST);
pack();
// setLocation(500, 30);
setVisible(true);
}
/** Update lastQuoteDisplay's text.
* If type = UPDATE_VALID, the update involves stock symbol s, price lq, date of that price lqtime.
* If type = UPDATE_INIT, the update text is "n/a" (no last quote when GUI is started up).
* If type is UPDATE_NOACCESS, the update text is "couldn't access Yahoo finance webpage, [lqtime]"
* If type is UPDATE_PARSEFAILED, the update text is "no data for [s], [latime]".
* If type is UPDATE_FETCHING, the update text is "working..."
* Precondition: type is one of these. If this isn't an UPDATE_INIT or UPDATE_FETCHING case, s and lqtime should not be null. */
private void updateQuote(int type, String s, double lq, Date lqtime) {
assert type == UPDATE_VALID || type == UPDATE_INIT || type == UPDATE_NOACCESS || type == UPDATE_PARSEFAILED || type == UPDATE_FETCHING;
String date= "(last date unknown)";
if (lqtime != null) {
DateFormat dateFormat =
DateFormat.getDateTimeInstance(
DateFormat.SHORT,
DateFormat.MEDIUM);
date= dateFormat.format(lqtime);
}
if (type == UPDATE_VALID) {
lastQuoteDisplay.setText(s + " " + lq + " @ " + date);
}
else if (type == UPDATE_INIT) {
lastQuoteDisplay.setText("n/a");
}
else if (type == UPDATE_NOACCESS) {
lastQuoteDisplay.setText("couldn't connect, " + lqtime);
}
else if (type == UPDATE_FETCHING) {
lastQuoteDisplay.setText("working...");
}
else {
lastQuoteDisplay.setText("no data for " + s + ", " + lqtime);
}
repaint(); // updateQuote remembers about repainting
}
/**
create and display a sample GUI
*/
public static void main(String[] args) {
new StockQuoteGUI();
}
/** specify actions to be performed */
public void actionPerformed(ActionEvent evt) {
if (evt.getSource() == recordButton)
{
records.append(lastQuoteDisplay.getText() + "\n");
}
else if (evt.getSource() == clearButton) {
records.setText("");
}
else if (evt.getSource() == symbolEntry) {
String symbol= symbolEntry.getText();
if (symbol.length() == 0) {
return;
}
updateQuote(UPDATE_FETCHING, symbol, 0.0, new Date());
try {
updateQuote(UPDATE_VALID, symbol, StockQuote.getQuote(symbol), new Date());
}
catch(YahooFinanceFailedException e) {
updateQuote(UPDATE_NOACCESS, symbol, 0.0, new Date()); // enter n/a (here stands for "not available")
}
catch (YahooDataUnparseableException e) {
updateQuote(UPDATE_PARSEFAILED, symbol, 0.0, new Date()); // enter n/a (here stands for "not available")
}
}
}
}