第一部分的主題
- 開始了解 JavaFX 。
- 創建並運行一個 JavaFX 項目。
- 使用 Scene Builder 來設計用戶界面。
- 使用 模型 - 視圖 - 控制器(MVC)模式 構造基礎的應用。
你需要准備
- 最新的 Java JDK 8 (包含 JavaFX 8)。
- Eclipse 4.3 或更高版本與 e(fx)clipse 插件。最簡單的方法是從 e(fx)clipse 網站 下載預先配置的發行版本。作為一種備選你可以使用一個 update site 來給您的 Eclipse 安裝。
- Scene Builder 2.0 或更高。
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 可執行文件的路徑。
幫助鏈接
你可能會想收藏下面的鏈接:
- Java 8 API - Java 標准類的文檔。
- JavaFX 8 API - JavaFX 類的文檔。
- ControlsFX API - ControlsFX project 額外 JavaFX 控件的文檔。
- Oracle’s JavaFX Tutorials - Oracle 的 JavaFX 官方教程。
一切就緒,讓我們開始吧!
創建一個新的 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應用程序的基本結構。
Image Source: http://www.oracle.com
一切看起來象是劇場里表演: 這里的 Stage
是一個主容器,它就是我們通常所認為的窗口(有邊,高和寬,還有關閉按鈕)。在這個 Stage
里面,你可以放置一個 Scene
,當然你可以切換別的 Scene
,而在這個 Scene
里面,我們就可以放置各種各樣的控件。
更詳細的信息,你可以參考 Working with the JavaFX Scene Graph.
打開 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
文件名是否拼寫錯誤