JavaFX 如何使用內建的對話框(Dialog)?


JavaFX改進了以往Java的Awt和Swing函式庫實作圖形化介面(GUI, Graphical User Interface)的方式,而且還可以使用Lambda表示式來快速實作出Functional Interface,這也讓JavaFX應用程式的效能優於使用Awt和Swing函式庫做出來的Java應用程式。只是非常奇怪的是,JavaFX在一開始的時候居然沒有內建對話框(Dialog),沒有提供像是Swing函式庫中的JOptionPane類別所提供的showMessageDialog這樣快速跳出訊息框的方法。因此,以往要在JavaFX上顯示對話框,就只能自己製作一個對話框的Stage。

還好,這樣的情況到了Java 8 Update 40之後,官方終於在JavaFX內新增了DialogPane與Dialog類別,並預設實作了基本的資訊(Information)、警告(Warning)、錯誤(Error)、確認(Confirmation)的訊息對話框(Alert)和選擇物件的選擇對話框(ChoiceDialog),以及能輸入文字的文字輸入對話框(TextInputDialog)。底下就讓我們來看看這些對話框的使用方法。

JavaFX的內建對話框全都繼承Dialog這個類別,在個別介紹JavaFX內建對話框的用法之前,須注意到JavaFX的Dialog類別雖是一個獨立的對話框視窗,但卻是位於javafx.scene.control套件內,而非javafx.stage套件,而且也沒有繼承Control這個抽象類別,所以Dialog不是Node(Dialog is not a Node),因此別想將Dialog當作是控制項元件來加入到別的視窗或是容器中。Dialog類別內有使用到HeavyweightDialog這個非公開類別,裡面已經實作好對話框的Stage了。

若您還不清楚什麼是Stage、什麼是Node,請先參考底下兩篇文章:

https://magiclen.org/javafx-architecture/
https://magiclen.org/javafx-hello-javafx/

訊息對話框(Alert)

JavaFXAlert類別其實就是我們熟知的MessageDialog,根據訊息類型的不同,分為幾種不同的AlertType,在顯示時也會有不同的圖示以及不同的按鈕。分類可列表如下:

  • None:不分類的訊息。常用於顯示使用說明。
  • Information:一般的提示訊息。常用於提示目前程式執行的狀態,以及回傳的正確結果。
  • Warning:警告訊息。常用於顯示程式遇到了一些不正常但無重大影響的問題。
  • Error:錯誤訊息。常用於顯示程式遇到的嚴重錯誤。
  • Confirmation:確認訊息。常用於再次確認使用者想要進行的動作。

建立Alert對話框的方式很簡單,程式如下:

執行結果如下:
JavaFX 如何使用內建的對話框(Dialog)?

如果想知道使用者按下了對話框的哪個按鈕,可以從showAndWait方法的傳回值來取得Optional物件所帶的ButtonType,或是在對話框被關閉後,使用getResult方法直接取得ButtonType。以確認訊息來舉例的話,程式如下:

執行結果如下:
JavaFX 如何使用內建的對話框(Dialog)?

如果想自訂對話框的按鈕,可以在實體化Alert時,將ButtonType以Varargs的方式作為建構子的參數,例如將Confirmation對話框按鈕改成「是、否」按鈕,可以將以上程式改成:

執行結果如下:
JavaFX 如何使用內建的對話框(Dialog)?

選擇對話框(ChoiceDialog)

選擇對話框算是一個蠻特別的存在,設計師可以將任何物件加入這個對話框內,被加入的物件會在這對話框內被轉成字串(toString),並且顯示在下拉式選單(ComboBox)中,用法如下:

執行結果如下:
JavaFX 如何使用內建的對話框(Dialog)?

文字輸入對話框(TextInputDialog)

跳出一個對話框要使用者輸入文字算是一個蠻常見的功能,在JavaFX中便有內建這樣的輸入對話框,用法如下:

執行結果如下:

JavaFX 如何使用內建的對話框(Dialog)?

更進階的對話框用法-DialogPane

Dialog類別的Stage使用到DialogPane來放置控制項元件,因此可以藉由修改DialogPane來大幅調整內建對話框的樣式。若要取得Dialog的DialogPane,可使用getDialogPane()方法,會直接回傳DialogPane物件。要修改DialogPane的內容,可以使用setContent這個方法,傳入自己製作的Node。

可製作出如下,能顯示Exception訊息的Error Dialog:

JavaFX 如何使用內建的對話框(Dialog)?

另外也可以使用setExpandableContent方法,同樣傳入自製的Node來建立可擴展與收合內容訊息的對話框。

已知的對話框問題

由於JavaFX的Dialog在Java 8 update 40才出現,所以在這之前的JavaFX版本都無法支援有使用到Dialog的JavaFX App。而且這版本的Dialog似乎還有很多Bug待解決,其中比較嚴重的是在某些平台下,Dialog的Resize和Redraw的功能無法使用,所以建議不要塞太多內容在Dialog中,上面提到的DialogPane的setExpandableContent方法也儘量不要使用,以免出現如以下視窗元件走位,以及內容顯示不完整的問題。

JavaFX 如何使用內建的對話框(Dialog)?

JavaFX 如何使用內建的對話框(Dialog)?

JavaFX的Dialog的問題大概要到Java 9之後才會比較少。如果想要更容易在JavaFX中使用對話框的話,可以參考這篇文章:

https://magiclen.org/javafx-dialog/

關於作者

Magic Len

各位好,我是Magic Len,是這網站的管理員。我是台灣台中大肚山上人,畢業於台中高工資訊科和台灣科技大學資訊工程系,曾在桃機航警局服役。我熱愛自然也熱愛科學,喜歡和別人分享自己的知識與經驗。如果你有興趣認識我,可以加我的Facebook,並且請註明是從MagicLen來的。

相關文章