【JavaFx教程】第一部分:Scene Builder
第一部分的主題
- 開始瞭解 JavaFX 。
- 建立並執行一個 JavaFX 專案。
- 使用 Scene Builder 來設計使用者介面。
- 使用 模型 - 檢視 - 控制器(MVC)模式 構造基礎的應用。
你需要準備
- 最新的 Java JDK 8 (包含 JavaFX 8)。
- Eclipse 4.3 或更高版本與 e(fx)clipse 外掛。最簡單的方法是從 e(fx)clipse 網站 下載預先配置的發行版本。作為一種備選你可以使用一個 update site 來給您的 Eclipse 安裝。
Eclipse 配置
配置Eclipse 所使用 JDK 和 Scene Builder:
-
開啟 Eclipse 的設定並找到 Java | Installed JREs 。
-
點選 Add…, 選擇 Standard VM 並選擇你安裝 JDK 8 的 Directory 。
-
移除其他的 JREs 或 JDKs 從而使 JDK 8 成為預設。
-
在 Java | Compiler 中設定 Compiler compliance level 到 1.8。
-
在 JavaFX 中指定你的 Scene Builder 可執行檔案的路徑。
幫助連結
你可能會想收藏下面的連結:
一切就緒,讓我們開始吧!
建立一個新的 JavaFX 專案
在 Eclipse(已安裝 e(fx)clipse 的)中,點選 File | New | Other… 並選擇 *JavaFX Project*。 指定這個專案的名字(e.g. *AddressApp*)並點選 *Finish*。
如果 application 包被自動建立,那麼刪除它和它的內容。
建立包
Model-View-Controller (MVC)是一個非常重要的軟體設計原則。按照MVC模式可以將我們的應用程式劃分成3個部分,然後為這每一部分建立自己的包 (在原始碼資料夾上右鍵, 選擇 新建 | 包):
ch.makery.address
- 放置所有的控制器類(也就是應用程式的業務邏輯)ch.makery.address.model
- 放置所有的模型類ch.makery.address.view
- 放置所有介面和控制元件類
注意: view包裡可能會包含一些控制器類,它可以直接被單個的view引用,我們叫它 檢視-控制器。
建立FXML佈局檔案
有兩種方式來建立使用者介面,一種是通過XML檔案來定義,另外一種則是直接通過java程式碼來建立. 這兩種方式你都可以在網上搜到. 我們這裡將使用XML的方式來建立大部分的介面。因為這種方式將會更好的將你的業務邏輯和你的介面開來,以保持程式碼的簡潔。在接下來的內容裡,我們將會介紹使用Scene Builder(所見即所得)來編輯我們的XML佈局檔案,它可以避免我們直接去修改XML檔案。
在view包上右鍵建立一個新*FXML Document*,把它命名為PersonOverview
。
用Scene Builder來設計你的介面
注意: 你可以下載這部分教程的原始碼,它裡面已經包含了設計好的佈局檔案。
在PersonOverview.fxml
右鍵選擇 *Open with Scene Builder*,那麼你將會在開啟的Scene Builder裡面看到一個固定的介面設計區域(在整個介面的左邊)。
-
選中這個介面設計區域,你就可以在右邊的屬性設定欄中對它的尺寸進行修改:
-
從Scene Builder的左邊控制元件欄中拖拽一個 Splite Pane(Horizontal Flow) 到介面設計區域,在Builder的右邊檢視結構中選擇剛新增的Pane,在彈出的右鍵選單中選擇 Fit to Parent 。
-
同樣從左邊的控制元件欄中拖拽一個 TableView 到 SplitPane 的左邊,選擇這個TableView(而不是它的列)對它的佈局進行設定,你可以在 AnchorPane 中對這個TableView四個邊的外邊距進行調節。(more information on Layouts).
-
點選選單中的 Preview | Show Preview in Window 可以預覽你設計好的介面,試著縮放預覽的介面,你會發現TableView會隨著視窗的縮放而變化。
-
修改TableView中的列名字,”First Name” and “Last Name”,在右邊面板中的屬性設定項
-
選擇這個 TableView ,在右邊面板中將它的 Column Resize Policy 修改成 constrained-resize (同樣是在屬性設定項裡面)。確保這個TableView的列能夠鋪滿所有的可用空間。
-
新增一個 Label 到 *SplitePane*的右邊部分,並設定它的顯示文字為 “Person Details” (提示: 你可以通過搜尋來找到 Label 這個控制元件)。 使用anchors來調節這個控制元件的佈局位置。
-
再新增一個 GridPane *SplitePane*的右邊部分, 使用anchors來調節這個控制元件的佈局位置。
-
按照下面的圖新增多個 *Lables*到表格中去。
-
注意: 新增一個控制元件到已經存在的行裡面去,你可在這行的行號上右鍵選擇 “Add Row”。
-
新增3個按鈕到這個 GridPane 的下面。 小提示: 選擇這3個按鈕,右鍵 *Wrap In | HBox*,那麼它們會被放置到一個HBox裡面。 你可能需要對這個HBox指定一個 spacing,同時也需要設定它們的右邊和下邊的anchors。
-
那麼基本已經完成了介面的設計,你可以通過 Preview 來預覽一下你設計的介面,同時縮放一下視窗來檢驗一下各個控制元件的位置是否正確。
建立主應用程式
我們還需要新建一個*FXML*檔案來做為主佈局檔案,它將包含選單欄並存放我們之前建立的佈局檔案 PersonOverview.fxml
。
-
在view包裡面建立一個新的 FXML Document 叫做
RootLayout.fxml
, 這一次,選擇 BorderPane 做為它的根節點 -
在Scene Builder中開啟
RootLayout.fxml
。 -
通過設定 Pref Width 為600和 Pref Height 為400來改變這個 *BorderPane*的尺寸。
-
在最頂上新增一個 *MenuBar*,先不去給這個選單新增任何的功能。
The JavaFX Main Class
現在,我們需要建立一個 main java class 用來載入 RootLayout.fxml
,同時新增 PersonOverview.fxml
到*RootLayout.fxml*中去,這個main class將做為我們這個應用程式的入口。
-
在工程上右鍵選擇 *New | Other…*,然後選擇 *JavaFX Main Class*。
-
將這個class命名為
MainApp
,將它放置到controller包中,也就是上面建的ch.makery.address
(注意: 這個包下有兩個子包,分別是view
和model
)。
你可能注意到了IDE生成的 MainApp.java
繼承自 Application
同時包含了兩個方法, 這是一個JavaFX應用程式的最基本的程式碼結構,這裡最重要的方法是 start(Stage primaryStage)
,它將會在應用程式執行時通過內部的 main
方法自動呼叫。
正如你所看到的,這個start(...)
方法會接收一個 Stage
型別的引數,下面的圖向你展示了一個JavaFX應用程式的基本結構。
一切看起來象是劇場裡表演: 這裡的 Stage
是一個主容器,它就是我們通常所認為的視窗(有邊,高和寬,還有關閉按鈕)。在這個 Stage
裡面,你可以放置一個 Scene
,當然你可以切換別的 Scene
,而在這個 Scene
裡面,我們就可以放置各種各樣的控制元件。
開啟 MainApp.java
,將已有的程式碼替換成下面的程式碼:
package ch.makery.address; import java.io.IOException; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class MainApp extends Application { private Stage primaryStage; private BorderPane rootLayout; @Override public void start(Stage primaryStage) { this.primaryStage = primaryStage; this.primaryStage.setTitle("AddressApp"); initRootLayout(); showPersonOverview(); } /** * Initializes the root layout. */ public void initRootLayout() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml")); rootLayout = (BorderPane) loader.load(); // Show the scene containing the root layout. Scene scene = new Scene(rootLayout); primaryStage.setScene(scene); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } /** * Shows the person overview inside the root layout. */ public void showPersonOverview() { try { // Load person overview. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/PersonOverview.fxml")); AnchorPane personOverview = (AnchorPane) loader.load(); // Set person overview into the center of root layout. rootLayout.setCenter(personOverview); } catch (IOException e) { e.printStackTrace(); } } /** * Returns the main stage. * @return */ public Stage getPrimaryStage() { return primaryStage; } public static void main(String[] args) { launch(args); } }
程式碼中的註釋會給你一些小提示,註明程式碼的含義。
如果你現在就執行這個程式,那麼你將會看到和這篇文章開頭所展示的圖片那樣的介面。
你有可能遇見的問題
如果你的應用程式找不到你所指定的 fxml
佈局檔案,那麼系統會提示以下的錯誤:
java.lang.IllegalStateException: Location is not set.
你可以檢查一下你的 fxml
檔名是否拼寫錯誤