使用eclipse開發JavaFx專案
JavaFX
JavaFX可以用來設計輕量且高效能使用者圖形介面(Graphical User Interface,GUI)的應用程式(Application),更能作為RIA(Rich Internat Application)應用程序來發佈,這篇文章筆者將使用eclipse來建立一個包含簡易視窗的JavaFX應用程式。
eclipse開發JavaFX
建置JavaFX專案的方式有很多種,我們可以使用一般Java專案,也可以透過eclipse plugin e(fx)clipse建置,而本篇我們將採用maven project方式建立。
環境建置
個人開發時的環境如下
• 作業系統 windows 10
• Eclipse 2021-03(Eclipse IDE for java Developers)
• java-1.8.0-openjdk-1.8.0.282-1
• Eclipse plugin: e(fx)clipse 3.7.0
• JavaFx Scene Builder: 8.5.0
注1:因Eclipse 2021-03自帶openjdk 15.0.2_jre,請先由window->Preferences->Java->Installed JREs新增jdk指向 我們安裝的java-1.8.0-openjdk-1.8.0.282-1或如筆者一樣直接將預設的jre路徑修改指向java-1.8.0-openjdk-1.8.0.282-1,後續我們將使用java1.8來開發JavaFx專案,如下圖
注2:eclipse plugin e(fx)clipse 安裝完成後,先開啟window->Preferences設定,找到javaFX項目,將安裝完成的SceneBuilder執行檔設定為SceneBuilder executable,如下圖顯示:
因java1.8內建JavaFX library,故這裡的JavaFX 11+SDK並不是作為在建立javaFx專案時引用為liberary路徑,無需設定(自從java11以後Oracle已將JavaFX分離唯一個獨立的項目,即便是使用java11,此處的設定也沒有效果,必須另外建立一個user library指向javaFx library路徑)。
e(fx)clipse是最早筆者用來產生javaFx專案的工具,使用e(fx)clipse建立的javaFx專案是透過Ant build產生可執行的jar檔,透過該工具的設定也可以直接由eclipse呼叫SceneBuilder,或者產生javaFx相關檔案(例如: fxml檔),所以此處安裝e(fx)clipse主要是運用它的工具,並非透過它產生JavaFX專案。
SceneBuilder主要用來建構應用程式的UI介面,透過SceneBuilder可以輕鬆的針對畫面進行各種元件排版與相關屬性設定,並可在SceneBuilder上進行預覽,SceneBuilder安裝後執行起來的初始畫面如下圖:
使用maven project建立javafx專案
目前使用Maven建立javaFx專案的型態已經有很多種了,在此就筆者使用的方式一步一步來說明。
在eclipse中,我們先選擇Maven Project,接著Next
此頁直接預設值Next
請在Filter中輸入javaFx,可以看到目前有各式各樣的JavaFX專案型態可供選擇,筆者使用com.zenjava的javafx-base-archetype來產生專案,選擇com.zenjava的javafx-base-archetype後Next。
輸入Group Id,Artifact Id,其中MyFx1就是這次範例的專案名稱,並且在organizationName自行輸入一個名稱(一定要輸入,否則無法繼續),輸入完成後Finish。
專案完成後可以看到預設使用的JRE System Library為J2SE-1.5,先將其改為我們設定的Java1.8版本,右擊專案->Properties->Java Build Path,切換到Libraries頁籤,點擊JRE System Library,點擊Edit…,選擇Workspace default JRE。
JavaFX基礎架構
展開MyFx1專案,在src\main\java目錄下可以看到MainApp.java以及HelloController.java,其中MainApp.java是JavaFX的執行點。
開啟MainApp.java可以看到MainApp繼承自javafx.application.Application,從main()方法進入後通過內部調用start()方法。
這裡我們可以看到整個JavaFX的基礎架構就如同下面這張圖:
其中Stage可以說是應用程式最上層的容器,在範例中可以看到他設定了視窗的Title,或甚至可改變應用程式的外觀(StageStyle)。而Scene是圖形化介面中所有內容物的基底容器,你可以在這個容器內放置各種JavaFX的控制元件。Node是控制元件的基礎類別,其子類包含了這個範例程式的Parent類,以及所有JavaFX控制元件。Node與Node之間可以層層套疊,依照javadoc的說法,Node的圖形化界面就像一組樹狀結構,每個Node都可以有零個或一個父Node,每個Node也可以是零個子Node或多個子Node。
JavaFX除了可由原生的Code產生圖形化界面外,還支援使用XML來描述圖形化界面(稱為FXML),透過JavaFX Scene Builder來製作圖形界面僅需要拖、拉、放等動作,再設定相關屬性即可完成界面的佈局,並可透過SceneBuilder預覽完成的圖形界面,在專案中透過FXMLLoader類來載入使用FXML製作的圖形界面,如範例中的hello.fxml。
Hello JavaFX
此範例中已為我們產製了一個姓名輸入的Hello視窗,透過執行MainApp可以看到這個視窗的樣子。
在輸入完First Name與Last Name後,點擊【Say Hello】,可以看到左下角出現Hello Sunny Yeh的紅色字樣。
回到eclipse,我們從SceneBuilder來看看Hello.fxml。在eclipse的Project explorer視窗中右擊hello.xml->Open with SceneBuilder,卻發生一個錯誤訊息。
怎麼回事? 先來看一下hello.fxml內容,因為fxml屬於xml標記式語言的一種,我們可以輕易地使用一般文字編輯器來開啟,可以看到hello.xml使用MigPane,而MigPane並不屬於JavaFX基本元件(Pane通常作為Scene下一層Node,有機會再談各種Pane的運用),所以目前無法透過SceneBuilder開啟。
解決的方式有兩種,一是透過文字編輯器將MigPane改為JavaFX基本Pane中的一種,並移除特殊的屬性設定,筆者不建議這種方式,因為MigPane與放置其中的元件還有位置的對應關係,若非極為熟悉各元件屬性,隨意修改只會混亂整個畫面。
而解決此問題的另一個方式就是在SceneBuilder中加入 MigPane相關Library使得SceneBuilder認得這個元件,筆者採用此方式解決這個問題。展開專案的Maven Dependencies,可以看到兩個miglayout相關jar檔
將這兩個jar檔從maven repository取出,然後由外部開啟SceneBuilder,在Library旁一個小小齒輪下拉選擇JAR/FXML Manager。
開啟Library Manager後,點擊Add Library/FXML from file system,選擇剛剛取出的兩個MigLayout相關jar檔,點擊Import Components。
完成後如下圖,在左側Custom展開後可見到MigPane已加入
現在我們再從eclipse使用Open with SceneBuilder開啟Hello.fxml看看,果然成功看到Hello.fxml的圖形視窗。
注1:eclipse中Open with SceneBuilder選項只會出現在Project explorer 或 Package explorer等視圖中,像Navigator視圖是不會出現的。Open with SceneBuilder是由e(fx)clipse提供,若未看到此選項或無法開啟SceneBuilder請回頭檢查是否已安裝並設定好SceneBuilder執行檔位置(請參考前述的環境建置)。
注2:任何在SceneBuilder所做的修改,在SceneBuilder儲存後返回eclipse時,請務必在eclipse你自己的專案做一次更新(右擊專案 -> refresh),否則eclipse不會知道fxml檔已被外部程式修改過。
回頭看一下剛剛執行的應用程式,應用程式似乎套用了一張底圖,怎麼此處的SceneBuilder沒看到底層圖樣?
回到eclipse的MainApp.java中我們可以看到有個style.css透過程式載入,那麼在SceneBuilder中可以嗎?畢竟css和畫面有著密不可分的關聯;這個答案是肯定的, 筆者使用以下方式呈現底圖:
第一種,我們可以在SceneBuilder中左側Document->展開Hierarchy視圖,選擇最底層的MigPane,然後在右側展開Properties視圖,往下找到Sytlesheets,點擊+後選擇專案的style.css,就可以看到css套用Hello.jxml,不過,透過程式載入與透過SceneBuilder設定只須擇一即可,若css是整個應用程式適用,建議如範例一樣,直接套用進最底層的Scene類則所有包含在Scene下的物件均會受到此css影響,筆者通常只為了要即時看到css對畫面造成的影響才會用此方式測試。
第二種方式是透過預覽來加入style.css,我們可以從SceneBuilder的選單Preview ->Scene Style Sheets-> Add a Style Sheet…將style.css加入,加入後也可看到實際上畫面的變化,此方式不會影響實際程式的運作。
操作元件
最後,我們要如何控制Hello.fxml這個畫面上的欄位呢?
程式中有一個HelloController.java就是實際操控畫面的程式碼,在SceneBuilder左側Document展開Controller視圖,可以看到Controller class指向HelloController,而下方可以看到三個擁有fx:id的元件,fx:id在哪設定呢?右邊展開Code視圖,就可看到fx:id欄位,我們可以為需要透過程式控制的元件設定唯一的名稱。
Say Hello這個Button有個On Action的事件(Event),點擊Say Hello就可以看到在On Action中我們設定了sayHello這個事件。
SceneBuilder設定完成後,我們回到eclipse看看HelloController.java。
在HelloController中我們可以看到三個變數分別以@FXML這個Annotation標註,其參數名稱與元件類別分別對應到SceneBuilder中相同元件類別與fx:id的元件,JavaFX透過@FXML來綁定Hello.fxml的元件與HelloController.java的變數;除此之外,我們也看到一個sayHello()的method,而這個method正是Hello.fxml中Say Hello Button的事件內容,在點擊Say Hello Button後串接firstNameField與lastNameField文字並修改messageLabel文字。
編譯為可執行檔
最後透過com.zenjava的javafx-maven-plugin我們可以產生一個可執行的jar檔,也可以產生一個原生的執行檔。
要產生可執行的jar,請執行maven jfx:jar(command line),而在eclipse中,我們可以右擊pom.xml -> maven build->在Goals中輸入jfx:jar後點擊Run。
重新整理專案後在target\jfx\app目錄下就能看到MyFx1-jfx.jar,開啟dos command切換到此目錄下執行java -jar MyFx1-jfx.jar 就能看到應用程式執行。
javafx-maven-plugin也可以用來產生原生應用程式,透過maven jfx:native(command line)即可,而在eclipse中,同樣右擊pom.xml -> maven build->在Goals中輸入jfx:native後點擊Run。
重新整理專案後在target\jfx\native目錄下就能看到MyFx1.exe,開啟dos command切換到此目錄下執行MyFx1.exe 就能看到應用程式執行。
注1:MyFx1.exe看起來只是一個原生前導程式,他其實還是去呼叫MyFx1\app\MyFx1-jfx.jar,所以筆者後來都改用maven-jar-plugin來編譯JavaFX程式,再透過launch4j包裝成windows應用程式(.exe)。
以上是筆者如何使用eclipse開發JavaFX專案的步驟,提供給想要嘗試使用JavaFX作為前台開發的朋友一個參考。