1. 程式人生 > >Java新手專案之第一個專案(一)2016.5.16-5.22

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();
                }
            });
        }
    }
}

諸多瑣事,沒有時間細細講解。直接上程式碼吧。