上一篇文章探討了使用 IntelliJ IDEA 創(chuàng)建 JavaFX 工程砚哆,進而開發(fā)了所需應(yīng)用程序勉失。更實際的情況是需要使用 Maven, Gradle 等進行項目的構(gòu)建羞海。本文探討使用 Maven 構(gòu)建集成 JavaFX 8 的可執(zhí)行程序的方法这吻,以及 <fx:root>
根節(jié)點問題琳轿。
1. Maven 構(gòu)建的程序未集成 FXML 布局文件
使用 Maven 直接構(gòu)建态鳖,在 compile
階段, .class
文件均被復(fù)制到 target/classes/
目錄转培,而對于 .FXML
文件,則分如下情況:
-
simple.fxml
文件位于src/main/resources/
目錄中浆竭,在compile
階段浸须,simple.fxml
會按照層級復(fù)制到target/classes/
目錄中,執(zhí)行:
getClass().getClassLoader().getResource("simple.fxml")
getClass().getResource("/simple.fxml")
- 為了方便使用邦泄,
simple.fxml
文件位于其 Controller 的同級目錄中删窒,此時在compile
階段,simple.fxml
會被忽略掉虎韵,Maven 不會復(fù)制位于src
目錄下的任何資源文件易稠,故需要采取其他策略,通過搜索StackOverflow
發(fā)現(xiàn)了解決方法如下:
在
pom.xml
文件中添加如下resource
插件即可解決問題:
<build>
...
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.fxml</include>
</includes>
</resource>
<resources>
...
</build>
此時所有的 .fxml
文件均會被完整復(fù)制到 src
下的同級目錄包蓝。
使用 Maven 構(gòu)建可執(zhí)行 Jar 可使用通用方法驶社,具體參考:鏡像1、鏡像2
可執(zhí)行 Jar 構(gòu)建完畢后测萎,在 Windows 平臺下可以直接雙擊執(zhí)行亡电。
2. FXML 文件中,「fx:root」根節(jié)點問題探討
為了更加方便靈活地使用自定義控件硅瞧,更方便的集成 Controller 和 FXML 資源文件份乒,以下內(nèi)容對 StackOverflow
的一則回復(fù)進行翻譯修改:
假設(shè)想要設(shè)計一個自定義控件:HBox
中包含 TextField
和 Button
,不使用 FXML
文件時腕唧,自定義控件設(shè)計如下:
public class MyComponent extends HBox {
private TextField textField ;
private Button button ;
public MyComponent() {
textField = new TextField();
button = new Button();
this.getChildren().addAll(textField, button);
}
}
此時可對該自定義控件方便地設(shè)計邏輯代碼或辖。
若使用 FXML
文件時,如:
<HBox>
<TextField fx:id="textField"/>
<Button fx:id="button" />
</HBox>
此時 HBox
的 Controller 定義如下:
public class MyComponent extends HBox {
@FXML
private TextField textField ;
@FXML
private Button button ;
public MyComponent() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
loader.setController(this);
HBox hbox = loader.load();
this.getChildren().add(hbox);
} catch (IOException exc) {
// handle exception
}
}
}
此時該自定義控件為一個 HBox
包裹一個 HBox
枣接,子 HBox
才包含 TextField
和 Button
颂暇,所以無法實現(xiàn)開始時,純代碼方式的自定義控件設(shè)計但惶。
而使用 <fx:root>
后耳鸯,可指導(dǎo) Controller 類作為「根節(jié)點」湿蛔,避免了 HBox
嵌套 HBox
的情況。
FXML 文件設(shè)計如下:
<fx:root type="javafx.scene.layout.HBox">
<TextField fx:id="textField" />
<Button fx:id="button" />
</fx:root>
FXML 文件同時指明了根節(jié)點的類型县爬,資源文件對應(yīng)的 Controller 設(shè)計如下:
public class MyComponent extends HBox {
@FXML
private TextField textField ;
@FXML
private Button button ;
public MyComponent() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
loader.setController(this);
loader.setRoot(this);
loader.load();
} catch (IOException exc) {
// handle exception
}
}
}
此時可實現(xiàn)開始時阳啥,純代碼方式的自定義控件設(shè)計。