2011-05-31

普物測驗軟體 原始碼–4 程式執行區、面板設計

這是整個程式核心 Main 所在位置,所有畫面製作也全在此完成。事實上我個人對這部分頗不滿意。

1. awt、swing 的標籤之類竟無法使用回圈重複製作,使得程式某些區域很醜,以下原始碼中的「**********66666666666」就是代表重複區段被我刪除了大半。

2. awt、swing 未能完全掌握,覺得應該有辦法獨立建立些類別,再於此建立物件來使用才漂亮!

3. 監聽的操作也有點問題,寫得太複雜了!也能獨立寫成類別嗎?例如上傳檔案的操作,應該獨立寫成類別才妥。

4.變數的設定誤了簡便,近乎全部都設在類別最上頭了,這似乎不太妥。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Timer;

public class swingtest extends JFrame implements ActionListener{
    private static final long serialVersionUID = 1L;    // Eclipse 自動產生的 ID
   
    static File wf= new File("C:\\phylab.txt");
   
    static Font f = new Font("新細明體",Font.PLAIN,15);
       
    /* 建立程式主選單 */
    static MenuBar mb=new MenuBar();
    static Menu menu0=new Menu("  ");    // 只是用來讓下一個 menu 的字體正常
    static Menu menu1=new Menu("↑↑↑ 傳送成績 ↑↑↑");
    static MenuItem mi11=new MenuItem("  傳送  ");
    static MenuItem mi12=new MenuItem("    否   ");
    static Menu menu2=new Menu("     關閉作答程式     ");
    static MenuItem mi21=new MenuItem("  關閉  ");
    static MenuItem mi22=new MenuItem("    否   ");    //按鍵無法共用,各自都要建立
    static Menu menu3=new Menu("   ");
    static MenuItem mi31=new MenuItem("    ");
   
    /* 建立分頁選單 */
    static JTabbedPane tp=new JTabbedPane(JTabbedPane.TOP);
    static JPanel[] panels=new JPanel[8];
   
    /*  利用延伸自 JFrame 父類別所建立的 swingtest 類別建立 frm 主框架 (swingtest 為本類別的名稱)*/
    static swingtest frm=new swingtest();
    static Container cp=frm.getContentPane();    // 在 JFrame 中需先建立一個 frame 的容器 Container
    static Button btn=new Button(" 準備好後  點此開始作答");
    static int timeini, time;
    static Button btnupload=new Button("(這是個按鈕) 上傳成績 ");
   
    static Label lab01=new Label(), **********6666
    
    /*     建立文字輸入物件 (也無法以陣列方式建立)*/
    static TextField tex0=new TextField();
    
    /*建立計分按鈕*/
    static swingtest frNaNu=new swingtest();
    static Container NaNu=frNaNu.getContentPane();
   
   
    static TextField txf1=new TextField("請輸入姓名");
    static TextField txf2=new TextField("請輸入學號");
//*關閉 server 用*        static TextField txf1=new TextField("close");
  //*關閉 server 用*    static TextField txf2=new TextField("close");
//    static TextField txf3=new TextField("助教電腦 IP");
    static TextField txf3=new TextField("192.168.0.101");
//    static TextField txf3=new TextField("127.0.0.1");
//    static TextField txf3=new TextField("140.121.179.194");
//    static TextField txf4=new TextField("");
   
    static Container AL01, **********6666
   
    static boolean timeup=false;
    static boolean nametxt=false;
    static boolean numbertxt=false;
    static boolean assiptxt=false;
   
   
    static JLabel lab000=new JLabel("<html>1. 作答前需輸入姓名、學號、助教電腦 IP,否則無法作答<br />2. 每實驗項目各三題選擇題,共 21 題,請點選各實驗項目分頁作答<br />★★★3. 作答完畢後,請回到本分頁,點選下面「作答完畢後點此按鈕  顯示得分」按鈕察看分數<br />4.最後點擊最上方工具列「傳送成績」再「關閉作答程式」。</html>" );
    static Button CalScoreButton=new Button("(這是個按鈕) 作答完畢後點此按鈕  顯示得分");
    static JLabel labspace=new JLabel("作答結束");
    static JLabel labinf=new JLabel(" ", JLabel.CENTER);
    static JLabel labinf2=new JLabel(" ", JLabel.CENTER);
   
    static int Ndefault=0;
    static int Nsave=0;
    static String EQC[][][][];

    public static void main (String args[]) throws IOException{
        
        UIManager.put("Button.font", f);
        UIManager.put("CheckBox.font", f);
        UIManager.put("CheckBoxMenuItem.acceleratorFont", f);
        UIManager.put("CheckBoxMenuItem.font", f);
        UIManager.put("ColorChooser.font", f);
        UIManager.put("FormattedTextField.font", f);
        UIManager.put("InternalFrame.titleFont", f);
        UIManager.put("Label.font", f);
        UIManager.put("JFrame.font", f);
        UIManager.put("List.font", f);
        UIManager.put("Menu.acceleratorFont", f);
        UIManager.put("Menu.font", f);
        UIManager.put("MenuBar.font", f);
        UIManager.put("MenuItem.acceleratorFont", f);
        UIManager.put("MenuItem.font", f);
        UIManager.put("OptionPane.font", f);
        UIManager.put("Panel.font", f);
        UIManager.put("RadioButton.font", f);
        UIManager.put("RadioButtonMenuItem.acceleratorFont", f);
        UIManager.put("RadioButtonMenuItem.font", f);
        UIManager.put("Spinner.font", f);
        UIManager.put("TabbedPane.font", f);
        UIManager.put("Table.font", f);
        UIManager.put("TableHeader.font", f);
        UIManager.put("TextArea.font", f);
        UIManager.put("TextField.font", f);
        UIManager.put("TextPane.font", f);
        UIManager.put("TitledBorder.font", f);
        UIManager.put("ToggleButton.font", f);

        
        /*建立初始檔案*/
        wf.delete();
        final BufferedWriter bfw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(wf.toString(), true),"big5"));
        try{
              bfw.write("01,"+"9");    //寫入 txt 的文字加上一個"," ,以避免擷取題號的時候,發生與題目中出現同樣的數字
              bfw.newLine();            // 每題設定的 9 代表本題尚未作答,作答後 9 會變成 5 或 0
              **********6666
        }catch(IOException e){}
        bfw.flush();
//          wf.close();
       
            RExps RE=new RExps();    // 利用自建的 RExps 類別來創見隨機實驗項目、題目排序陣列
            EQC=RE.RE2(7,7,7);    //method 回傳值取得排列結果
       
            /* 以 RExps 所排列的項目名稱,建立分頁標題陣列 */
            String[] titles = new String[]{"測驗說明", "一. "+EQC[0][6][0][0], "二. "+EQC[1][6][0][0], "三. "+EQC[2][6][0][0], "四. "+EQC[3][6][0][0], "五. "+EQC[4][6][0][0], "六. "+EQC[5][6][0][0], "七. "+EQC[6][6][0][0]};
       
            /*  建立各標題陣列內容*/
            final int row = 6;
            final int column = 0;
            for(int i=0; i< panels.length; i++){
                panels[i] = new JPanel();        //以 JPanel 將面板物件建立出來
                panels[i].setBackground(Color.white);
                panels[i].setLayout(new GridLayout(row, column));
                tp.addTab(titles[i],null,panels[i],titles[i]+"*");    // 將前面建立的分頁項目名稱分別帶入各分頁
            }
     
            /*排列實驗項目*/
            String[][] Ques = new String[][]{{"1. "+EQC[0][1][0][1], "2. "+EQC[0][2][0][1], "3. "+EQC[0][3][0][1]}, {"1. "+EQC[1][1][0][1], "2. "+EQC[1][2][0][1], "3. "+EQC[1][3][0][1] }, {"1. "+EQC[2][1][0][1], "2. "+EQC[2][2][0][1], "3. "+EQC[2][3][0][1]}, {"1. "+EQC[3][1][0][1], "2. "+EQC[3][2][0][1], "3. "+EQC[3][3][0][1]}, {"1. "+EQC[4][1][0][1], "2. "+EQC[4][2][0][1], "3. "+EQC[4][3][0][1]}, {"1. "+EQC[5][1][0][1], "2. "+EQC[5][2][0][1], "3. "+EQC[5][3][0][1]}, {"1. "+EQC[6][1][0][1], "2. "+EQC[6][2][0][1], "3. "+EQC[6][3][0][1]}};
     
            /*建立各實驗題目的選項列陣*/
            final String AnsList01[]={EQC[0][1][1][2], EQC[0][1][2][2], EQC[0][1][3][2], EQC[0][1][4][2]};
            **********6666
     
          /*建立各實驗題目的答案列陣*/
          final String ScoList01[]={EQC[0][1][1][3], EQC[0][1][2][3], EQC[0][1][3][3], EQC[0][1][4][3]};
          **********6666
      
          AL01 = ChoButtonGro.CreateChoseButtonGroup(AnsList01, ScoList01, EQC[0][1][0][2]);
          **********6666
          
          AL01.setVisible(false);
          **********6666
      
          lab01.setText(Ques[0][0]);
          lab02.setText(Ques[0][1]);
          lab03.setText(Ques[0][2]);
          panels[1].add(lab01).setFont(new Font("標楷體",java.awt.Font.BOLD,16));
          panels[1].add(AL01);
          panels[1].add(lab02).setFont(new Font("標楷體",java.awt.Font.BOLD,16));
          panels[1].add(AL02);
          panels[1].add(lab03).setFont(new Font("標楷體",java.awt.Font.BOLD,16));
          panels[1].add(AL03);
          **********6666
     
     
          btn.addActionListener(frm);
          NaNu.setLayout(null);
          txf1.setBounds(200, 30, 120, 20);
          txf2.setBounds(330, 30, 120, 20);
          txf3.setBounds(500, 30, 130, 20);
//          txf3.setEditable(false);
//          txf4.setBounds(495, 20, 20, 20);
          btn.setBounds(670, 30, 200, 25);
          NaNu.add(txf1);
          NaNu.add(txf2);
          NaNu.add(txf3);
//          NaNu.add(txf4);
          NaNu.add(btn);
          
          panels[0].add(lab000).setFont(new Font("微軟正黑體",java.awt.Font.PLAIN,16));
           panels[0].add(NaNu).setFont(new Font("微軟正黑體",java.awt.Font.PLAIN,16));
          panels[0].add(CalScoreButton).setFont(new Font("微軟正黑體",java.awt.Font.PLAIN,16));        //加入計分按鈕
          panels[0].add(labinf).setFont(new Font("微軟正黑體",java.awt.Font.PLAIN,18));
          panels[0].add(labinf2).setFont(new Font("微軟正黑體",java.awt.Font.PLAIN,18));
          panels[0].add(btnupload).setFont(new Font("微軟正黑體",java.awt.Font.PLAIN,18));
          CalScoreButton.addActionListener(frm);
          CalScoreButton.setBounds(20, 20, 100, 100);
          btnupload.setVisible(false);
         
          tp.setBounds(0,0,1000,600);    //    設定分頁選單大小
     
          frm.add(tp);

          // 建立選單系統

          frm.setMenuBar(mb);
          mb.add(menu1);
          mb.add(menu2);
          mb.add(menu3);
          menu1.add(mi11);
          menu1.add(mi12);
          menu2.add(mi21).setEnabled(true);    //視窗關閉
          menu2.add(mi22);
          menu3.add(mi31);
       
         
          mi11.addActionListener(frm);
          mi12.addActionListener(frm);
          mi21.addActionListener(frm);
          mi22.addActionListener(frm);
          mi31.addActionListener(frm);
          btnupload.addActionListener(frm);
       

          // 建立選單系統
          cp.setLayout(null);
          frm.setSize(1010,650);
          frm.setVisible(true);
          frm.setTitle("99學年度 第二學期 普物實驗期末線上測驗");
         
          frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
   
   
    public void actionPerformed(ActionEvent e){
               
        if(e.getSource()==mi21){//利用 e.getSource==Object 判斷點擊的對象
            time=0;
            frm.dispose();
        }
       
        if(e.getSource()==mi11||e.getSource()==btnupload||e.getSource()==mi31){
//*關閉 server 用*                Ndefault=1;
            if(Ndefault==1){    // 確定作答完畢才可以傳送檔案
               
           
            try{
                byte buff[]=new byte[1024];   //*******
                String sip=txf3.getText();
                labinf.setText(" 連結伺服器中 ... ...");
//                Socket skt=new Socket("127.0.0.1", 2525);
//                Socket skt=new Socket("140.121.179.194", 2525);
                Socket skt=new Socket(sip, 2525);
                labinf.setText(" 連線成功 !!");
               
                FileInputStream fout = new FileInputStream("C:\\phylab.txt");    // Stream 的輸出、入都以 byte 模式
                byte bout[]=new byte[fout.available()];    //記憶體建立所要顯示的空間大小
                fout.read(bout);    //將檔案寫入記憶體               
                labinf.setText(" 資料轉換,準備傳送 ...");
               
                OutputStream out=skt.getOutputStream();
                out.write(bout);
                labinf.setText(" 資料傳送中 . .. ... ");
               
                InputStream in=skt.getInputStream();    //接受伺服器回傳值
                int n=in.read(buff);//***********
                String backinf=new String(buff,0,n);
                labinf.setText("伺服器回應:"+backinf+" 您的得分 "+Nsave+" 分");//***********
                in.close();//***********
                
                out.close();    //關閉字串輸出
                fout.close();//關閉字串寫入記憶體
                skt.close();//關閉連線
                mi11.setEnabled(false);
                btnupload.setEnabled(false);
            }
            catch(Exception e2){
                labinf.setText(" 檔案傳送失敗(伺服器無回應) 請快呼叫助教 ");
            }
             }
            else{
                labinf.setText(" 未作答完畢不可上傳資料 ");
            }
        }
        
        if(e.getSource()==btn){
           
            if(txf3.getText().equals("助教電腦 IP")){
                labinf.setText("輸入「助教電腦 IP」後才可作答");
            }
            else{assiptxt=true;}
            if(txf2.getText().equals("請輸入學號")){
                labinf.setText("輸入「學號」後才可作答");
            }
            else{numbertxt=true;}
            if(txf1.getText().equals("請輸入姓名")){    //文字的比較不可使用 ==,需使用 equals
                labinf.setText("輸入「姓名」後才可作答");
            }
            else{nametxt=true;}
           
            if((nametxt==true && numbertxt==true )&& assiptxt==true){
            btn.setVisible(false);
            try{
                final Timer t = new Timer();
                timeini =60*15+6;        // 設定考試時間
                time = timeini;
                TimerTask tt = new TimerTask(){
                    public void run(){
                        int mins=time/60;
                        int secs=time-mins*60-1;
                       
                        if(time >0){
                            time--;
                            if(time<890){
                                mi21.setEnabled(true);
                            }
                            labinf2.setText("剩餘時間:"+mins+" 分 "+secs+" 秒");
             
                            AL01.setVisible(true);
                            **********6666
                        }
                   
                        if(time==0){
                           
                            AL01.setVisible(false);
                            **********6666
                            timeup=true;
                            t.cancel();
                        }
                    }
                };

                    t.scheduleAtFixedRate(tt,0,1000);

            }
            catch(Exception e3)
            {
            }
            }
        }
       

        if(e.getSource()==CalScoreButton){
            try{
            FileInputStream fi = new FileInputStream("C:\\phylab.txt");
            byte ba[]=new byte[fi.available()];
            fi.read(ba);
           
            int N01= Integer.valueOf(new String(ba).lastIndexOf("01,"));
            **********6666
           
            int UNs=0;
           
            int Ns01=Integer.valueOf(new Character((char)(new String(ba).charAt(N01+3))).toString());
            if(Ns01==9){
                Ns01=0;
                UNs=UNs+1;
            }
            **********6666
            labinf.setText("尚有 " +UNs+" 題未作答耶!作答完畢才計算分數喔!");
           
           
//*關閉 server 用*            UNs=0;   
            if(UNs==0||timeup==true){
                int timefinal = time;
                time=1;
                // 未完全作答完畢就不計算分數
                int Ntotal = Ns01+Ns02+Ns03+Ns11+Ns12+Ns13+Ns21+Ns22+Ns23+Ns31+Ns32+Ns33+Ns41+Ns42+Ns43+Ns51+Ns52+Ns53+Ns61+Ns62+Ns63;
                if(Ndefault==0){
                    Nsave=Ntotal;
                    labinf.setText("您本次普物實驗期末考成績為 " +Ntotal+ " 分,作答時間 "+(timeini-timefinal)/60+" 分 "+((timeini-timefinal)-((timeini-timefinal)/60)*60)+" 秒。下方「上傳成績」按鈕傳送成績!!");
                    btnupload.setVisible(true);
                    panels[1].removeAll();
                    panels[1].add(lab01).setFont(new Font("標楷體",java.awt.Font.BOLD,16));
                    panels[1].add(lab02).setFont(new Font("標楷體",java.awt.Font.BOLD,16));
                    panels[1].add(lab03).setFont(new Font("標楷體",java.awt.Font.BOLD,16));
                    **********6666
                   
                    File fw= new File("C:\\phylab.txt");
                    BufferedWriter bfw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fw.toString(), true),"big5"));
                    bfw.write("Name:"+txf1.getText()+", Number:"+txf2.getText()+",  Score:"+Ntotal+"分"+" end."+" 作答時間:"+(timeini-timefinal)/60+" 分 "+((timeini-timefinal)-((timeini-timefinal)/60)*60)+" 秒");
                    bfw.flush();
                   
                }
                if(Ndefault==1){  //關閉程式時是否刪除檔案
                    labinf.setText("已作答完畢,成績為 " +Nsave+" 分,請上傳成績!!");
                }
                Ndefault=1;
            }
            fi.close();
        }
        catch(IOException e1)
        {
        }
        }
    }
       
}

沒有留言: