Compare commits
No commits in common. 'deliverable_11' and 'deliverable_2' have entirely different histories.
deliverabl
...
deliverabl
Binary file not shown.
Binary file not shown.
@ -1,7 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
// Const for everywhere
|
|
||||||
public class Const {
|
|
||||||
public static final String PROGRAM_NAME = "J-WatchList";
|
|
||||||
public static final String USAGE_TEXT = "Usage: Placeholder";
|
|
||||||
}
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public abstract class DataSource {
|
|
||||||
protected HashMap<String, StockType> targets;
|
|
||||||
protected String name;
|
|
||||||
protected String url;
|
|
||||||
protected String apiKey;
|
|
||||||
|
|
||||||
public DataSource(String name, String url, String apiKey) {
|
|
||||||
this.targets = new HashMap<String, StockType>();
|
|
||||||
this.name = name;
|
|
||||||
this.url = url;
|
|
||||||
this.apiKey = apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: add target to this
|
|
||||||
// add this to target if not already done
|
|
||||||
//Modifies: this, stype
|
|
||||||
public void addStype(StockType stype) {
|
|
||||||
String sname = stype.getName();
|
|
||||||
if (!this.targets.containsKey(sname)) {
|
|
||||||
targets.put(sname,stype);
|
|
||||||
stype.addSource(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: del target to this
|
|
||||||
// del this to target if not already done
|
|
||||||
//Modifies: this, stype
|
|
||||||
public void delStype(StockType stype) {
|
|
||||||
String sname = stype.getName();
|
|
||||||
if (this.targets.containsKey(sname)) {
|
|
||||||
targets.remove(sname,stype);
|
|
||||||
stype.delSource(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof DataSource)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DataSource temp = (DataSource) obj;
|
|
||||||
if (temp.getName().equals(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: returns updated data in the form: double[2], [0] is price, [1] is %change
|
|
||||||
public abstract double[] update(String stype, String idstring) throws IOException;
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
//Singleton pattern from https://www.tutorialspoint.com/java/java_using_singleton.htm
|
|
||||||
public class ListOfWatchList {
|
|
||||||
private static ListOfWatchList lowl = new ListOfWatchList();
|
|
||||||
private ArrayList<WatchList> wlists;
|
|
||||||
|
|
||||||
private ListOfWatchList() {
|
|
||||||
wlists = new ArrayList<WatchList>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ListOfWatchList getList() {
|
|
||||||
return lowl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: add a watchlist to this list, if it isn't already in the list
|
|
||||||
//Modifies: this
|
|
||||||
public void addWatchList(WatchList wlist) {
|
|
||||||
if (!(wlists.contains(wlist))) {
|
|
||||||
wlists.add(wlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: remove a watchlist
|
|
||||||
//Modifies: this
|
|
||||||
public void delWatchList(WatchList wlist) {
|
|
||||||
wlists.remove(wlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: return a watchlist by index
|
|
||||||
public WatchList getWatchList(int index) {
|
|
||||||
return (WatchList) wlists.get(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
public interface Load {
|
|
||||||
// Effects: Load data from a file
|
|
||||||
// Modifies: this
|
|
||||||
// Requires: Existing file with name "filename"
|
|
||||||
public void load(String filename);
|
|
||||||
|
|
||||||
// Effects: Check if file exists
|
|
||||||
public boolean fileExists(String filename);
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import data.StockType;
|
|
||||||
|
|
||||||
public class Nasdaq extends StockType {
|
|
||||||
public Nasdaq() {
|
|
||||||
super();
|
|
||||||
name = "NASDAQ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import data.StockType;
|
|
||||||
import network.AlphaVantage;
|
|
||||||
|
|
||||||
public class Nyse extends StockType {
|
|
||||||
public Nyse() {
|
|
||||||
super();
|
|
||||||
name = "NYSE";
|
|
||||||
addSource(new AlphaVantage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
public interface Save {
|
|
||||||
// Effects: Save data to a file
|
|
||||||
// Modifies: this
|
|
||||||
public void save(String filename);
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class StockEntry {
|
|
||||||
private String identifier;
|
|
||||||
private StockType stype;
|
|
||||||
private double price;
|
|
||||||
private double change;
|
|
||||||
private boolean updating = false;
|
|
||||||
|
|
||||||
public StockEntry(StockType stype, String idstring) {
|
|
||||||
identifier = idstring;
|
|
||||||
this.stype = stype;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: return true if price or change is/are new
|
|
||||||
// update the price and %change by the stype update
|
|
||||||
//Modifies: this
|
|
||||||
public boolean update() {
|
|
||||||
boolean changed = false;
|
|
||||||
updating = true;
|
|
||||||
double[] result;
|
|
||||||
try {
|
|
||||||
result = this.stype.update(this.identifier);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Error getting update");
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ((result[0] != price) || (result[1] != change)) {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
this.price = result[0];
|
|
||||||
this.change = result[1];
|
|
||||||
updating = false;
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTypeName() {
|
|
||||||
return this.stype.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getID() {
|
|
||||||
return this.identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getChange() {
|
|
||||||
return change;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUpdating() {
|
|
||||||
return updating;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof StockEntry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
StockEntry tmp = (StockEntry) obj;
|
|
||||||
if (tmp.getID().equals(identifier)
|
|
||||||
&& tmp.getTypeName().equals(stype.getName())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(identifier, stype.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public abstract class StockType {
|
|
||||||
protected String name;
|
|
||||||
protected HashSet<DataSource> sources;
|
|
||||||
|
|
||||||
// Sources is empty
|
|
||||||
public StockType() {
|
|
||||||
sources = new HashSet<DataSource>();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effects: return current price[0] and %change[1]
|
|
||||||
// (2 element array)
|
|
||||||
//Require: working sources
|
|
||||||
public double[] update(String idstring) throws IOException {
|
|
||||||
double[] result = {0.0, 0.0};
|
|
||||||
for (DataSource source : sources) {
|
|
||||||
double[] sourceRes = source.update(name, idstring);
|
|
||||||
result[0] += sourceRes[0];
|
|
||||||
result[1] += sourceRes[1];
|
|
||||||
}
|
|
||||||
result[0] /= sources.size();
|
|
||||||
result[1] /= sources.size();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effects: add source to this
|
|
||||||
// add this to source, if not already added
|
|
||||||
//Modifies: this, source
|
|
||||||
public void addSource(DataSource source) {
|
|
||||||
if (!this.sources.contains(source)) {
|
|
||||||
this.sources.add(source);
|
|
||||||
source.addStype(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effects: add source to this
|
|
||||||
// add this to source, if not already added
|
|
||||||
//Modifies: this, source
|
|
||||||
public void delSource(DataSource source) {
|
|
||||||
if (this.sources.contains(source)) {
|
|
||||||
this.sources.remove(source);
|
|
||||||
source.delStype(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effects: return name of type
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof StockType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
StockType sobj = (StockType) obj;
|
|
||||||
return this.name.equals(sobj.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import data.StockType;
|
|
||||||
import data.Nyse;
|
|
||||||
import data.Nasdaq;
|
|
||||||
//import data.Jpx;
|
|
||||||
//import data.Sse;
|
|
||||||
//import data.Hkse;
|
|
||||||
|
|
||||||
//Contains one instance of all supported
|
|
||||||
//StockType
|
|
||||||
//Singleton from https://www.tutorialspoint.com/java/java_using_singleton.htm
|
|
||||||
public class StypeMap {
|
|
||||||
private static HashMap<String, StockType> smap;
|
|
||||||
private static StypeMap stypemap = new StypeMap();
|
|
||||||
|
|
||||||
// Effects: smap is initialized
|
|
||||||
// with supported StockType
|
|
||||||
private StypeMap() {
|
|
||||||
smap = new HashMap<String, StockType>();
|
|
||||||
addStype(new Nyse());
|
|
||||||
addStype(new Nasdaq());
|
|
||||||
//addStype(new Jpx());
|
|
||||||
//addStype(new Sse());
|
|
||||||
//addStype(new Hkse());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: Returns the StockType
|
|
||||||
// Require: Valid typeString
|
|
||||||
// note: this is a shortcut to getMap and then getInstStype
|
|
||||||
public static StockType getStype(String typeString) {
|
|
||||||
return stypemap.getInstStype(typeString);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addStype(StockType stype) {
|
|
||||||
smap.put(stype.getName(), stype);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StockType getInstStype(String typeString) {
|
|
||||||
return this.smap.get(typeString);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StypeMap getMap() {
|
|
||||||
return stypemap;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HashMap getHMap() {
|
|
||||||
return smap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.io.*;
|
|
||||||
import data.StockEntry;
|
|
||||||
import ui.Main;
|
|
||||||
import data.exceptions.*;
|
|
||||||
import java.util.Observable;
|
|
||||||
|
|
||||||
public class WatchList extends Observable implements Load,Save {
|
|
||||||
private LinkedHashMap<String, StockEntry> listdata;
|
|
||||||
public static final String DEFAULT_SAVEFILE = ".jwatch.list";
|
|
||||||
|
|
||||||
public enum Etype {
|
|
||||||
UPDATE, ADD, DEL
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: List is empty
|
|
||||||
// or loaded with save values
|
|
||||||
public WatchList() {
|
|
||||||
listdata = new LinkedHashMap<String, StockEntry>();
|
|
||||||
if (fileExists(DEFAULT_SAVEFILE)) {
|
|
||||||
load("");
|
|
||||||
}
|
|
||||||
ListOfWatchList.getList().addWatchList(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: Add an entry with key==target
|
|
||||||
// (XXX For now, only Nyse)
|
|
||||||
// Modifies: this.listdata
|
|
||||||
// Requires: target doesn't already exists
|
|
||||||
public void addStock(String target) {
|
|
||||||
//The only implementation yet
|
|
||||||
StockType stype = StypeMap.getStype("NYSE");
|
|
||||||
this.listdata.put(target, new StockEntry(stype, target));
|
|
||||||
setChanged();
|
|
||||||
notifyObservers(new Wevent(Etype.ADD, size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: Delete an entry with key==target
|
|
||||||
// Modifies: this.listdata
|
|
||||||
// Requires: target exists in list
|
|
||||||
public void delStock(String target) throws StockNotExistsException {
|
|
||||||
if (!listdata.containsKey(target)) {
|
|
||||||
throw new StockNotExistsException();
|
|
||||||
}
|
|
||||||
int index = new ArrayList(listdata.keySet()).indexOf(target);
|
|
||||||
this.listdata.remove(target);
|
|
||||||
setChanged();
|
|
||||||
notifyObservers(new Wevent(Etype.DEL, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: return an array of all Stock names in list
|
|
||||||
public String[] getNames() {
|
|
||||||
return listdata.keySet().toArray(new String[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: Return an iterator of the list
|
|
||||||
// Warning: not thread-safe, fail-fast
|
|
||||||
public Iterator iterator() {
|
|
||||||
Set entryset = listdata.entrySet();
|
|
||||||
return entryset.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effects: return a stockentry given its index
|
|
||||||
public StockEntry getStock(int index) {
|
|
||||||
String key = (String) listdata.keySet().toArray()[index];
|
|
||||||
return (StockEntry) listdata.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects: Return the size of list
|
|
||||||
public int size() {
|
|
||||||
return listdata.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: save list to a file, save to DEFAULT_SAVEFILE if filename is empty
|
|
||||||
@Override
|
|
||||||
public void save(String filename) {
|
|
||||||
if (filename.equals("")) {
|
|
||||||
filename = DEFAULT_SAVEFILE;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
FileWriter fwriter = new FileWriter(filename);
|
|
||||||
BufferedWriter bwriter = new BufferedWriter(fwriter);
|
|
||||||
Iterator iterate = iterator();
|
|
||||||
while (iterate.hasNext()) {
|
|
||||||
Map.Entry entry = (Map.Entry)iterate.next();
|
|
||||||
String outString = (String)entry.getKey();
|
|
||||||
System.out.println("Exported: " + outString);
|
|
||||||
bwriter.write(outString);
|
|
||||||
bwriter.newLine();
|
|
||||||
}
|
|
||||||
bwriter.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("IO Error when writing: " + filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: return true if filename exists and is a file
|
|
||||||
@Override
|
|
||||||
public boolean fileExists(String filename) {
|
|
||||||
File fileObj = new File(filename);
|
|
||||||
return fileObj.isFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: load list from file, load from DEFAULT_SAVEFILE if filename is empty
|
|
||||||
//Modifies: this
|
|
||||||
@Override
|
|
||||||
public void load(String filename) {
|
|
||||||
if (filename.equals("")) {
|
|
||||||
filename = DEFAULT_SAVEFILE;
|
|
||||||
}
|
|
||||||
String sss = null;
|
|
||||||
try {
|
|
||||||
FileReader freader = new FileReader(filename);
|
|
||||||
BufferedReader breader = new BufferedReader(freader);
|
|
||||||
while ((sss = breader.readLine()) != null) {
|
|
||||||
addStock(sss);
|
|
||||||
System.out.println("Imported: " + sss);
|
|
||||||
}
|
|
||||||
breader.close();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
System.out.println("File not found: " + filename);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("IO Error when reading: " + filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: perform price and %update for @ stockentry in list
|
|
||||||
//Modifies: this, stockentries
|
|
||||||
public void updateList() {
|
|
||||||
Iterator watchit = iterator();
|
|
||||||
boolean changed = false;
|
|
||||||
while (watchit.hasNext()) {
|
|
||||||
Map.Entry entry = (Map.Entry)watchit.next();
|
|
||||||
StockEntry sentry = (StockEntry)entry.getValue();
|
|
||||||
if (!changed) {
|
|
||||||
changed = changed || sentry.update();
|
|
||||||
}
|
|
||||||
sentry.update();
|
|
||||||
}
|
|
||||||
setChanged();
|
|
||||||
notifyObservers(new Wevent(Etype.UPDATE));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Wevent {
|
|
||||||
private Etype type;
|
|
||||||
private int data;
|
|
||||||
|
|
||||||
public Wevent(Etype type) {
|
|
||||||
this(type, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Wevent(Etype type, int num) {
|
|
||||||
this.type = type;
|
|
||||||
this.data = num;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Etype getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
package data.exceptions;
|
|
||||||
|
|
||||||
import data.exceptions.WatchListExceptions;
|
|
||||||
|
|
||||||
public class StockNotExistsException extends WatchListExceptions {
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
package data.exceptions;
|
|
||||||
|
|
||||||
public abstract class WatchListExceptions extends Exception {
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package network;
|
|
||||||
|
|
||||||
import data.StypeMap;
|
|
||||||
import java.io.IOException;
|
|
||||||
import javax.json.JsonObject;
|
|
||||||
import data.DataSource;
|
|
||||||
import network.exceptions.*;
|
|
||||||
|
|
||||||
public class AlphaVantage extends DataSource {
|
|
||||||
|
|
||||||
public AlphaVantage() {
|
|
||||||
super("AlphaVantage", "https://www.alphavantage.co/query", "4MC2LL0HOQ2TFQL1");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: get intraday price and %change through JSON given the stock ticker
|
|
||||||
@Override
|
|
||||||
public double[] update(String stype, String idstring) throws IOException {
|
|
||||||
double[] result = {0.0, 0.0};
|
|
||||||
try {
|
|
||||||
String urlString = Net.urlStringBuilder(url, "function", "TIME_SERIES_INTRADAY", "symbol", idstring,
|
|
||||||
"interval", "5min",
|
|
||||||
"apikey", apiKey);
|
|
||||||
JsonObject response = StockJson.urlToJson(urlString);
|
|
||||||
JsonObject preJson = StockJson.jsonInJson(response, "Time Series (5min)");
|
|
||||||
if (preJson == null) {
|
|
||||||
throw new IOException("Error getting data from " + name);
|
|
||||||
}
|
|
||||||
JsonObject mainJson = StockJson.timeSeriesElement(preJson, 0);
|
|
||||||
//System.out.print(mainJson);
|
|
||||||
result[0] = Double.parseDouble(StockJson.stringGetter(mainJson, "4. close"));
|
|
||||||
Double open = Double.parseDouble(StockJson.stringGetter(mainJson, "1. open"));
|
|
||||||
result[1] = (result[0] - open) / open;
|
|
||||||
} catch (ParaMismatchException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} //catch (IOException e) {
|
|
||||||
// System.out.println("Error getting data from: " + name);
|
|
||||||
//e.printStackTrace();
|
|
||||||
//}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package network;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import network.exceptions.*;
|
|
||||||
|
|
||||||
//Ref: https://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests
|
|
||||||
public class Net {
|
|
||||||
//Effect: returns a String of url built with given url and paras
|
|
||||||
public static String urlStringBuilder(String url, String... paras) throws ParaMismatchException {
|
|
||||||
String urlString = url;
|
|
||||||
String charset = "UTF-8";
|
|
||||||
if ((paras.length % 2) != 0) {
|
|
||||||
throw new ParaMismatchException("Except even paras, but have " + paras.length);
|
|
||||||
}
|
|
||||||
if (paras.length != 0) {
|
|
||||||
urlString += "?";
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < paras.length - 3; i = i + 2) {
|
|
||||||
urlString += paras[i] + "=" + URLEncoder.encode(paras[i + 1], charset) + "&";
|
|
||||||
}
|
|
||||||
urlString += paras[paras.length - 2] + "=" + URLEncoder.encode(paras[paras.length - 1], charset);
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
System.out.println("Error during encoding url: Unsupported encoding");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return urlString;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: Open connection, fires a http GET and returns the InputStream of result
|
|
||||||
public static InputStream urlToInputStream(String url) throws IOException {
|
|
||||||
try {
|
|
||||||
return (new URL(url).openStream());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
package network;
|
|
||||||
|
|
||||||
import javax.json.Json;
|
|
||||||
import javax.json.JsonObject;
|
|
||||||
import javax.json.JsonReader;
|
|
||||||
import javax.json.JsonNumber;
|
|
||||||
import javax.json.JsonArray;
|
|
||||||
import javax.json.JsonValue;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
//Json library from https://docs.oracle.com/javaee/7/api/javax/json/Json.html
|
|
||||||
public class StockJson {
|
|
||||||
public static JsonObject inputStreamToJson(InputStream istream) {
|
|
||||||
JsonReader jreader = Json.createReader(istream);
|
|
||||||
JsonObject jobj = jreader.readObject();
|
|
||||||
jreader.close();
|
|
||||||
return jobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JsonObject urlToJson(String url) throws IOException {
|
|
||||||
try {
|
|
||||||
return inputStreamToJson(Net.urlToInputStream(url));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effect: return double from jsonnumber
|
|
||||||
public static double doubleGetter(JsonObject jobj, String name) {
|
|
||||||
return jobj.getJsonNumber(name).doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effect: return jsonobject from jsonobject
|
|
||||||
public static JsonObject jsonInJson(JsonObject jobj, String name) {
|
|
||||||
return jobj.getJsonObject(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effect: return string from jsonstring
|
|
||||||
public static String stringGetter(JsonObject jobj, String name) {
|
|
||||||
return jobj.getString(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effect: return double from percentage string
|
|
||||||
public static double doublePercent(JsonObject jobj, String name) {
|
|
||||||
String temp = stringGetter(jobj, name);
|
|
||||||
return Double.parseDouble(temp.split("%")[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// From https://stackoverflow.com/questions/33531041/jsonobject-get-value-of-first-node-regardless-of-name
|
|
||||||
// Effect: extract the jsonobject from jsonobject by index
|
|
||||||
public static JsonObject timeSeriesElement(JsonObject jobj, int index) {
|
|
||||||
String name = (String) jobj.keySet().toArray()[index];
|
|
||||||
return jsonInJson(jobj, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package network.exceptions;
|
|
||||||
|
|
||||||
public class ParaMismatchException extends Exception {
|
|
||||||
public ParaMismatchException(String sss) {
|
|
||||||
super(sss);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,83 +1,16 @@
|
|||||||
package ui;
|
import javax.swing.*;
|
||||||
|
|
||||||
import javax.swing.SwingUtilities;
|
public class Gui {
|
||||||
import javax.swing.JFrame;
|
//public Gui() {
|
||||||
import javax.swing.JComponent;
|
// JLabel label = new JLabel("Hello World");
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.GroupLayout;
|
|
||||||
import java.awt.Container;
|
|
||||||
import java.awt.LayoutManager;
|
|
||||||
import ui.guicomp.*;
|
|
||||||
import data.WatchList;
|
|
||||||
import data.ListOfWatchList;
|
|
||||||
import static data.Const.PROGRAM_NAME;
|
|
||||||
import javax.swing.GroupLayout.Alignment;
|
|
||||||
|
|
||||||
// based on http://zetcode.com/tutorials/javaswingtutorial/firstprograms/
|
// JFrame.setDefaultLookAndFeelDecorated(true);
|
||||||
public class Gui extends JFrame implements Iface {
|
// JFrame f = new JFrame("Hello World");
|
||||||
private JButton addButton;
|
// f.setSize(300,150);
|
||||||
private JButton delButton;
|
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
private JButton upButton;
|
|
||||||
private WatchTablePane wtable;
|
|
||||||
private WatchList wlist;
|
|
||||||
private Runnable init = new Runnable() {
|
|
||||||
//Effect: Init gui all components
|
|
||||||
//Modifies: this
|
|
||||||
public void run() {
|
|
||||||
addComponents();
|
|
||||||
createLayout();
|
|
||||||
setTitle(PROGRAM_NAME);
|
|
||||||
setSize(300, 200);
|
|
||||||
setLocationRelativeTo(null);
|
|
||||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addComponents() {
|
// f.add(label);
|
||||||
addButton = new AddButt(wlist);
|
|
||||||
delButton = new DelButt(wlist);
|
|
||||||
upButton = new UpButt(wlist);
|
|
||||||
wtable = new WatchTablePane(wlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createLayout() {
|
// f.setVisible(true);
|
||||||
Container pane = getContentPane();
|
//}
|
||||||
GroupLayout lman = new GroupLayout(pane);
|
|
||||||
pane.setLayout(lman);
|
|
||||||
lman.setAutoCreateContainerGaps(true);
|
|
||||||
lman.setHorizontalGroup(lman.createParallelGroup(GroupLayout.Alignment.CENTER)
|
|
||||||
.addComponent(wtable.getPane())
|
|
||||||
.addGroup(lman.createSequentialGroup()
|
|
||||||
.addComponent(addButton)
|
|
||||||
.addComponent(delButton)
|
|
||||||
.addComponent(upButton)
|
|
||||||
));
|
|
||||||
lman.setVerticalGroup(lman.createSequentialGroup()
|
|
||||||
.addComponent(wtable.getPane())
|
|
||||||
.addGroup(lman.createParallelGroup(GroupLayout.Alignment.CENTER)
|
|
||||||
.addComponent(addButton)
|
|
||||||
.addComponent(delButton)
|
|
||||||
.addComponent(upButton)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Gui() {
|
|
||||||
wlist = ListOfWatchList.getList().getWatchList(0);
|
|
||||||
SwingUtilities.invokeLater(init);
|
|
||||||
setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: nothing
|
|
||||||
//not enough time to do something useful for this
|
|
||||||
@Override
|
|
||||||
public void redraw() {
|
|
||||||
//Nothing for now
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: nothing
|
|
||||||
//not enough time to do something useful for this
|
|
||||||
@Override
|
|
||||||
public void destory() {
|
|
||||||
//Nothing for now
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,5 @@
|
|||||||
package ui;
|
//import data.Options;
|
||||||
|
|
||||||
public interface Iface {
|
public abstract class Iface {
|
||||||
//private Options ifaceOpts;
|
//private Options ifaceOpts;
|
||||||
|
|
||||||
//Effect: Redraw the whole interface
|
|
||||||
//Modify: This
|
|
||||||
//Require: Running thread of initialized Iface, data backend
|
|
||||||
public void redraw();
|
|
||||||
|
|
||||||
//Effect: Close all windows and disable all output
|
|
||||||
//Modify: This
|
|
||||||
//Require: Running thread of initialized Iface
|
|
||||||
public void destory();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,7 @@
|
|||||||
package ui;
|
//import data.Options;
|
||||||
|
//import ui.Iface;
|
||||||
import ui.Tui;
|
|
||||||
|
|
||||||
public class IfaceFactory {
|
public class IfaceFactory {
|
||||||
// Produce Iface given the config
|
//public Iface getIface(Options IfaceOptions){
|
||||||
public static Iface getIface() {
|
//}
|
||||||
//uses Tui for now
|
|
||||||
//return new Tui();
|
|
||||||
//Test Gui
|
|
||||||
return new Gui();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,75 @@
|
|||||||
package ui;
|
package ui;
|
||||||
|
|
||||||
import data.Const;
|
import java.util.*;
|
||||||
import data.StypeMap;
|
|
||||||
import data.StockType;
|
|
||||||
import data.WatchList;
|
|
||||||
import ui.IfaceFactory;
|
|
||||||
import data.exceptions.*;
|
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
private Iface iface;
|
public static final String PROGRAM_NAME = "Num guess";
|
||||||
|
//public static final String USAGE_TEXT = "Usage";
|
||||||
|
private int win;
|
||||||
|
private int games;
|
||||||
|
//private Iface iface;
|
||||||
|
//private Options allOptions;
|
||||||
|
|
||||||
//Constructor, not the java main
|
//Constructor, not the java main
|
||||||
public Main(String[] args) {
|
public Main(String[] args) {
|
||||||
WatchList mainList = new WatchList();
|
//options = new Options();
|
||||||
iface = IfaceFactory.getIface();
|
System.out.println("Welcome to " + PROGRAM_NAME + "!");
|
||||||
|
guess();
|
||||||
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
// java main
|
// java main
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new Main(args);
|
new Main(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void guess() {
|
||||||
|
Random rand = new Random();
|
||||||
|
while (true) {
|
||||||
|
int range = rand.nextInt(1000);
|
||||||
|
int secret = rand.nextInt(range);
|
||||||
|
System.out.println("Can you guess my number? [0 - " + range + "]");
|
||||||
|
System.out.println("Enter -1 to end");
|
||||||
|
int user = getUserInt();
|
||||||
|
if (user < 0) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
guessResult(user, secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserInt() {
|
||||||
|
Scanner scan = new Scanner(System.in);
|
||||||
|
int result = 0;
|
||||||
|
while (true) {
|
||||||
|
if (scan.hasNextInt()) {
|
||||||
|
result = scan.nextInt();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
System.out.println("Try again?");
|
||||||
|
scan.nextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void guessResult(int user, int secret) {
|
||||||
|
if (user < secret || user > secret) {
|
||||||
|
this.games++;
|
||||||
|
System.out.println("Too bad. You guessed "
|
||||||
|
+ secret + " with " + user + ".");
|
||||||
|
} else {
|
||||||
|
this.games++;
|
||||||
|
this.win++;
|
||||||
|
System.out.println("Wonderful! You have correctly guessed: "
|
||||||
|
+ secret + " with " + user + "!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end() {
|
||||||
|
System.out.println("You have won: " + this.win + " out of " + this.games
|
||||||
|
+ "!");
|
||||||
|
System.out.println("Thank you for playing this game! Bye!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,199 +1,36 @@
|
|||||||
package ui;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
//import ui.Iface;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import ui.Main;
|
|
||||||
import data.Const;
|
|
||||||
import data.WatchList;
|
|
||||||
import data.StockEntry;
|
|
||||||
import data.ListOfWatchList;
|
|
||||||
import data.exceptions.*;
|
|
||||||
import java.util.Observer;
|
|
||||||
import java.util.Observable;
|
|
||||||
|
|
||||||
public class Tui implements Iface, Observer {
|
|
||||||
|
public class Tui extends Iface {
|
||||||
private static final String SAVE_CURSOR = "\u001b[s";
|
private static final String SAVE_CURSOR = "\u001b[s";
|
||||||
private static final String RESTORE_CURSOR = "\u001b[s";
|
private static final String RESTORE_CURSOR = "\u001b[s";
|
||||||
private static final String REQUEST_CURSOR = "\u001b[6n";
|
private static final String REQUEST_CURSOR = "\u001b[6n";
|
||||||
private int maxrow;
|
|
||||||
private int maxcol;
|
private int maxcol;
|
||||||
|
private int maxrow;
|
||||||
private BufferedReader stdin;
|
private BufferedReader stdin;
|
||||||
|
|
||||||
public Tui() {
|
public Tui() {
|
||||||
stdin = new BufferedReader(new InputStreamReader(System.in));
|
// stdin = new BufferedReader(new InputStreamReader(System.in));
|
||||||
getMax();
|
|
||||||
WatchList watch = ListOfWatchList.getList().getWatchList(0);
|
|
||||||
watch.addObserver(this);
|
|
||||||
//XXX Start ui thread
|
|
||||||
demo();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: wait for user input and get a line (pressed Enter)
|
|
||||||
public String getInputLine() {
|
|
||||||
String result;
|
|
||||||
try {
|
|
||||||
// if (stdin.ready() && (result = stdin.readLine()) != null) {
|
|
||||||
// return result;
|
|
||||||
// } else {
|
|
||||||
// return "";
|
|
||||||
// }
|
|
||||||
result = stdin.readLine();
|
|
||||||
return result;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: capture user input, constantly
|
|
||||||
//Unused, for future dev uses
|
|
||||||
public String readUntil(char end) {
|
|
||||||
String result = "";
|
|
||||||
char c;
|
|
||||||
try {
|
|
||||||
while ((c = (char)stdin.read()) != end) {
|
|
||||||
result = result + String.valueOf(c);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return cursor coord as int[0]=row int[1]=colums
|
|
||||||
private int[] getCursor() {
|
|
||||||
int[] result = new int[2];
|
|
||||||
try {
|
|
||||||
if (stdin.ready()) {
|
|
||||||
System.out.print(REQUEST_CURSOR);
|
|
||||||
stdin.skip(1);
|
|
||||||
String s = readUntil(';');
|
|
||||||
result[0] = Integer.parseInt(s); //row
|
|
||||||
s = readUntil('R');
|
|
||||||
result[1] = Integer.parseInt(s); //colums
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveCursor(int col, int row) {
|
|
||||||
System.out.print("\u001b[" + col + ";" + row + "H");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getMax() {
|
|
||||||
System.out.print(SAVE_CURSOR);
|
|
||||||
moveCursor(9999,9999); //move cursor to impossibly big coord
|
|
||||||
int[] maxCoord = getCursor();
|
|
||||||
maxrow = maxCoord[0];
|
|
||||||
maxcol = maxCoord[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: nothing has to be done
|
|
||||||
@Override
|
|
||||||
public void destory() {
|
|
||||||
//Nothing has to be done
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Effect: nothing
|
//public String getInput() {
|
||||||
//will be used when Tui is redesigned
|
//}
|
||||||
@Override
|
|
||||||
public void redraw() {
|
|
||||||
//XXX Do nothing for now
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: Show a menu of functions
|
|
||||||
public void demomenu() {
|
|
||||||
System.out.println("Function select:");
|
|
||||||
System.out.println("1: Update watchlist");
|
|
||||||
System.out.println("2: Add stock");
|
|
||||||
System.out.println("3: Remove stock");
|
|
||||||
System.out.println("q: Quit");
|
|
||||||
System.out.println("Enter a number or q, then press enter.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: execute functions basing on user input from menu
|
|
||||||
public boolean demoinput() {
|
|
||||||
switch (getInputLine()) {
|
|
||||||
case "1":
|
|
||||||
updateWatch();
|
|
||||||
break;
|
|
||||||
case "2":
|
|
||||||
addWatch();
|
|
||||||
break;
|
|
||||||
case "3":
|
|
||||||
delWatch();
|
|
||||||
break;
|
|
||||||
case "q":
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
System.out.println("Invalid input, try again.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: main loop of program, displays menu, get input and execute functions
|
|
||||||
public void demo() {
|
|
||||||
System.out.println(" Welcome to " + Const.PROGRAM_NAME + "!");
|
|
||||||
boolean cont = true;
|
|
||||||
while (cont) {
|
|
||||||
demomenu();
|
|
||||||
cont = demoinput();
|
|
||||||
}
|
|
||||||
WatchList watch = ListOfWatchList.getList().getWatchList(0);
|
|
||||||
watch.save("");
|
|
||||||
System.out.println("Thank you for using " + Const.PROGRAM_NAME + "!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateWatch() {
|
|
||||||
WatchList watch = ListOfWatchList.getList().getWatchList(0);
|
|
||||||
watch.updateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printWatchList() {
|
|
||||||
WatchList watch = ListOfWatchList.getList().getWatchList(0);
|
|
||||||
Iterator watchit = watch.iterator();
|
|
||||||
while (watchit.hasNext()) {
|
|
||||||
Map.Entry entry = (Map.Entry)watchit.next();
|
|
||||||
StockEntry sentry = (StockEntry)entry.getValue();
|
|
||||||
System.out.println("Type: " + sentry.getTypeName() + "\t"
|
|
||||||
+ "Identifier: " + sentry.getID() + "\t"
|
|
||||||
+ "Price: " + sentry.getPrice() + "\t"
|
|
||||||
+ "Change %" + sentry.getChange());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addWatch() {
|
|
||||||
System.out.print("Enter your stock number and press enter: ");
|
|
||||||
String userin = getInputLine();
|
|
||||||
WatchList watch = ListOfWatchList.getList().getWatchList(0);
|
|
||||||
watch.addStock(userin);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void delWatch() {
|
//public getCursor(){
|
||||||
boolean success = false;
|
// if (stdin.ready()) {
|
||||||
System.out.print("Enter your stock number and press enter: ");
|
// System.out.print(REQUEST_CURSOR);
|
||||||
String userin = getInputLine();
|
// stdin.skip(1);
|
||||||
WatchList watch = ListOfWatchList.getList().getWatchList(0);
|
// char c;
|
||||||
try {
|
// while (char = (char)stdin.read() != ';') {
|
||||||
watch.delStock(userin);
|
// row =
|
||||||
success = true;
|
// }
|
||||||
} catch (StockNotExistsException e) {
|
// }
|
||||||
System.out.println("Stock: " + userin + " doesn't exists");
|
//}
|
||||||
} finally {
|
|
||||||
System.out.println(success ? "Deleted: " + userin : "Failed to delete: " + userin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: reprint the list when the list is updated, or if stocks are added or deleted
|
//public void moveCursor(int col, int row) {
|
||||||
@Override
|
// System.out.print("\u001b["+col+";"+row+"H");
|
||||||
public void update(Observable obsed, Object event) {
|
//}
|
||||||
printWatchList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
package ui.guicomp;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import data.WatchList;
|
|
||||||
|
|
||||||
public class AddButt extends JButton {
|
|
||||||
private WatchList wlist;
|
|
||||||
|
|
||||||
public AddButt(WatchList wlist) {
|
|
||||||
super("Add Stock...");
|
|
||||||
//https://coderanch.com/t/580497/java/JButton-clicked-action
|
|
||||||
if (getActionListeners().length < 1) {
|
|
||||||
addActionListener(new AddButtList());
|
|
||||||
}
|
|
||||||
this.wlist = wlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AddButtList implements ActionListener {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
//https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html#input
|
|
||||||
//https://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html
|
|
||||||
String userin = (String)JOptionPane.showInputDialog("Enter the identifier:");
|
|
||||||
if ((userin != null) && (userin.length() > 0)) {
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
wlist.addStock(userin);
|
|
||||||
wlist.updateList();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package ui.guicomp;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import data.WatchList;
|
|
||||||
import data.exceptions.StockNotExistsException;
|
|
||||||
|
|
||||||
public class DelButt extends JButton {
|
|
||||||
private WatchList wlist;
|
|
||||||
|
|
||||||
public DelButt(WatchList wlist) {
|
|
||||||
super("Remove Stock...");
|
|
||||||
if (getActionListeners().length < 1) {
|
|
||||||
addActionListener(new DelButtList());
|
|
||||||
}
|
|
||||||
this.wlist = wlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DelButtList implements ActionListener {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
//https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html#input
|
|
||||||
//https://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html
|
|
||||||
String[] names = wlist.getNames();
|
|
||||||
String userin = (String)JOptionPane.showInputDialog(
|
|
||||||
null, "Choose a stock to delete:", "Delete Stock",
|
|
||||||
JOptionPane.PLAIN_MESSAGE, null, names, null);
|
|
||||||
if ((userin != null) && (userin.length() > 0)) {
|
|
||||||
//https://stackoverflow.com/questions/12771500/best-way-of-creating-and-using-an-anonymous-runnable-class
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
wlist.delStock(userin);
|
|
||||||
} catch (StockNotExistsException e) {
|
|
||||||
//impossible
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package ui.guicomp;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import data.WatchList;
|
|
||||||
|
|
||||||
public class UpButt extends JButton {
|
|
||||||
private WatchList wlist;
|
|
||||||
|
|
||||||
public UpButt(WatchList wlist) {
|
|
||||||
super("Update");
|
|
||||||
if (getActionListeners().length < 1) {
|
|
||||||
addActionListener(new UpButtList());
|
|
||||||
}
|
|
||||||
this.wlist = wlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UpButtList implements ActionListener {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
wlist.updateList();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
package ui.guicomp;
|
|
||||||
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
import javax.swing.event.*;
|
|
||||||
import data.WatchList;
|
|
||||||
import data.WatchList.Wevent;
|
|
||||||
import data.StockEntry;
|
|
||||||
import java.util.Observer;
|
|
||||||
import java.util.Observable;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
|
|
||||||
// Ref: https://docs.oracle.com/javase/tutorial/uiswing/components/table.html
|
|
||||||
// Ref2: https://docs.oracle.com/javase/8/docs/api/javax/swing/table/AbstractTableModel.html
|
|
||||||
public class WatchTableModel extends AbstractTableModel implements Observer {
|
|
||||||
private final String[] colnames = {"Identifier", "Price", "% change", "Status"};
|
|
||||||
private final Object[] example = {"asdf", 0.0, "asdf", "asdf"};
|
|
||||||
private WatchList watch;
|
|
||||||
|
|
||||||
public WatchTableModel(WatchList wlist) {
|
|
||||||
watch = wlist;
|
|
||||||
watch.addObserver(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnCount() {
|
|
||||||
return colnames.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRowCount() {
|
|
||||||
return watch.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnName(int num) {
|
|
||||||
return colnames[num];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: return generated table data for whatever asked
|
|
||||||
public Object getValueAt(int stock, int field) {
|
|
||||||
StockEntry entry = watch.getStock(stock);
|
|
||||||
switch (field) {
|
|
||||||
case 0: //Name
|
|
||||||
return entry.getID();
|
|
||||||
case 1: //Price
|
|
||||||
return entry.getPrice();
|
|
||||||
case 2: //% change
|
|
||||||
return entry.getChange() + " %";
|
|
||||||
case 3:
|
|
||||||
return entry.isUpdating() ? "Updating" : "Ok";
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class getColumnClass(int col) {
|
|
||||||
return example[col].getClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: updates table for different events, ran by event dispatch thread as recommanded
|
|
||||||
//Modifies: Table displayed
|
|
||||||
@Override
|
|
||||||
public void update(Observable obsed, Object event) {
|
|
||||||
Wevent weve = (Wevent) event;
|
|
||||||
switch (weve.getType()) {
|
|
||||||
case UPDATE:
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
fireTableDataChanged(); });
|
|
||||||
break;
|
|
||||||
case ADD:
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
fireTableRowsInserted(weve.getData(), weve.getData()); });
|
|
||||||
break;
|
|
||||||
case DEL:
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
fireTableRowsDeleted(weve.getData(), weve.getData()); });
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package ui.guicomp;
|
|
||||||
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
import data.WatchList;
|
|
||||||
|
|
||||||
//https://docs.oracle.com/javase/7/docs/api/javax/swing/JTable.html
|
|
||||||
public class WatchTablePane {
|
|
||||||
private JTable table;
|
|
||||||
private TableModel tmodel;
|
|
||||||
private JScrollPane spane;
|
|
||||||
|
|
||||||
public WatchTablePane(WatchList wlist) {
|
|
||||||
tmodel = new WatchTableModel(wlist);
|
|
||||||
table = new JTable(tmodel);
|
|
||||||
spane = new JScrollPane(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JScrollPane getPane() {
|
|
||||||
return spane;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import network.AlphaVantage;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class DataSourceTest {
|
|
||||||
private StockType testStype;
|
|
||||||
private DataSource testSource;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void runBefore() {
|
|
||||||
testStype = StypeMap.getStype("NYSE");
|
|
||||||
testSource = new AlphaVantage();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test add and double deleting for many to many relationship
|
|
||||||
@Test
|
|
||||||
public void testAddDel() {
|
|
||||||
testStype.addSource(testSource);
|
|
||||||
testSource.delStype(testStype);
|
|
||||||
testSource.delStype(testStype);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test overridden equals and hashcode
|
|
||||||
@Test
|
|
||||||
public void testEqualsHash() {
|
|
||||||
DataSource testSource2 = new AlphaVantage();
|
|
||||||
DataSource testSource3 = new DataSource("test source", "asdf", "asdf") {
|
|
||||||
@Override
|
|
||||||
public double[] update(String asdf, String asdf2) throws IOException {
|
|
||||||
double[] asdfjkl = {0.0, 0.0};
|
|
||||||
return asdfjkl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
String asdf = "asdf";
|
|
||||||
assertEquals(testSource, testSource);
|
|
||||||
assertEquals(testSource, testSource2);
|
|
||||||
assertFalse(testSource.equals(asdf));
|
|
||||||
assertFalse(testSource.equals(testSource3));
|
|
||||||
assertEquals(testSource.hashCode(), testSource2.hashCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import data.ListOfWatchList;
|
|
||||||
import data.WatchList;
|
|
||||||
import data.exceptions.*;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
public class ListOfWatchListTest {
|
|
||||||
private WatchList watchlist;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void runBefore() {
|
|
||||||
watchlist = new WatchList();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: check if only one instance is returned
|
|
||||||
@Test
|
|
||||||
public void singletonCheck() {
|
|
||||||
assertTrue(ListOfWatchList.getList() == ListOfWatchList.getList());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: check double adding and deleting watchlists
|
|
||||||
@Test
|
|
||||||
public void addDelWatchList() {
|
|
||||||
ListOfWatchList lowl = ListOfWatchList.getList();
|
|
||||||
lowl.addWatchList(watchlist);
|
|
||||||
assertEquals(watchlist, lowl.getWatchList(0));
|
|
||||||
lowl.addWatchList(watchlist);
|
|
||||||
assertEquals(watchlist, lowl.getWatchList(0));
|
|
||||||
try {
|
|
||||||
lowl.getWatchList(1);
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
// expected fail
|
|
||||||
}
|
|
||||||
lowl.delWatchList(watchlist);
|
|
||||||
try {
|
|
||||||
lowl.getWatchList(0);
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
// expected fail
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package test;
|
|
||||||
|
|
||||||
import data.StypeMap;
|
|
||||||
import data.StockType;
|
|
||||||
import data.Nasdaq;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
public class NasdaqTest {
|
|
||||||
private StockType naasdaq;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
// Effect: Initialize Stype
|
|
||||||
public void runBefore() {
|
|
||||||
naasdaq = StypeMap.getStype("NASDAQ");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
//Effect: test if name matches
|
|
||||||
public void testName() {
|
|
||||||
assertTrue(naasdaq.getName().equals("NASDAQ"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
//Effect: check (indirectly) if update works, require internet to AlphaVantage
|
|
||||||
public void testUpdate() {
|
|
||||||
try {
|
|
||||||
double[] farray = naasdaq.update("MSFT");
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import data.StypeMap;
|
|
||||||
import data.StockType;
|
|
||||||
import data.Nyse;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
public class NyseTest {
|
|
||||||
private StockType nyyyse;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void runBefore() {
|
|
||||||
nyyyse = StypeMap.getStype("NYSE");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test constructor and if name matches
|
|
||||||
@Test
|
|
||||||
public void testNameInit() {
|
|
||||||
assertTrue(nyyyse.getName().equals("NYSE"));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: will connect to the internet and test update
|
|
||||||
//Require: internet connection to AlphaVantage.co
|
|
||||||
@Test
|
|
||||||
public void testUpdate() {
|
|
||||||
try {
|
|
||||||
double[] farray = nyyyse.update("MSFT");
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test overridden equals and hashcode
|
|
||||||
@Test
|
|
||||||
public void testEqualsHash() {
|
|
||||||
StockType testst1 = new Nyse();
|
|
||||||
StockType testst2 = new Nasdaq();
|
|
||||||
String asdf = "asdf";
|
|
||||||
assertEquals(nyyyse, nyyyse);
|
|
||||||
assertEquals(nyyyse, testst1);
|
|
||||||
assertFalse(nyyyse.equals(testst2));
|
|
||||||
assertFalse(nyyyse.equals(asdf));
|
|
||||||
assertEquals(nyyyse.hashCode(), testst1.hashCode());
|
|
||||||
assertFalse(nyyyse.hashCode() == testst2.hashCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import data.StockEntry;
|
|
||||||
import data.StypeMap;
|
|
||||||
import data.StockType;
|
|
||||||
import data.Nyse;
|
|
||||||
import ui.Main;
|
|
||||||
import java.io.*;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class StockEntryTest {
|
|
||||||
private StockEntry entry;
|
|
||||||
private StockType nyyyse;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void runBefore() {
|
|
||||||
nyyyse = StypeMap.getStype("NYSE");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test constructor, two getters and default 0 price
|
|
||||||
@Test
|
|
||||||
public void testTypeAndName() {
|
|
||||||
entry = new StockEntry(nyyyse, "test");
|
|
||||||
assertTrue(entry.getTypeName().equals("NYSE"));
|
|
||||||
assertTrue(entry.getID().equals("test"));
|
|
||||||
assertFalse(entry.isUpdating());
|
|
||||||
assertEquals(0, entry.getPrice());
|
|
||||||
assertEquals(0, entry.getChange());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test overridden equals and hashcode
|
|
||||||
@Test
|
|
||||||
public void testEqualsHash() {
|
|
||||||
entry = new StockEntry(nyyyse, "test");
|
|
||||||
StockEntry entry2 = new StockEntry(nyyyse, "test");
|
|
||||||
StockEntry entry3 = new StockEntry(StypeMap.getStype("NASDAQ"),
|
|
||||||
"test");
|
|
||||||
String asdf = "asdf";
|
|
||||||
assertEquals(entry, entry);
|
|
||||||
assertEquals(entry, entry2);
|
|
||||||
assertFalse(entry.equals(entry3));
|
|
||||||
assertFalse(entry.equals(asdf));
|
|
||||||
assertEquals(entry.hashCode(), entry2.hashCode());
|
|
||||||
assertFalse(entry.hashCode() == entry3.hashCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import data.StypeMap;
|
|
||||||
import data.StockType;
|
|
||||||
import data.Nyse;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class StypeMapTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
//Effect: Test if Stype NYSE exists in StypeMap
|
|
||||||
public void testGetStype() {
|
|
||||||
StockType stype = StypeMap.getStype("NYSE");
|
|
||||||
assertEquals(stype.getName(), "NYSE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
package data;
|
|
||||||
|
|
||||||
import data.WatchList;
|
|
||||||
import data.StypeMap;
|
|
||||||
import data.StockType;
|
|
||||||
import data.Nyse;
|
|
||||||
import data.exceptions.*;
|
|
||||||
import ui.Main;
|
|
||||||
import java.io.*;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
public class WatchListTest {
|
|
||||||
private WatchList watchlist;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void runBefore() {
|
|
||||||
watchlist = new WatchList();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: add stock named 1 to 100 to watchlist, test if index is keep
|
|
||||||
//counting up and if getNames() works
|
|
||||||
@Test
|
|
||||||
public void testAddStockNames() {
|
|
||||||
String[] testarray = new String[100];
|
|
||||||
String[] testgetName = new String[100];
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
watchlist.addStock(Integer.toString(i));
|
|
||||||
testarray[i] = Integer.toString(i);
|
|
||||||
}
|
|
||||||
testgetName = watchlist.getNames();
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
assertEquals(testarray[i], watchlist.getStock(i).getID());
|
|
||||||
assertEquals(Integer.toString(i), watchlist.getStock(i).getID());
|
|
||||||
assertEquals(testarray[i], testgetName[i]);
|
|
||||||
assertEquals(Integer.toString(i), testgetName[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Effect: test size function for 100 stocks
|
|
||||||
@Test
|
|
||||||
public void testSize() {
|
|
||||||
assertEquals(watchlist.size(), 0);
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
watchlist.addStock(Integer.toString(i));
|
|
||||||
}
|
|
||||||
assertEquals(watchlist.size(), 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDelStockNoThrow() {
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
watchlist.addStock(Integer.toString(i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 50; i++) {
|
|
||||||
try {
|
|
||||||
watchlist.delStock(Integer.toString(i));
|
|
||||||
} catch (WatchListExceptions e) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertEquals(watchlist.size(), 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDelNotExistsStock() {
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
watchlist.addStock(Integer.toString(i));
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
watchlist.delStock(Integer.toString(-1));
|
|
||||||
fail();
|
|
||||||
} catch (WatchListExceptions e) {
|
|
||||||
//expected to throw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSaveLoad() {
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
watchlist.addStock(Integer.toString(i));
|
|
||||||
}
|
|
||||||
watchlist.save("");
|
|
||||||
assertTrue(watchlist.fileExists(watchlist.DEFAULT_SAVEFILE));
|
|
||||||
WatchList testlist = new WatchList();
|
|
||||||
testlist.load("");
|
|
||||||
assertEquals(watchlist.size(), testlist.size());
|
|
||||||
File testFile = new File(watchlist.DEFAULT_SAVEFILE);
|
|
||||||
testFile.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFileNotFound() {
|
|
||||||
//redirect stdout: https://stackoverflow.com/questions/1119385/junit-test-for-system-out-println
|
|
||||||
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
|
|
||||||
ByteArrayOutputStream errContent = new ByteArrayOutputStream();
|
|
||||||
PrintStream originalOut = System.out;
|
|
||||||
PrintStream originalErr = System.err;
|
|
||||||
System.setOut(new PrintStream(outContent));
|
|
||||||
System.setErr(new PrintStream(errContent));
|
|
||||||
watchlist.load("thisfiledoesnotexist-andwillneverexists");
|
|
||||||
assertEquals("File not found: thisfiledoesnotexist-andwillneverexists\n", outContent.toString());
|
|
||||||
System.setOut(originalOut);
|
|
||||||
System.setErr(originalErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateEmptyList() {
|
|
||||||
watchlist.updateList();
|
|
||||||
watchlist.addStock("MSFT");
|
|
||||||
watchlist.updateList();
|
|
||||||
//https://stackoverflow.com/questions/24104313/how-do-i-make-a-delay-in-java
|
|
||||||
try {
|
|
||||||
Thread.sleep(500);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
watchlist.updateList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package placeholder;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class MainTest {
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in new issue