「译」Maven 集成 JavaFX 8 以及「fx:root」问题探讨
上一篇文章探讨了使用 IntelliJ IDEA 创建 JavaFX 工程,进而开发了所需应用程序。更实际的情况是需要使用 Maven, Gradle 等进行项目的构建。本文探讨使用 Maven 构建集成 JavaFX 8 的可执行程序的方法,以及 <fx:root> 根节点问题。
1. Maven 构建的程序未集成 FXML 布局文件
使用 Maven 直接构建,在 compile 阶段, .class 文件均被复制到 target/classes/ 目录,而对于 .FXML 文件,则分如下情况:
simple.fxml文件位于src/main/resources/目录中,在compile阶段,simple.fxml会按照层级复制到target/classes/目录中,执行:1
2getClass().getClassLoader().getResource("simple.fxml")
getClass().getResource("/simple.fxml")为了方便使用,
simple.fxml文件位于其 Controller 的同级目录中,此时在compile阶段,simple.fxml会被忽略掉,Maven 不会复制位于src目录下的任何资源文件,故需要采取其他策略,通过搜索StackOverflow发现了解决方法如下:在
pom.xml文件中添加如下resource插件即可解决问题:1
2
3
4
5
6
7
8
9
10
11
12
13<build>
...
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.fxml</include>
</includes>
</resource>
<resources>
...
</build>此时所有的
.fxml文件均会被完整复制到src下的同级目录。
使用 Maven 构建可执行 Jar 可使用通用方法,具体参考:镜像1、镜像2
可执行 Jar 构建完毕后,在 Windows 平台下可以直接双击执行。
2. FXML 文件中,「fx:root」根节点问题探讨
为了更加方便灵活地使用自定义控件,更方便的集成 Controller 和 FXML 资源文件,以下内容对 StackOverflow 的一则回复进行翻译修改:
假设想要设计一个自定义控件:HBox 中包含 TextField 和 Button,不使用 FXML 文件时,自定义控件设计如下:
1 | public class MyComponent extends HBox { |
此时可对该自定义控件方便地设计逻辑代码。
若使用 FXML 文件时,如:
1 | <HBox> |
此时 HBox 的 Controller 定义如下:
1 | public class MyComponent extends HBox { |
此时该自定义控件为一个 HBox 包裹一个 HBox,子 HBox 才包含 TextField 和 Button,所以无法实现开始时,纯代码方式的自定义控件设计。
而使用 <fx:root> 后,可指导 Controller 类作为「根节点」,避免了 HBox 嵌套 HBox 的情况。
FXML 文件设计如下:
1 | <fx:root type="javafx.scene.layout.HBox"> |
FXML 文件同时指明了根节点的类型,资源文件对应的 Controller 设计如下:
1 | public class MyComponent extends HBox { |
此时可实现开始时,纯代码方式的自定义控件设计。