1. 简介
本文将介绍 TornadoFX 是什么,如何在 Oracle JDK 和 OpenJDK 上进行环境搭建。我们还会解析其架构组成,并快速浏览一些常用控件的使用方式。
在开始前,建议你对 JavaFX 有一定了解——虽然不是必须的。因为 TornadoFX 本质上是 Kotlin 的 JavaFX 框架,它充分利用了 Kotlin 的语言特性,比如声明式 UI、依赖注入、委托属性、扩展函数等,极大提升了开发效率和代码可读性。
⚠️ 需要特别注意:TornadoFX 目前尚未支持 Java 9 及以上版本,因此推荐使用 Java 8。这一点在项目选型时务必留意,避免踩坑。
2. 环境搭建
本节将演示如何从零开始配置一个 TornadoFX 项目,分别基于 Maven 和 Gradle。
2.1. OpenJDK
如果你使用的是 Linux 系统,大概率会用 OpenJDK。但要注意:OpenJDK 默认不包含 JavaFX 模块,所以需要手动引入,配置相对复杂。
✅ 正确做法:
- 升级 OpenJDK 至 11 或更高版本
- 使用
javafxplugin
插件管理 JavaFX 依赖
Gradle 配置(build.gradle)
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.5.10'
id 'org.openjfx.javafxplugin' version '0.0.8'
id 'application'
}
compileKotlin {
kotlinOptions.jvmTarget = "11"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "11"
}
javafx {
version = "11.0.2"
modules = ['javafx.controls', 'javafx.graphics']
}
repositories {
mavenCentral()
}
dependencies {
implementation platform('org.jetbrains.kotlin:kotlin-bom')
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation "no.tornado:tornadofx:1.7.20"
}
📌 提示:
- 最新 TornadoFX 版本请查阅 Maven Central
- OpenJFX 插件版本参考 Gradle Plugin Portal
Maven 配置(pom.xml)
先定义版本属性:
<properties>
<tornadofx.version>1.7.20</tornadofx.version>
</properties>
添加核心依赖:
<dependency>
<groupId>no.tornado</groupId>
<artifactId>tornadofx</artifactId>
<version>1.7.20</version>
</dependency>
由于 JavaFX 被拆分为多个模块,需显式引入以下组件:
<!-- JavaFX 基础模块 -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>17-ea+11</version>
</dependency>
<!-- 控件模块(ListView, MenuBar 等) -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17-ea+11</version>
</dependency>
同时添加 JavaFX Maven 插件用于运行:
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.3</version>
<configuration>
<mainClass>MyApp</mainClass>
</configuration>
</plugin>
</plugins>
⚠️ 注意:若项目使用模块化(module-info.java),需在 src/main/kotlin
下创建 module-info.kt
:
module TFXSAMPLE {
requires javafx.controls;
requires javafx.graphics;
requires javafx.base;
requires tornadofx;
requires kotlin.stdlib;
exports com.example.demo.app to javafx.graphics, tornadofx;
exports com.example.demo.view to tornadofx;
}
2.2. Oracle JDK
Oracle JDK 自带完整 JavaFX 支持,因此配置极其简单——无需额外引入 JavaFX 模块。
Gradle 配置
repositories {
mavenCentral()
}
dependencies {
implementation 'no.tornado:tornadofx:1.7.20'
}
Maven 配置
<dependency>
<groupId>no.tornado</groupId>
<artifactId>tornadofx</artifactId>
<version>1.7.20</version>
</dependency>
✅ 总结:
| JDK 类型 | 是否需手动引入 JavaFX | 配置复杂度 |
|--------------|------------------------|------------|
| OpenJDK | ✅ 是 | ⚠️ 高 |
| Oracle JDK | ❌ 否 | ✅ 低 |
3. 应用基础结构
和所有 Java/Kotlin 应用一样,TornadoFX 需要一个主类作为入口点。
创建 app
包并定义 MyApp
类,继承自 App
,并通过构造函数指定初始视图:
class MyApp : App(HelloWorld::class)
这里的 HelloWorld::class
即为启动后默认加载的视图类。
4. 视图类(View)
视图(View)负责 UI 展示逻辑与节点布局,类似于 JavaFX 中的 Stage 或 Scene。但与 FXML 不同,TornadoFX 使用纯 Kotlin 代码构建 UI,带来类型安全和编译时检查的优势。
创建 view
包并添加 HelloWorld
类:
import tornadofx.*
class HelloWorld : View() {
override val root = hbox {
label("Hello world")
}
}
关键点说明:
import tornadofx.*
必须存在,否则 IDE 无法识别 DSL 扩展函数hbox
是水平布局容器,label
为其子节点root
是视图的根节点,必须被重写
运行效果如下:
5. 样式处理(Styling)
TornadoFX 支持类型安全的 CSS 样式定义,可通过独立样式类或内联方式设置。
方式一:独立样式类
创建 Styles
类统一管理样式:
class Styles : Stylesheet() {
init {
label {
padding = box(10.px)
fontSize = 20.px
fontWeight = FontWeight.BOLD
}
}
}
然后在应用类中注册该样式表:
class MyApp : App(MainView::class, Styles::class)
效果呈现:
方式二:内联样式(Inline Style)
适用于局部覆盖或临时调整:
label("Hello world") {
style {
padding = box(10.px)
fontSize = 20.px
fontWeight = FontWeight.BOLD
}
}
✅ 内联样式的优先级高于全局样式,适合做动态样式覆盖。
6. 视图注入(View Injection)
TornadoFX 内建依赖注入机制,支持松耦合组件通信。
有两种注入方式:
方法 | 行为特点 | 推荐场景 |
---|---|---|
find() |
立即获取单例实例 | 简单引用,无循环依赖 |
inject() |
懒加载代理,首次访问时初始化 | 复杂组件、存在循环依赖 |
推荐使用 inject()
,优势在于:
- ✅ 支持循环依赖
- ✅ 实现懒加载,提升启动性能
示例代码:
class SampleView : View() {
private val headerView = find(HeaderView::class)
private val footerView: FooterView by inject()
override val root = borderpane {
top = headerView.root
bottom = footerView.root
}
}
7. 控制器(Controller)
遵循关注点分离原则,业务逻辑应与 UI 解耦。TornadoFX 提供 Controller
类实现这一模式。
典型用法:
- 创建 Controller 类继承
Controller
- 在 View 中通过
by inject()
注入控制器 - 绑定事件触发业务逻辑
class SampleView : View() {
private val controller: SampleController by inject()
private val input = SimpleStringProperty()
override val root = form {
fieldset {
field() {
textfield(input)
}
button("Post") {
action {
controller.postApi(input.value)
input.value = ""
}
}
}
}
}
class SampleController : Controller() {
fun postApi(inputValue: String) {
println("Doing backend stuff with $inputValue")
}
}
✅ 这种分层结构便于单元测试和维护,是大型项目的推荐实践。
8. 总结
本文带你快速入门 TornadoFX,涵盖环境搭建、视图定义、样式管理、依赖注入与控制器使用等核心内容。
虽然还有很多高级特性未涉及(如 REST 客户端、表格绑定、状态管理等),但已足够让你上手开发桌面应用。
📌 延伸学习资源:
- 官方文档:TornadoFX Guide
- 示例源码:GitHub - kotlin-tornadofx
对于熟悉 Kotlin 的开发者来说,TornadoFX 是构建现代 JavaFX 应用的高效选择,值得一试。