新開了一門外教課程,Object-oriented Programming(JAVA), 記錄一些學習經驗,以及部分和c++的區別感悟。本文為降雨繪圖作業demo, 大概要求是從一個.text檔案中找到使用者從console中輸入的城市,並將該城市的12個月的降雨量資料繪製。要求是不可以使用array等容器提前儲存資料,必須輸在使用者輸入後,在.text檔案中找到目標城市並繪圖。text檔案格式如下:
…
Beijing 20.8 52.4 67.3 22.3 55.0 76.3 20.8 52.4 67.3 22.3 55.0 76.3
…
package assignment;
import java.awt.*;
import java.util.*;
import java.io.*;
public class RainfallPlotter {
private static final int MONTH_WIDTH = 70;
private static final int NAME_WIDTH = 100;
private static final int HEIGHT = 550;
private static final int LINE_OFFSET = 25;
private static final int WIDTH = 12 * MONTH_WIDTH;
private static final Color[] COLORS = { Color.RED, Color.BLUE, Color.GREEN };
// global para of color index
public static int I = -1;
private static final String STOP = "stop";
private static final String[] MONTHS_NAME = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
// relative path
private static final String DATA_FILE = "./rainfall.txt";
// object panel is used in all process-life, and never changed.
private static final DrawingPanel panel = new DrawingPanel(WIDTH, HEIGHT);
// object g is used in three method of my solution.
private static final Graphics g = panel.getGraphics();
/**
* The main program
* Plus. If the user input the four city it will be wrong. Maybe use the para I
* as the while loop stop condition( || )can solve this question.
*/
public static void main(String[] args) throws FileNotFoundException {
menuOpen();
// draw the panel.(No data)
drawingPanel();
// Scanner for console input of user
Scanner consol_input = new Scanner(System.in);
do {
System.out.print("City? ");
} while( readDbFile(consol_input) );
consol_input.close();
menuClose();
}
private static void menuOpen()
{
System.out.println("Welcome to the Rainfall Plotter program!");
System.out.println("You can plot the rainfall for up to 3 cities");
System.out.println("You can stop plotting by entering 'stop' as the name of the city");
}
private static void menuClose()
{
System.out.println("Thank you for using the Rainfall Plotter program!");
}
//
private static boolean readDbFile(Scanner consol_input) throws FileNotFoundException
{
String answer = consol_input.nextLine().trim();
// Scanner for user input
if (answer.equals(STOP)) { return false; } // 比 == 好用
// Scanner for load file
Scanner input_file = new Scanner(new File(DATA_FILE));
while ( input_file.hasNextLine() ) {
String line = input_file.nextLine();
// Scanner for every row
Scanner input_line = new Scanner(line);
//注意這裡不可以直接用input_line與string比較
String city = input_line.next(); //每next一次都往下移
// find city
if (city.equals(answer)) // java 風格 相等
{
// draw point on the panel
drawingPoint(input_line, answer);
// scanner close. Draw over
input_line.close();
return true;
}
input_line.close();
}
input_file.close();
System.out.println("City not found.");
return true;
}
//
private static void drawingPoint(Scanner city, String answer)
{
// draw city name on the panel(avoid overlap too), and set the color.
// I is index of color.
++I;
g.setColor(COLORS[I]);
g.drawString(answer, NAME_WIDTH * I, LINE_OFFSET-5);
// i and j is index of month
int i = 0;
double temp_point_next = 0;
while ( city.hasNext() )
{
double temp_point = city.nextDouble();
drawNum(temp_point, i);
if (i != 0) { drawColorLine(temp_point, temp_point_next, i, i-1); }
for (int j = i+1; j < i+2; j++)
{
temp_point_next = city.nextDouble();
drawNum(temp_point_next, j);
drawColorLine(temp_point, temp_point_next, i, j);
}
i = i + 2;
}
}
private static void drawColorLine(double temp_point, double temp_point_next, int i, int j)
{
int point1 = doubleToIntPoint(temp_point);
int point2 = doubleToIntPoint(temp_point_next);
g.drawLine(MONTH_WIDTH * i - 5, HEIGHT - (LINE_OFFSET + point1), MONTH_WIDTH * j -5, HEIGHT - (LINE_OFFSET + point2));
}
private static void drawNum(double temp_point, int i)
{
String num = String.valueOf(temp_point);
int point = doubleToIntPoint(temp_point);
g.drawString(num, MONTH_WIDTH * i, HEIGHT - (LINE_OFFSET + point));
}
private static int doubleToIntPoint(double target)
{
target = (target * 10) / 3;
int point = (int)target;
return point;
}
private static void drawingPanel()
{
g.drawLine(0, LINE_OFFSET, WIDTH, LINE_OFFSET);
g.drawLine(0, HEIGHT-LINE_OFFSET, WIDTH, HEIGHT-LINE_OFFSET);
for (int i = 0; i < MONTHS_NAME.length; i++)
{
g.drawString(MONTHS_NAME[i], MONTH_WIDTH * i, HEIGHT);
// "-5" to avoid "line" and "month text" overlap. For beauty
g.drawLine(MONTH_WIDTH * i - 5, LINE_OFFSET, MONTH_WIDTH * i -5, HEIGHT);
}
}
}