用SWT可視化工具快速開發GUI應用

一、開發背景介紹:

     1. 要開發什麼工具?

    最近和公司裏的幾位同事湊錢買了個的士發票打印機(報銷用,你懂的^_^),內容可自己寫,比如金額,時間,路程等等。發票內容的輸出位置和文字樣式要跟真實發票的一樣,否則容易穿幫(嘻嘻...)。但位置、樣式要手工調,非常麻煩。所以如果有個工具能夠幫助我們調好位置和文字樣式的話,那就方便省事多了!!
    2. 爲什麼強調要快速開發?
    其實已經有個同事開發出這樣的工具了,所以一開始我也沒想過再造一個出來。但是當我好奇的問他用什麼語言開發的時候,他來了句“你可以自己開發一個嘛!我用C#啊!”!我如果沒理解錯,這是向我宣戰了。而我接受了這個挑戰。那天是週五快下班的時候,我決定下週一給他看看我的版本!
    3.我爲什麼選擇SWT,而不選擇Swing?
    Swing有太深的Java UI的烙印--UI控件的風格過於簡陋。既然要PK,起碼外觀上不能輸。而SWT的好處是它會調用底層操作系統提供的UI控件,因此UI風格比較友好,用戶覺得親切熟悉。還有一個好處是可在Eclipse上進行SWT可視化開發,這能極大提高開發速度!就它了!
 
終於說到正題了。
   二、準備工作
       1.Eclipse我用的是3.5 Galileo。
       2.可視化工具:WindowBuilder ,可通過Eclipse在線安裝,這裏不多說了,可google下。
       3.jar包轉exe工具:Jsmooth。
 
  三、     實際開發
     1. 先看看成果
 
      
       
 
      

   2. 開發要點

      2.1讀取Excel文件將內容顯示到表格中
 
      核心代碼如下:
      2.1.1 “導入”按鈕的觸發動作
 
  1. Button button_1 = new Button(shell, SWT.NONE); 
  2. button_1.addSelectionListener(new SelectionAdapter() { 
  3.       @Override 
  4.       public void widgetSelected(SelectionEvent selectionevent) { 
  5.                         String filePath = text.getText(); 
  6.                         showProgressDialog(filePath); 
  7.                   } 
  8.             }); 
        2.1.2 顯示進度條
 
  1.     private void showProgressDialog(final String filePath) { 
  2.         try { 
  3.              final Display display = Display.getCurrent(); 
  4.              ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(display.getActiveShell()); 
  5.              final List<String[]> contents = new ArrayList<String[]>(); 
  6.              IRunnableWithProgress progRunnable = new IRunnableWithProgress() { 
  7.  
  8.                 public void run(IProgressMonitor iprogressmonitor) 
  9.                         throws InvocationTargetException, InterruptedException { 
  10.                     int totalRow = 0; 
  11.                     try { 
  12.                     InputStream in = ExcelUtils.readExcelFile(filePath); 
  13.                     // IProgressMonitor 爲監視器,可監控任務進度,此處設定任務總量爲100個單位 
  14.                     iprogressmonitor.beginTask("努力爲你讀取文件,請稍候...", 100); 
  15.                      
  16.                     Sheet sheet = ExcelUtils.retreiveSheet(in, 0); 
  17.                     totalRow = sheet.getRows(); 
  18.                     int totalCol = sheet.getColumns(); 
  19.                     int rowStart = 0;  
  20.                     int rowEnd = 0; 
  21.                     int temp = totalRow / 10; 
  22.                     int segLength = temp > 0 ? temp : 1; 
  23.                     // 把任務人爲的分成10端 
  24.                     for(int seg = 1; seg <= 10 && !iprogressmonitor.isCanceled(); seg++) { 
  25.                         rowStart = rowEnd; 
  26.                         rowEnd += segLength; 
  27.                         for(int row = rowStart; row < rowEnd; row++) { 
  28.                             List<String> rowContent = new ArrayList<String>(); 
  29.                             for(int c = 0; c < totalCol; c++) { 
  30.                                 Cell cell = sheet.getCell(c, row); 
  31.                                 rowContent.add(cell.getContents()); 
  32.                             } 
  33.                             contents.add(rowContent.toArray(new String[0])); 
  34.                         } 
  35.                         //每完成一段監視器增加10個單位 
  36.                         iprogressmonitor.worked(10); 
  37.                         iprogressmonitor.subTask("已完成"+seg*10+"%"); 
  38.                         if(rowEnd >= totalRow) { 
  39.                             break
  40.                         } 
  41.                     } 
  42.                     // 完成剩餘的記錄(如果有的話) 
  43.                     for(int k = rowEnd; k < totalRow; k++) { 
  44.                         List<String> rowContent = new ArrayList<String>(); 
  45.                         for(int c = 0; c < totalCol; c++) { 
  46.                             Cell cell = sheet.getCell(c, k); 
  47.                             rowContent.add(cell.getContents()); 
  48.                         } 
  49.                         contents.add(rowContent.toArray(new String[0])); 
  50.                     } 
  51.                     // 在非UI線程中更新UI,必須利用asyncExec 或者 syncExec  
  52.                     display.asyncExec(new Runnable() { 
  53.                         public void run() { 
  54.                             // 向表格控件添加數據 
  55.                             addTableItems(table,contents); 
  56.                         } 
  57.                     }); 
  58.                     iprogressmonitor.done(); 
  59.                       // 如果此時爲用戶取消的操作 
  60.                     if (iprogressmonitor.isCanceled()) { 
  61.                        throw new InterruptedException("用戶已取消操作"); 
  62.                     } 
  63.                     }catch(Exception ex) { 
  64.                         ex.printStackTrace(); 
  65.                         showMessgeBox(shell,ex.getMessage()); 
  66.                     } 
  67. //                  showMessgeBox(shell,"已成功爲你讀取" + totalRow + "條記錄."); 
  68.                 } 
  69.                   
  70.              }; 
  71.              progressDialog.run(truefalse, progRunnable); 
  72.         }catch(Exception ex) { 
  73.             ex.printStackTrace(); 
  74.         } 
  75.     } 
  76.      
  77.     private void addTableItems(Table table,List<String[]> contents) { 
  78.         for(String[] rowContents : contents) { 
  79.             TableItem tableItem = new TableItem(table, SWT.NONE); 
  80.             tableItem.setText(rowContents); 
  81.         } 
  82.     } 
 
 
 
     2.2 選中某一行數據後將數據格式化顯示
        2.2.1效果如下:
     
 
       2.2.2 核心代碼如下
 
  1. table.addListener(SWT.MouseUp, new Listener() { 
  2.  
  3.                   public void handleEvent(Event event) { 
  4.                         int sTextWidth = initStyledText(Integer.parseInt(combo.getItem(combo 
  5.                                     .getSelectionIndex())),Integer.parseInt(spinner_3.getText()), Integer.parseInt(spinner_1 
  6.                                     .getText())); 
  7.                         int charsNum = new Double(Math.ceil(sTextWidth/8.0)).intValue(); 
  8.                         int colCount = table.getColumnCount(); 
  9.                         TableItem[] selectedItems= table.getSelection(); 
  10.                         StringBuffer sb = new StringBuffer(); 
  11.                         int topLine = Integer.parseInt(spinner.getText()); 
  12.                         for(int line = 0; line < topLine; line++) { 
  13.                               sb.append(LINE_SEPARATOR); 
  14.                         } 
  15.                         for(int i = 0; i < selectedItems.length; i++) { 
  16.                               TableItem item = selectedItems[i]; 
  17.                               for(int j=0;j<colCount;j++) { 
  18.                                     String realText = item.getText(j); 
  19.                                     if(realText.length() < charsNum) { 
  20.                                           int spaces = charsNum - realText.getBytes().length; 
  21.                                           for(int k = 0;k < spaces;k++) { 
  22.                                                 sb.append(" "); 
  23.                                           } 
  24.                                     } 
  25.                                     sb.append(item.getText(j)).append(LINE_SEPARATOR); 
  26.                               } 
  27.                         } 
  28.                         styledText.setText(sb.toString()); 
  29.                   } 
  30.                    
  31.             }); 
  32.       } 
  33.  
  34.      /** 
  35.        * 文本樣式,如字體大小,行距,對齊等用StyledText來控制。 
  36.       * @param fontSize 字體大小 
  37.       * @param rightMove      右移位數 
  38.       * @param lineSpacing 行距 
  39.       * @return 
  40.       * @version: v1.0.0 
  41.       * @author: <a href="mailto:[email protected]">flysqrlboy</a> 
  42.       * @date: 2013-1-27 
  43.        */ 
  44.       private int initStyledText(int fontSize,int rightMove,int lineSpacing) { 
  45.             styleTextFont = SWTResourceManager.getFont("宋體", fontSize, SWT.NORMAL); 
  46.             styledText.setFont(styleTextFont); 
  47.             styledText.setAlignment(SWT.LEFT); 
  48.             styledText.setJustify(true); 
  49.             styledText.setLineSpacing(lineSpacing); 
  50.             return styledTextSrcWidth + rightMove * 8
  51.       } 
 
  四、jar包轉成Exe執行文件
    打成Exe可執行文件的目的是雙擊即可運行,當然運行目前這個版本的exe文件要求用戶的電腦中要有Java 運行時環境(JRE)。如果要在沒有JRE的電腦中運行,則在轉exe時把jre包一起打進exe文件中即可。 
    1.打jar包
    這裏要注意的是,我們的目標是雙擊exe即可運行,無需依賴外部的資源,所以打jar包時要把所有依賴的jar都打進一個jar裏。
     如下圖操作:
 

       

       

 

     2. 用Jsmooth轉成EXE
     
     這裏只說Application的配置,如下圖:
 

    由於invoice.jar已經是可運行的jar(雙擊運行),所以上圖中的Classpath無需任何設置,即不必依賴外部資源。

 
    至此,工具開發完成。週末兩天去除生活上一些雜七雜八的瑣事,開發時間應該在18小時內。
工具本身很輕巧沒什麼難度,不過把一個想法鼓搗出來的過程還是挺爽的!
 
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章