Java新手專案之第一個專案(一)2016.5.16-5.22
Java學生選課教務系統
作為學習Java的新手,之前學過點Java的基礎,後來又看了看網易雲課堂的java,總共差不多兩個月的時間吧,陸陸續續跟著書和視訊編了一些程式。馬上也要畢業,現在開始,希望能夠寫一些新手,進階,高階專案經歷。一方面,是對自己實踐的一個總結反思學習的過程,另一方面,也是對自己職業的一個管理。
經驗現在明顯不足。有很多沒有考慮到的地方,嘛嘛,總是要從入門到放棄的嘛,留在這,供高手娛樂消遣,供自己回憶吐槽:-D
無論如何,程式設計師這一行算是準備開始了/(ㄒoㄒ)/~~少年,邁上不歸之路吧!Let’s go! All in!
介面設計以及功能分析
寫在分析前
因為趕上畢業,所以希望能馬上完事,照著實現最簡單的功能來,爭取一週完事。說易行難,一看網上的各種分析,立馬畏難情緒上來了,這各種各樣的類,介面,功能,我完全無從下手啊。啊啊啊啊,這怎麼辦啊,雖然之前也做過小的專案,也知道甭管難不難,先去下手做就行,碰到問題,就解決問題唄。可這次問題是,我不知道從哪入手。這不就無語凝噎了嗎?刷了重新整理聞,哎,又被Unix的發明者的故事給虐了,你說人家20出頭的時候已經能幹出這麼前無古人,很有可能後無來者的牛逼的事來,而逗逼如我,以臨近畢業之勢,剛剛開始學習java,這還有啥好奮鬥的?大晚上的從實驗室出來,簡直是生無可戀有木有~。
偉大的某個偉人說過,想不通的時候要麼吃飯,要麼睡覺。一覺醒來,挫敗感少了,頭腦也清醒許多了,想了想,管他呢,就從如果我是使用者,我要選課的流程是啥,首先幹啥,接著怎麼了(有沒有產品設計的趕腳。。。),那我就從這個入手,按照使用者操作來,需要啥寫啥。需要啥,就打包到類裡,提供統一面向外部的介面,然後打包到包裡。。。不知道這樣想對不對,反正這麼一頓遇到問題解決問題下來,也整了個系統出來。好壞不說,自己設計的第一個獨立的小系統,還是有成就感的。所以還是記錄下來,若干年後,再來自打臉。。。
第一個專案為了打基礎,會寫的詳細一些,以後會簡寫。(ps. 第一次用markdown寫,文字都在一行了,後來發現,是不要隨便敲空格啊,實在不行,複製一下最開始使用時跳出來的那個介紹markdown的介面作為模板,然後就知道咋回事了。。。原諒我這笨拙的人生吧。。)
- 深深體會到不知道的太多
- 要時刻網上查閱
- 還有下載一個jdk API文件
- 以及熟練使用alt+/輔助輸入
- 以及Ctrl+待檢視的類和方法
介面設計,功能分析
好,扯淡夠了,言歸正傳。平臺採用從Eclipse官網裡下載的eclipse for java軟體平臺,然後配置了一下jre 用的是jre 1.7。說到這裡,也是之前很困惑,然後上網查閱。
寫java程式,不用專門的eclipse,而是下載jdk軟體包,然後配置classpath,再呼叫javac編譯,java來執行。這種情況下,jdk軟體包包含jre和一些開發工具,主要是javac和java(呼叫虛擬機器)。jre是java執行引擎,是使用者安裝使用,它包含庫lib以及java,用來呼叫使用者的java虛擬機器,執行java程式。而jdk是開發人員使用,它包含javac等用來開發的工具。而java虛擬機器在jre中,因為java是跨平臺執行在各系統中,它需要一個虛擬機器幫助實現這個。至於配置classpath,則是可以實現在計算機任何位置都能呼叫javac和java的作用。而eclipse for java 有自己的編譯器,直接下載安裝,然後在build path 裡選擇jre 1.7(或者其他)即可使用。另外有些方法是不適合較早版本的編譯器的,因此,我經常直接把編譯器改成1.7版本的。接下來繼續說專案吧。
主介面–學生選課系統登入介面
首先學生選課系統主介面,應該是一個登入系統,和大部分你見過的一樣,直接上圖(醜陋style,用的是swing)
好了,可以看到,首先我們要設計一個MyFrame繼承JFrame類,把圖中相應的Component物件設計好(剛開始把密碼框弄成了JTextFiled類了,應該是JPasswordFiled類,專門為密碼輸入提供的,還有使用者名稱框不要用JTextArea類,這是一大塊文字輸入域,用JTextFiled類,一行即可)。
接著就是放置這些元件到MyFrame裡了,在放置的時候,需要注意佈局,通常我會採用在主JPanel類物件裡,採用GridLayout佈局,然後在每一行的JPanel類物件裡,預設使用FlowLayout佈局(可以設定放在左右位置),把主JPanel放置在MyFrame(預設BorderLayout的CENTER位置上)
可以在函式ini()裡實現,然後是註冊元件的事件監聽器,我用到的一般是按鈕(JButton)的addActionlistener(new Acitonlistener(){//在這裡面實現處理事件};)在register()函式裡實現,接著將這兩個函式放到MyFrame建構函式裡,最後在建構函式裡將視窗的visible(),置為true;
接著,我們分析使用者登入流程,當用戶還沒點選登入的時候,要在介面顯示如上圖,那首先得實現產生驗證碼的功能,Java是面向物件的嘛,在我理解就是能打包成一個類的弄成一個類,提供類面向外部的介面,因此可以把這個產生驗證碼的功能放在Tools類中實現;
當用戶點選登入的時候,也就是要實現登入按鈕的註冊事件,首先獲取使用者輸入的資訊,然後接下來就是連線資料庫,查詢使用者名稱和密碼的正確性。所以需要一個數據庫,庫裡有user表,含有使用者名稱,密碼,使用者許可權(設定1對應管理員,2對應教師,3對應學生,這是為了登陸後彈出相應的介面),也應該有student,teacher這些使用者,以及course表。相應的在Java裡要設計類,有User類,然後是繼承User類的Student類和Teacher類,和資料庫中的表相對應。同時有一個Course類,用來記錄課程,選課的老師,以及選課的學生。
接著登入功能來說,在登入註冊事件裡,需要接收使用者輸入,驗證登入正確性。驗證正確性,可以在UserManage這個操作User類中實現,即實現login方法,提供使用者輸入的資訊,在login裡應該實現連線資料庫,獲取Connection物件,使用PreparedStatement,傳送sql語句,獲取ResultSet,然後驗證輸入的正確性。
選資料庫的時候,最開始選了SQLite資料庫,適合嵌入,後面對多使用者併發讀寫支援不好,可能是我沒弄好,所以棄了,選擇了SQL Server資料庫,這個資料庫使用,首先要在配置管理器裡啟動sql server服務,切記切記。
Java的jdbc可以通過下載的資料庫驅動包,實現對各類資料庫的統一呼叫方法,包括Class.forName(“驅動”),Connection DriverManager.getConnection(“協議+路徑”)。因此選擇好資料庫,然後下載相應的驅動檔案包(.jar),然後將其build path進Libarary中,就可以直接呼叫以上方法了。而這兩個函式裡所需的字串,可以通過解析xml檔案實現,將解析過程設為MyFrame的靜態程式碼塊,只執行一次。xml解析也有兩種,考慮到解析較小檔案和提高效率,選用了DOM解析,先讀進記憶體,再遍歷樹。在login裡實現連線。然後就是傳送sql語句了。Statement類不能使用引數,因此使用PreparedStatement,用?代替引數,如
String str="select * from user where uname=?"
PreparedStatement ps=conn.getPreparedStatement(str);
ps.setString(1,name)
將這個傳送過程,放進Tools裡去實現PreparedStatement sqlBuilder(String str,Object obj[])。接著利用返回的ps,得到ResultSet rs,然後就是利用rs的next()函式,獲取從資料庫中得到的查詢的值,然後判斷使用者名稱與密碼的正確性。若正確,就要考慮寫登入日誌了,記錄登入時間和使用者,放在Record類裡,登出時間,在某個使用者登出後記錄,然後是通過I/O將Record物件寫入/讀出檔案中。寫物件,用ObjectOutputStream。
這個MyFrame作為gui,可以將放在com.my.gui包裡。具體public class MyFrame{},Tools類,User類,Student類,Teacher類,Course類,UserManage類,實現在文末統一給出。其實,很多類都是基本定了,然後缺啥補啥。。
最後,注意一些使用的友好性,在登入時,對某些使用者的一些操作,如輸入為空,點選叉號等,要及時彈出對話方塊,因此要設計一個MyDialog類繼承JDialog類,實現對話功能。然後就是驗證碼輸入不對,重輸之前,要清零等一些友好設計,想象一下,作為使用者的你,面對一些不友好設計時的各種吐槽吧~
接下來,就是分別設計管理員系統介面,學生系統介面,教師系統介面,以及資料庫的設計了。
程式附錄
主介面MyFrame;
有些編寫,本文未提到的,後面會介紹
package com.my.gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import com.my.beans.Record;
import com.my.beans.Student;
import com.my.beans.Teacher;
import com.my.beans.User;
import com.my.manage.UserManage;
import com.my.util.Tools;
public class MyFrame extends JFrame{
private Container pn;
private JPanel pn_name,pn_pwd,pn_code,pn_login;
private JLabel label,label_name,label_pwd,label_code;
private JTextField filed_name,filed_code,field_code_play;
private JPasswordField pwd;
private JButton login;
private String uname;
private String upwd;
private String code;
private String codePlay;
private UserManage um=null;
private Record record=null;
private Date inTime;
private Date outTime;
private User user=null;
private AdmisterGUI agui=null;
private TeacherGUI tgui=null;
private StudentGUI sgui=null;
public UserManage getUm() {
return um;
}
public MyFrame()
{
ini();
register();
this.setVisible(true);
}
public void ini()
{
this.setSize(400,300);
this.setTitle("學生選課教務系統");
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
pn=new Container();
pn_name=new JPanel();
pn_pwd=new JPanel();
pn_code=new JPanel();
pn_login=new JPanel(new FlowLayout(FlowLayout.RIGHT));
label=new JLabel("登入");
label_name=new JLabel("賬戶", JLabel.CENTER);
label_pwd=new JLabel("密碼", JLabel.CENTER);
label_code=new JLabel("驗證碼", JLabel.CENTER);
filed_name=new JTextField(20);
field_code_play = new JTextField(9);
filed_code=new JTextField(9);
pwd=new JPasswordField(20);
login=new JButton("登入");
//窗體居中
Toolkit kit=Toolkit.getDefaultToolkit();
Dimension dm=kit.getScreenSize();
this.setLocation((dm.width-this.getWidth())/2, (dm.height-this.getHeight())/2);
//放置
pn_name.add(label_name);
pn_name.add(filed_name);
pn_pwd.add(label_pwd);
pn_pwd.add(pwd);
pn_code.add(label_code);
pn_code.add(filed_code);
//呼叫tools類產生驗證碼,並顯示在介面上
codePlay=Tools.codeGen();
field_code_play.setText(codePlay);
field_code_play.setHorizontalAlignment(JTextField.CENTER);
pn_code.add(field_code_play);
pn_login.add(login);
pn.setLayout(new GridLayout(4, 1));
this.add(label,BorderLayout.NORTH);
pn.add(pn_name);
pn.add(pn_pwd);
pn.add(pn_code);
pn.add(pn_login);
this.add(pn,BorderLayout.CENTER);
}
public void register()
{
login.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
um=new UserManage();
uname=filed_name.getText();
upwd=pwd.getText();
code=filed_code.getText();
if("".equals(uname)||"".equals(upwd))
{
//自定義對話方塊 MyDialog 彈出提示
new MyDialog("賬戶和密碼不能為空!");
}
else
{
if("".equals(code)){
new MyDialog("驗證碼不能為空!");
}
else if(code.equalsIgnoreCase(codePlay))
{
//呼叫UserManage類 login方法
user=um.login( uname,upwd);
if(user==null){
new MyDialog("賬戶和密碼不正確!");}
else
{
//重複登入 驗證碼清零
codePlay=Tools.codeGen();
field_code_play.setText(codePlay);
field_code_play.setHorizontalAlignment(JTextField.CENTER);
//清空輸入
filed_code.setText("");
record=new Record();
record.setUser(user);
inTime= new Date(Calendar.getInstance().getTimeInMillis());
record.setInTime(inTime);
//判斷uright,呼叫管理員、教師、學生視窗
int uright=user.getUright();
if(uright==1)//管理員
{
agui=new AdmisterGUI(record,MyFrame.this);////在裡面實現 視窗退出 寫登入日誌
}
else
if(uright==2)//教師
{
Teacher teacher=(Teacher)user;
tgui=new TeacherGUI(record,MyFrame.this,teacher);////在裡面實現 視窗退出 寫登入日誌
}
else
{
Student student=(Student)user;
sgui=new StudentGUI(record,MyFrame.this,student);////在裡面實現 視窗退出 寫登入日誌
}
}
}
else
{
new MyDialog("驗證碼不正確!");
//呼叫tools類產生驗證碼,並顯示在介面上
codePlay=Tools.codeGen();
field_code_play.setText(codePlay);
field_code_play.setHorizontalAlignment(JTextField.CENTER);
//清空輸入
filed_code.setText("");
}
}
}
});
//主視窗正在關閉 釋放資源
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
if(um!=null){
um.closeConnection();}
((MyFrame)e.getSource()).dispose();
System.exit(0);
}
});
}
//自定義對話方塊
class MyDialog extends JDialog{
private JLabel msg;
private JButton ok;
private JPanel pne;
public MyDialog(String msg)
{
ini( msg);
register();
MyDialog.this.setVisible(true);
}
public void ini(String msg)
{
MyDialog.this.setSize(300,100);
//窗體居中
Toolkit kit=Toolkit.getDefaultToolkit();
Dimension dm=kit.getScreenSize();
MyDialog.this.setLocation((dm.width-MyDialog.this.getWidth())/2, (dm.height-MyDialog.this.getHeight())/2);
pne=new JPanel();
pne.setLayout(new GridLayout(2, 1));
MyDialog.this.msg=new JLabel(msg, JLabel.CENTER);
MyDialog.this.ok=new JButton("確定");
pne.add(MyDialog.this.msg);
pne.add(MyDialog.this.ok);
MyDialog.this.add(pne,BorderLayout.CENTER);
}
public void register()
{
MyDialog.this.ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MyDialog.this.dispose();
}
});
}
}
}
諸多瑣事,沒有時間細細講解。直接上程式碼吧。