桌面软件 已归档

tornadofx

edvin/tornadofx

面向 Kotlin 的轻量级 JavaFX 框架

3630
Stars 标星
267
Forks 分支
5
Watchers 关注
197
Open Issues
Kotlin
主要语言
Apache-2.0
开源协议
4.2 MB
仓库大小
3 年前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:edvin/tornadofx
git clone https://github.com/edvin/tornadofx.git
git clone git@github.com:edvin/tornadofx.git
README.md master

机器翻译正文由机器翻译自项目原始文档(英文),排版经程序统一处理,可能存在偏差,请以原项目仓库为准。

龙卷风FX

用于 Kotlin 的 JavaFX 框架

(该项目不再维护)

重要:TornadoFX 目前尚不兼容 Java 9/10

Oracle 打算将 JavaFX 从 JDK 中分离。我们将等待分离后的 JavaFX 可用且稳定后,再升级 TornadoFX 以支持它。目前,升级到 JDK 9/10 的价值很小,而所需的工作量很大,而升级到分离版本将具有巨大的价值。

功能

  • 支持 MVC、MVP 及其衍生模式
  • 依赖注入
  • 类型安全 GUI 构建器
  • 类型安全 CSS 构建器
  • 一流的 FXML 支持
  • 异步任务执行
  • 带线程目标的事件总线
  • 视图和样式表的热重载
  • OSGi 支持
  • 具有自动 JSON 转换的 REST 客户端
  • 零配置,无 XML,无注解

重要版本说明

TornadoFX 需要 Kotlin 1.1.2 和 jvmTarget 1.8。确保你更新了 IDE 插件(Kotlin 和 TornadoFX)。

更新 IntelliJ IDEA 后,确保你的 Kotlin 目标版本为 1.1(项目设置 -> 模块 -> Kotlin -> 语言版本 / API 版本)。

记得更新你的构建系统以配置 jvmTarget。

对于 Maven,你需要在 kotlin-maven-plugin 中添加以下配置块:

<configuration>
    <jvmTarget>1.8</jvmTarget>
</configuration>

对于 Gradle,这意味着配置 Kotlin 编译任务的 kotlinOptions:

compileKotlin {
    kotlinOptions.jvmTarget= "1.8"
}

如果不这样做,将会出现关于编译器无法内联某些调用的错误。

在版本升级后,你还需要对代码进行完整重建。如果遇到问题,可以尝试清理缓存并重启 IDEA(文件 -> 使缓存失效 / 重启)。

入门

使用 Maven 生成一个快速启动应用程序

mvn archetype:generate -DarchetypeGroupId=no.tornado \
  -DarchetypeArtifactId=tornadofx-quickstart-archetype \
  -DarchetypeVersion=1.7.20

将 TornadoFX 添加到您的项目中

专家

<dependency>
    <groupId>no.tornado</groupId>
    <artifactId>tornadofx</artifactId>
    <version>1.7.20</version>
</dependency>

Gradle

implementation 'no.tornado:tornadofx:1.7.20'

快照已发布到 Sonatype

如果您想尝试最新功能,请配置您的构建环境以使用快照:

 <repositories>
   <repository>
     <id>snapshots-repo</id>
     <url>https://oss.sonatype.org/content/repositories/snapshots</url>
     <releases><enabled>false</enabled></releases>
     <snapshots><enabled>true</enabled></snapshots>
   </repository>
 </repositories>

如果有任何更改,快照每天在格林尼治时间16:00发布。

它看起来像什么?(代码片段)

创建一个视图

class HelloWorld : View() {
    override val root = hbox {
        label("Hello world")
    }
}

启动您的应用程序,显示主要的 View,并添加类型安全的样式表

import javafx.scene.text.FontWeight
import tornadofx.*

class HelloWorldApp : App(HelloWorld::class, Styles::class)

class Styles : Stylesheet() {
    init {
        label {
            fontSize = 20.px
            fontWeight = FontWeight.BOLD
            backgroundColor += c("#cecece")
        }    
    }    
}

启动应用并加载类型安全的样式表

使用 类型安全的构建器 快速创建复杂的用户界面

class MyView : View() {
    private val persons = FXCollections.observableArrayList(
            Person(1, "Samantha Stuart", LocalDate.of(1981,12,4)),
            Person(2, "Tom Marks", LocalDate.of(2001,1,23)),
            Person(3, "Stuart Gills", LocalDate.of(1989,5,23)),
            Person(3, "Nicole Williams", LocalDate.of(1998,8,11))
    )

    override val root = tableview(persons) {
        column("ID", Person::id)
        column("Name", Person::name)
        column("Birthday", Person::birthday)
        column("Age", Person::age)
        columnResizePolicy = SmartResize.POLICY
    }
}

渲染的界面

创建一个可以在 JSON 与对象之间相互转换的 Customer 模型对象,并同时提供 JavaFX 属性以及 getter/setter 对:

import tornadofx.getValue
import tornadofx.setValue

class Customer : JsonModel {
    val idProperty = SimpleIntegerProperty()
    var id by idProperty

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    override fun updateModel(json: JsonObject) {
        with(json) {
            id = int("id") ?: 0
            name = string("name")
        }
    }

    override fun toJSON(json: JsonBuilder) {
        with(json) {
            add("id", id)
            add("name", name)
        }
    }
}

创建一个控制器,通过 REST API 下载客户的 JSON 列表:

class HelloWorldController : Controller() {
    val api : Rest by inject()

    fun loadCustomers(): ObservableList<Customer> = 
        api.get("customers").list().toModel() 
}

使用基本身份验证配置带有基本 URI 的 REST API:

with (api) {
    baseURI = "http://contoso.com/api"
    setBasicAuth("user", "secret")
}

在后台加载客户并在 UI 线程上更新 TableView:

runAsync {
    controller.loadCustomers()
} ui {
    customerTable.items = it
}

以声明方式加载客户并应用到表格:

customerTable.asyncItems { controller.loadCustomers() }

定义一个类型安全的 CSS 样式表:

class Styles : Stylesheet() {
    companion object {
        // Define css classes
        val heading by cssclass()

        // Define colors
        val mainColor = c("#bdbd22")
    }

    init {
        heading {
            textFill = mainColor
            fontSize = 20.px
            fontWeight = BOLD
        }

        button {
            padding = box(10.px, 20.px)
            fontWeight = BOLD
        }

        val flat = mixin {
            backgroundInsets += box(0.px)
            borderColor += box(Color.DARKGRAY)
        }

        s(button, textInput) {
            +flat
        }
    }
}

使用类型安全构建器创建一个包含标签和文本框的HBox:

hbox {
    label("Hello world") {
        addClass(heading)
    }

    textfield {
        promptText = "Enter your name"
    }
}

获取和设置每个组件的配置设置:

// set prefWidth from setting or default to 200.0
node.prefWidth(config.double("width", 200.0))

// set username and age, then save
with (config) {
    set("username", "john")
    set("age", 30)
    save()
}

创建一个 Fragment 而不是 View。Fragment 并不像 View 那样是 Singleton,所以你将创建一个新实例,并且可以在多个 UI 位置同时重用该 Fragment。

class MyFragment : Fragment() {
    override val root = hbox {
    }
}

在模态窗口中打开它:

find<MyFragment>().openModal()

一次查找并将一个 View 嵌入到另一个 Pane 中

add<MyFragment>()

注入一个 View 并嵌入到另一个 Pane 内

val myView: MyView by inject()

init {
    root.add(myFragment)
}

将一个视图换成另一个(更改场景根或嵌入视图)

button("Go to next page") {
    action {
        replaceWith<PageTwo>(ViewTransition.Slide(0.3.seconds, Direction.LEFT)
    }
}

在当前场景图上方的内部窗口中打开视图

button("Open") {
    action {
        openInternalWindow<MyOtherView>()
    }
}
本站来源与版权声明
  • 本文标题:tornadofx - 面向 Kotlin 的轻量级 JavaFX 框架
  • 本文链接:https://www.cn121.com/desktop/edvin-tornadofx.html
  • 原项目:edvin/tornadofx 版权归原作者 edvin 及贡献者所有
  • 收录信息:本站于 2026-10-16 收录本项目,本页所列协议与仓库指标均为收录当时的状态;该日期之后原项目的版本更新与协议变更,本页不作同步。
  • 开源协议:收录时本项目采用 Apache-2.0(查看 LICENSE 原文),本站译文为其衍生内容;使用、修改、分发请以该仓库 LICENSE 原文为准。本站对原文仅作排版与图片地址适配, 并保留原项目的 NOTICE 与署名要求。
  • 站点出处:本文首发于 OneTwoOne,收录自 GitHub 开源项目 edvin/tornadofx。
  • 翻译说明:本页正文为人工智能生成内容——由机器翻译对原项目 README 初译、经程序校验排版,可能存在错漏,请以原项目文档为准。
  • 引用声明:商业转载、第三方聚合或 AI 检索训练引用时,请务必保留以上来源出处、本文永久链接,以及原项目的版权声明与许可信息。
  • 下架通道:若原项目此后变更或收紧了许可协议、或作者/权利人认为本站的收录方式(译文、排版适配、简介翻译等)超出其授权范围,请通过 xyd3302001@163.com 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。