今天,有個朋友在網路上問我,如何在 NetBeans 載入 modules 前顯示一個 Login Dialog 以進行身份認證。關於這個問題,其實在 NetBeans 的討論串中出現過,當時我也沒有花時間去試。今天,剛好有這個機會,我就寫了這個程式,用它在 NetBeans 載入 modules 前顯示一個 Login Dialog 。所以,這篇文章將會教大家如何在 NetBeans 載入 modules 的時候,加入一個 Login Dialog,同時,我們也會討論一下這種作法的適切性。
1. 準備專案
我們在一開始之前必須先建立一個 module suite – Login Dialog 及一個 module – Login Dialog Module 。建立專案的方式可以參考之前的文章。
2. 建立 Dialog
首先,我們須要設計一個 JDialog – 名叫 LoginDialog –用來當成我們的 Login Dialog 。我們可以如下圖般建立一個 login dialog 用來進行使用者認證。並且,在 這個 JDialog 中,我們建立一個 boolean 的變數 m_Ok 用來記錄使用者按下的是那個按鈕,同時,在login 與 cancel 的按鈕上,加入程式碼,用來修改 m_Ok 的值,以及關閉這個 JDialog 。完整程式如下:
LoginDialog 程式碼
-
private boolean m_Ok;
-
-
public boolean isOK ( ) {
-
return m_Ok;
-
}
-
m_Ok= false;
-
this. setVisible ( false );
-
}
-
-
m_Ok= true;
-
this. setVisible ( false );
-
}
3. 建立 ModuleInstall
ModuleInstall 是 NetBeans 提供的一個可以在 module 被載入,或卸載時進行處理的地方。同時,在 NetBeans 關閉的時候,它會呼叫 ModuleInstall 的 closing()
方法,如果,有某個 module 不希望被關閉的話,也可以透過這個方法回傳 true ,以使 NetBeans 取消關閉的動作。
我們可以透過 ModuleInstall 的支援,在我們的 module 被載入的時候,顯示一個對話方塊,用來進行身份認證。根據 ModuleInstall 的 javadoc 所述,我們可以實作 ModuleInstall.restored()
的方法來完成它。
建立 ModuleInstall 可以使用 NetBeans 的 New File 來完成。我們可以在 Categories 中選擇 NetBeans Module Development ,在 File Types 中選擇 Module Installer 。
下一步後,我們設定這個 Module Installer 要儲存的 package ,以及 NetBeans 會幫我們新增/修改的檔案清單。
完成後,我們就可以在 Installer 的 restored() 方法中加入程式碼了。
-
package fox. netbeans. logindialog;
-
-
import java.awt.event.WindowAdapter;
-
import java.awt.event.WindowEvent;
-
import javax.swing.SwingUtilities;
-
import org.openide.LifecycleManager;
-
import org.openide.modules.ModuleInstall;
-
import org.openide.windows.WindowManager;
-
-
public class Installer extends ModuleInstall {
-
public void restored ( ) {
-
LoginDialog oDialog= new LoginDialog ( null, true );
-
oDialog. setLocation ( 330, 300 );
-
oDialog. setVisible ( true );
-
if (oDialog. isOK ( ) ) {
-
} else {
-
public void run ( ) {
-
LifecycleManager. getDefault ( ). exit ( );
-
}
-
} );
-
}
-
} );
-
-
}
-
oDialog. dispose ( );
-
}
-
-
}
在這段程式碼中,我們首先建立了我們剛剛設計的 LoginDialog。當使用者按下 login 的按鈕時,系統會在 console 中顯示 Login Correctly.. 的字串。當使用者按下 cancel 的按鈕時,系統會在 WindowManager 的 Main Window 中加上一個 WindowListener 並在 Window Opened 事件發生時,呼叫 LifecycleManager 的 exit 方法來離開 NetBeans 。大家可能會覺得奇怪,為什麼要在 Window Opened 的時候再呼叫,為什麼不直接呼叫?其實,在這個 Installer 運作的時候,NetBeans 還沒把所有該載入的程式都載入完成。此時,如果貿然呼叫 System.exit(-1) 將有可能無法儲存原先該儲存起來的 state ,造成下次開啟的時候發生錯誤。同理,如果,我們在這邊直接呼叫 LifecycleManager.getDefault().exit() ,NetBeans 也將會無法繼續執行下去。筆者有試著在 restored() 方法中呼叫 LifecycleManager.getDefault().exit() ,呼叫後 NetBeans 將不會有任何的反應,且不會進行之後的載入動作,就單純地卡死在這個畫面上了。
執行畫面如下:
4. 討論
一開頭,我們就有提到 NetBeans 的討論串當中,有些人在討論這個問題。在他們的討論過程中,其實提到了幾個重要的事情:
a. ModuleInstall 中的 Dialog 不能使用 Main Window 當成 parent
ModuleInstall 的 restored 方法並不是在 NetBeans 把全部的程式都初始化完成才呼叫,它是在 module 都載入完後(此處,筆者也不大確定是全部的 module 還是設計 ModuleInstall 的 module 本身),再進行呼叫。所以,某些 NetBeans 的基礎服務還沒被完全初始化完成,而 Main Window 就是其中之一。
正因為這個問題,導致我們所設出來的 JDialog ,只要 focus 一離開就無法正常地蓋在 splash screen 上面(甚至於一時找不到它)。唯有透過 windows 的 alt + tab 才能讓它顯示出來。
針對這個問題,有人提出,可以使用 JDK 1.5 以上的 setAlwaysOnTop(true) 的方法來處理,但是,當這個方法一被呼叫之後,將不會有任何的 Window 能夠蓋在它上面。
筆者認為,最好的方式應該是等到整個 Main Window 都顯示出來後,再顯示認證的視窗。這部份執行後的畫面如下:
程式碼如下:
-
public void restored ( ) {
-
public void run ( ) {
-
WindowManager. getDefault ( ). getMainWindow ( ). removeWindowListener ( this );
-
LoginDialog oDialog= new LoginDialog (WindowManager. getDefault ( ). getMainWindow ( ), true );
-
oDialog. setLocation ( 330, 300 );
-
oDialog. setVisible ( true );
-
if (oDialog. isOK ( ) ) {
-
} else {
-
LifecycleManager. getDefault ( ). exit ( );
-
}
-
oDialog. dispose ( );
-
}
-
} );
-
}
-
} );
-
-
}
b. 有必要在載入的時候進行身份認證嗎?
其實,這個問題比較像是見仁見智的問題,很難有個標準的答案。筆者第一次看到『加入 Login Dialog』 的問題時,筆者第一個直覺也是這個問題,有必要這樣做嗎?筆者想了想覺得,可能因為有許多系統都是在 splash screen 出來之前,先進行身份證認,當通過後,再開始載入程式。可能因為這樣才會讓大家有這種想法吧。
不過,對筆者來說,比較建議的方式還是等到全部的模組都正常被載入後,再進行身份認證會比較好。
完整的程式可以在這裡下載。
转自: http://fox.jenming.info