斯坦福CS106A作业6
这次的作业是做一个姓名使用趋势的展示作业,综合了很多知识,收获很大。
NameSurfer
/*
* File: NameSurfer.java
* ---------------------
* When it is finished, this program will implements the viewer for
* the baby-name database described in the assignment handout.
*/
import acm.program.*;
import java.awt.event.*;
import javax.swing.*;
public class NameSurfer extends Program implements NameSurferConstants {
/* Method: init() */
/**
* This method has the responsibility for reading in the data base
* and initializing the interactors at the top of the window.
*/
public void init() {
// You fill this in, along with any helper methods //
label=new JLabel("Name");
text=new JTextField(20);
graph=new JButton("Graph");
clear=new JButton("Clear");
deletion=new JButton("Deletion");
add(label,NORTH);
add(text,NORTH);
add(graph,NORTH);
add(clear,NORTH);
add(deletion,NORTH);
text.addActionListener(this);
addActionListeners();
//读取数据
database=new NameSurferDataBase(NAMES_DATA_FILE);
Graph = new NameSurferGraph();
add(Graph);
Graph.update();
}
/* Method: actionPerformed(e) */
/**
* This class is responsible for detecting when the buttons are
* clicked, so you will have to define a method to respond to
* button actions.
*/
public void actionPerformed(ActionEvent e) {
// You fill this in //
if(e.getSource()==text) {
String name=text.getText();
NameSurferEntry entry=database.findEntry(name.toUpperCase());
if(entry!=null) {
Graph.addEntry(entry);
Graph.update();
}
//println("Graph: \""+text.getText()+'"');
//println("Graph: \""+database.findEntry(name.toUpperCase())+'"');
}else if(e.getSource()==graph) {
String name=text.getText();
NameSurferEntry entry=database.findEntry(name.toUpperCase());
if(entry!=null) {
Graph.addEntry(entry);
Graph.update();
}
//println("Graph: \""+text.getText()+'"');
//println("Graph: \""+database.findEntry(name.toUpperCase())+'"');
}else if(e.getSource()==clear){
Graph.clear();
Graph.update();
}else {
String name=text.getText();
NameSurferEntry entry=database.findEntry(name.toUpperCase());
Graph.deletion(entry);
Graph.update();
}
}
private JLabel label;
private JTextField text;
private JButton graph;
private JButton clear;
private JButton deletion;
private NameSurferDataBase database;
private NameSurferGraph Graph;
}
NameSurferDataBase
/*
* File: NameSurferDataBase.java
* -----------------------------
* This class keeps track of the complete database of names.
* The constructor reads in the database from a file, and
* the only public method makes it possible to look up a
* name and get back the corresponding NameSurferEntry.
* Names are matched independent of case, so that "Eric"
* and "ERIC" are the same names.
*/
import acm.util.*;
import java.io.*;
import java.util.*;
public class NameSurferDataBase implements NameSurferConstants {
/* Constructor: NameSurferDataBase(filename) */
/**
* Creates a new NameSurferDataBase and initializes it using the
* data in the specified file. The constructor throws an error
* exception if the requested file does not exist or if an error
* occurs as the file is being read.
*/
public NameSurferDataBase(String filename) {
// You fill this in //
database=new HashMap<String,NameSurferEntry>();
//打开文件
BufferedReader rd = null;
try {
rd=new BufferedReader(new FileReader(filename));
}catch(IOException ex) {
System.out.println("Can't open that file.");
}
//读取数据
try {
while(true) {
String line=rd.readLine();
if(line==null) {
break;
}
NameSurferEntry text=new NameSurferEntry(line);
database.put(text.getName().toUpperCase(), text);
}
rd.close();
}catch(IOException ex) {
throw new ErrorException(ex);
}
}
/* Method: findEntry(name) */
/**
* Returns the NameSurferEntry associated with this name, if one
* exists. If the name does not appear in the database, this
* method returns null.
*/
public NameSurferEntry findEntry(String name) {
// You need to turn this stub into a real implementation //
return database.get(name);
}
HashMap<String,NameSurferEntry> database;
}
NameSurferEntry
/*
* File: NameSurferEntry.java
* --------------------------
* This class represents a single entry in the database. Each
* NameSurferEntry contains a name and a list giving the popularity
* of that name for each decade stretching back to 1900.
*/
import acm.util.*;
import java.util.*;
public class NameSurferEntry implements NameSurferConstants {
/* Constructor: NameSurferEntry(line) */
/**
* Creates a new NameSurferEntry from a data line as it appears
* in the data file. Each line begins with the name, which is
* followed by integers giving the rank of that name for each
* decade.
*/
public NameSurferEntry(String line) {
// You fill this in //
this.text=line.split(" ");
}
/* Method: getName() */
/**
* Returns the name associated with this entry.
*/
public String getName() {
// You need to turn this stub into a real implementation //
return text[0];
}
/* Method: getRank(decade) */
/**
* Returns the rank associated with an entry for a particular
* decade. The decade value is an integer indicating how many
* decades have passed since the first year in the database,
* which is given by the constant START_DECADE. If a name does
* not appear in a decade, the rank value is 0.
*/
public int getRank(int decade) {
// You need to turn this stub into a real implementation //
int rank;
if (decade==0 || decade==10 || decade==20 ||
decade==30 || decade==40 || decade==50 ||
decade==60 || decade==70 || decade==80 ||
decade==90 || decade==100) {
int index=(decade)/10+1;
rank=Integer.parseInt(text[index]);
}else {
rank=0;
}
return rank;
}
/* Method: toString() */
/**
* Returns a string that makes it easy to see the value of a
* NameSurferEntry.
*/
public String toString() {
// You need to turn this stub into a real implementation //
String result=text[0]+" [";
for (int i=1;i<text.length-1;i++) {
result+=text[i]+" ";
}
result+=text[text.length-1]+"]";
return result;
}
private String[] text;
}
NameSurferGraph
/*
* File: NameSurferGraph.java
* ---------------------------
* This class represents the canvas on which the graph of
* names is drawn. This class is responsible for updating
* (redrawing) the graphs whenever the list of entries changes
* or the window is resized.
*/
import acm.graphics.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
public class NameSurferGraph extends GCanvas
implements NameSurferConstants, ComponentListener {
/**
* Creates a new NameSurferGraph object that displays the data.
*/
public NameSurferGraph() {
addComponentListener(this);
// You fill in the rest //
//init();
}
/**
* Clears the list of name surfer entries stored inside this class.
*/
public void clear() {
// You fill this in //
removeAll();
list.clear();
}
//删除元素
public void deletion(NameSurferEntry entry) {
list.remove(entry);
}
/* Method: addEntry(entry) */
/**
* Adds a new NameSurferEntry to the list of entries on the display.
* Note that this method does not actually draw the graph, but
* simply stores the entry; the graph is drawn by calling update.
*/
public void addEntry(NameSurferEntry entry) {
// You fill this in //
if(list.indexOf(entry)==-1) {
list.add(entry);
}
}
public void show() {
//记录每个排名的位置
double d=(getHeight()-2*GRAPH_MARGIN_SIZE)*1.0/MAX_RANK;
//记录间距
double distance=getWidth()*1.0/NDECADES;
//记录上一年的排名
int last=0;
//画标签以及直线
for ( int j=0;j<list.size();j++) {
NameSurferEntry entry=list.get(j);
String name=entry.getName();
//设置颜色
Color c=color[j%4];
for(int i=0;i<NDECADES;i++) {
//获得年份
int year=10*i;
//System.out.println(year);
//获得数量
int num=entry.getRank(year);
GLabel text=new GLabel(name+" "+(num));
if(num==0) {
text=new GLabel(name+" *");
num=MAX_RANK;
}
text.setColor(c);
//根据增长还是下降调整位置
add(text,i*distance,GRAPH_MARGIN_SIZE+d*num-text.getHeight());
//扩展功能,增加图形点
if (j%2==0) {
GOval object=new GOval(size, size);
object.setFilled(true);
object.setColor(c);
add(object,i*distance-size/2,GRAPH_MARGIN_SIZE+d*num-size/2);
}else {
GRect object=new GRect(size, size);
object.setFilled(true);
object.setColor(c);
add(object,i*distance-size/2,GRAPH_MARGIN_SIZE+d*num-size/2);
}
//画直线
if(i>0) {
GLine line=new GLine((i-1)*distance,GRAPH_MARGIN_SIZE+d*last,
i*distance,GRAPH_MARGIN_SIZE+d*num );
line.setColor(c);
add(line);
}
//更新上一年排名
last=num;
}
}
}
/**
* Updates the display image by deleting all the graphical objects
* from the canvas and then reassembling the display according to
* the list of entries. Your application must call update after
* calling either clear or addEntry; update is also called whenever
* the size of the canvas changes.
*/
public void update() {
removeAll();
init();
show();
}
public void init() {
double distance=getWidth()*1.0/NDECADES;
for (int i=0;i<NDECADES;i++) {
add(new GLine(i*distance,0,i*distance,getWidth()));
String Year=(1900+10*i)+"";
GLabel label=new GLabel(Year);
add(label,i*distance,getHeight()-GRAPH_MARGIN_SIZE+label.getHeight());
}
add(new GLine(0,GRAPH_MARGIN_SIZE,getWidth(),GRAPH_MARGIN_SIZE));
add(new GLine(0,getHeight()-GRAPH_MARGIN_SIZE,getWidth(),getHeight()-GRAPH_MARGIN_SIZE));
}
/* Implementation of the ComponentListener interface */
public void componentHidden(ComponentEvent e) { }
public void componentMoved(ComponentEvent e) { }
public void componentResized(ComponentEvent e) { update(); }
public void componentShown(ComponentEvent e) { }
private ArrayList<NameSurferEntry> list=new ArrayList<NameSurferEntry>();
private Color[] color= {Color.BLACK,Color.RED,Color.BLUE,Color.magenta};
//private GObject object;
private int size=5;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere