顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2016年7月12日 星期二

Javascript 標準及一些 API

You-Dont-Need-jQuery
You-Dont-Need-Lodash-Underscore

由於最近幾年,隨著 Browser 「再次」大戰 ,Google Chrome 取得了主導的地位。而 Javascript 也在「這幾年」開始有進一步的標準,及許多新的原生標準 API 出現。使得原先為解決功能不足而產生的 js lib,突然間許多 API 都有原生版本。也因此開始有人提倡使用新的 Javascript 標準 API 來寫作 js 。

其實,要求已經使用這些 js lib 的人改回用原生 API 的作法,就算新寫的程式可以,舊版的及早期開發完成的系統,也很難逐一修改。這之中比較適當的作法,應該是在新版 js lib 中,把原生 API 包進去,把那些不適宜的部分,予以註記不再使用 (deprecated),這樣應該會比較好。

Vanilla JS 很有趣,把需要的功能全部選一選,結果下載的vanilla.js,檔案大小為「零」。意思就是,直接用 browser 提供的 javascript 即可,也就是用標準的 javascript API 就對了。

2016年6月22日 星期三

開發 File Monitor 2

之前完成的程式,用 Class Diagram 隨便畫一下,大概的關係圖如下:

由於 WatchDir 中,為了使用 textArea 來顯示訊息,所以把 textArea 當作參數傳給 WatchDir。此外,textArea 使用String.format處理產生的訊息。

這樣的寫法,其實變成日後要加新的「訊息處理者」,如 MessageDialog 來產生 alert 對話視窗時,變成要再加參數傳給 WatchDir。而且使用的 ? 方法,也要另外再寫 String.format 來處理對應的訊息。因此這部分需要作修改,重構一下。


讓 WatchDir extends Observable,把所觀測到的檔案訊息,包成一個 final 物件FileMonitorEvent,將訊息資料傳入個別的 Observer 作處理。作成 final 物件,是因為檔案異動訊息一產生,就不能被更改。圖中的 Observer (藍色部分),不一定需要實際的 class ,也可以用 lambda 或 anonymous 的方式。

此外,一個監控目錄,應該對到一個 OptionDialog,也就是之前提到的 UseCase 中,除了顯示檔案異動訊息之外,其它的動作設定,均會在這個 OptionDialog 中。而個別的 Observer 也會在這個 OptionDialog 實作。如此將來可以擴充成多個 OptionDialog ,就可以監控多個目錄。

再回頭看一下這兩個 Class Diagram,也許會有人認為,其實一開始是可以設計第二張圖的,為什麼不一開始就「設計好」呢?這個部分要思考一下幾個想法。

首先,每個人寫程式的方式其實是不一樣的,即使是同一人,每次作法也不見得會一樣。以這個監控檔案異動的程式,當初在寫的時候,「重點」是趕快寫出來,讓監控檔案異動的部分可以動再說,如果實際上 Java API 作不到,可能要採用其它的語言來寫。

第二,因為不了解實際 Java API 處理檔案監控的機制為何,所以一開始也無法很快了解要用到 Observer pattern 來處理「檔案異動訊息」,而原本的範例程式,就 for 一直跑,要修改成 Thread 來使用。再加上之前寫的都是 Server Side 的 Java, Swing 很久沒寫了,WindowBuilder 也才剛用個「幾天」,雖然很直覺,很好用,但總是要花時間摸索。如果不先把功能作出來,大概時間都會花在處理了解這些 Swing 元件 或 找 pattern 了。

第三,這其實是個小程式,因此初期不需要太多的設計,就可以很快實作出來,而會卡關的,除了對 API 不熟之外,還有環境的不了解,因此,當初寫的時候,「一不小心」就花了半天的時間去查「所有可以監控檔案」的程式寫作,包含 windows 的 API 等,最後才發現,就用 Java 自己的 API 就可以了。這樣寫程式,很容易「發散」沒有專注。

上述的想法,在寫作小程式或試驗的時候,是可以這樣處理的。大型專案就比較難這樣作。因為大型專案如果沒有作好設計,一開發下去,若有問題,人力物力還要重新投資。

從想到作,寫大概的 UseCase,程式實作出來,作 Class Diagram,然後再改成新版用 Observer pattern 也花了二天左右。真的作不對,整個打掉再來,也還能接受。

倒是寫這個 blog 文章花的時間比較多。因此,有一個構想點子,會比去了解更多有的沒有的技術,會更重要。因為這樣比較好聚焦在要處理的程式碼上。而技術的使用,在需求及功能初步達成後,再回頭重構也是可以的。

2016年6月19日 星期日

開發 File Monitor

加密勒索病毒 CryptoLocker 是很難對付的病毒,中毒之後,重要的檔案都會被加密,而解密的 key 在對方手上,除非防毒軟體有找到這些 key ,不然除了付錢給對方,要求提供解密功能,用其它的方式,幾乎是不可能回復檔案。

但加密檔案,一定會動檔案作異動。這個時候若有可以監控指定目錄下的檔案異動程式,就可以得知是否有可疑的異動。以便使用者進一步作處理。

因此 File Monitor 這個程式,就是因應這樣的需求而作的。

本程式是用 Java 語言,在 Eclipse 下寫作而成。

1. 首先是大概確認使用案例,這裡用簡單的 UML Use case 表示

使用者可以有三個動作,一是執行或停止監控,一是設定指定監控目錄,最後則是設定選項,可以指定目錄、指定檔名過瀘、顯示訊息、撥放聲音檔、執行程式等。先實作紅色框的部分。

2.使用 Eclipse ,建立 FileMonitor 專案,並用 WindowBuilder 拉出如下的視窗

畫面分成三個部分,
    上方 panel,放 Monitor Directory: 文字和按鈕等元件
    中間 scrollPane,放顯示監控到的檔案異動 textArea
    下方 textPane,顯示訊息

3. 實作檔案監控的部分,需要使用到 WatchService API ,可參考 Watching a Directory for Changes ,使用它所提供 WatchDir example,原程式是命令模式執行,並用 System.out 輸出訊息,因此要修改為接收一個 textArea 作輸出。此外,把 WatchDir 實作 Runnable 界面,這樣就可以用 Thread 起動。因此也需加上 run() 的實作部分。


4.在 UI 使用 WatchDir,主要增加 button 的動作。

btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    try {
      wd = new WatchDir(Paths.get(textField.getText()), true, textArea);
      Thread t = new Thread(wd);
      t.setDaemon(true); 
      t.start();
      btnStart.setEnabled(false);
      btnStop.setEnabled(true);
    } catch (IOException e1) {
      textPane.setText(e1.getMessage());
    }
  }
});
panel.add(btnStart);

btnStop = new JButton("Stop");
btnStop.setEnabled(false);
btnStop.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    wd.stopRunning();
    btnStart.setEnabled(true);
    btnStop.setEnabled(false);
  }
});
panel.add(btnStop);

btnClear = new JButton("Clear");
btnClear.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    textArea.setText("");
  }
});
panel.add(btnClear);

5. 實際的執行結果如下

2016年6月15日 星期三

Eclipse Java Swing BeansBinding JSR 295

UI 元件常需跟 Model 的資料作連動,除了自己寫程式之外,也可以用 Eclipse WindowBuilder + BeansBinding 提供的方式作連動。

底下是簡單的範例,當使用者輸入最上方的文字方塊,最下方會同步顯示輸入的文字。按下 Add 後,該文字就會置入中央的列表中,並清空文字方塊。

 


1.首先要加裝  jsr 295 Beans Binding 的實作,選用的是 BetterBeansBinding ,如果使用 Gradle,則要設定 BetterBeansBinding SwingBinding


2.執行 gradlew.bat 把 jar 檔設定好後,隨便拉一下 Swing 組成如下的視窗,可以看到有個Bindings的tab
 

3. 把 Target 跟 Model 的 text 綁定起來。
 

4.底下是自動產生的程式碼片斷,怎麼解讀?算了,不重要,有興趣自己去看 JSR 295,只要它能讓兩個元件彼此資料連動就好了。
 

好啦,這樣就可以連動兩個元件的資料了。

不過 JSR 295 好像熄火了,沒什麼動作,所以這些程式庫也很久沒有新版。目前比較「熱」的是 JGoodies Binding ,至於怎麼用,下次再研究吧 ......

2016年6月13日 星期一

Eclipse WindowBuilder 的使用心得

Eclipse 預設在建立 Swing 物件時,會把一切組件宣告通通放在 constructor 中。

但有時要特別處理某組件,我們可以將它 expose 出來,也就是多一個 get method 並把該組件宣告成 class 成員變數,如果沒有外部程式使用 get method,那就刪除那個 get method。另外使用 private method 操作該組件。

例如:
1.底下是一個簡單的 Swing 程式
 

2.在 Eclipse 的程式碼如下,可見綠色框的部分,已經是成員變數,而紅色框的部分,則定義在method中
 

3. 回到 Desgin 模式,將 textArea Expose 出來
 

4.  切換到程式碼模式,就可以看到改變的部分
 

5. 此時就可以在整個 class 中,使用 textArea ,因為它已經是成員變數了

 

如果希望每一個組件都是成員變數,可以由 Window -> Preferences -> WindowBuilder -> Code Generation 中,設定 Field 模式即可
  

這樣產生出來的組件,都會是成員變數了。

2016年6月12日 星期日

減少冗長的樣板程式碼 - Lombok

寫 Java 程式時,常會需要為成員變數建立 getter 及 setter,使用 IDE 工具可以容易自動建立這些樣板程式碼,但當成員變數過多時,整個程式碼就會變得很長,而真正運作的程式碼,就會淹沒在其中。有個 Lombok 的專案,針對這個部分,作了一系列的 annotations。效果顯示如下:

1.未使用前,右方只有一堆成員變數。
 

2.使用 @Data 後,自動產生樣板程式碼,顯示在右方 method 清單上,但左方並沒有產生這些程式碼,都被 @Data 代表了。


3.而底下就是真正執行功能的程式,整個程式碼清爽多了




專案主頁
https://projectlombok.org/
詳細說明
http://jnb.ociweb.com/jnb/jnbJan2010.html