
第一部分的主題
- 開始了解 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 文件名是否拼寫錯誤
