译自Why TornadoFX?
介绍
用户界面对消费者和商业应用的成功越来越重要。 随着消费者移动应用程序和Web应用程序的兴起,企业用户越来越多地将企业应用程序保持在更高的质量水平。 他们需要丰富的功能,丰富的用户界面,提供直观的洞察力,直观地浏览复杂的屏幕。 更重要的是,他们希望应用程序能够频繁地适应业务变化。 对于开发人员来说,这意味着应用程序不仅要可以维护,而且可以演化。 TornadoFX旨在帮助所有这些目标,并大大简化JavaFX UI的编码。
虽然大部分企业IT世界正在推动HTML5和基于云的应用程序,但许多企业仍在使用像JavaFX这样的桌面UI框架。 虽然它不像Web应用程序那样轻易地分发给大众,但JavaFX适用于“内部”业务应用程序。 它的高性能与大型数据集(事实上它是本机Java)使其成为企业防火墙后面应用程序的实际选择。
像许多UI框架一样,JavaFX可能会很快变得冗长且难以维护。 幸运的是,Kotlin的发布创造了一个机会来重新思考如何构建JavaFX应用程序。
正在开发的一个有趣的产品是JPro,一个基于Web的JavaFX容器,不使用插件。 它可以与TornadoFX和JavaFX配合使用,但在本文写作时仍然处于封闭式测试阶段。 您可以follow该项目并等待其可用性: https://jpro.io/
为什么选择TornadoFX?
2016年2月,JetBrains发布了Kotlin,一种新的JVM语言,强调实用主义。 Kotlin在更高级别的抽象中工作,并提供Java中不可用的实用语言功能。 Kotlin的一个更重要的功能是与现有Java库和代码库(包括JavaFX)的100%互操作性。
虽然JavaFX可以与Java一样在Kotlin中使用,但还是有些人认为Kotlin具有的语言功能可以简化JavaFX的开发。 在Kotlin测试版之前,Eugen Kiss用KotlinFX将JavaFX “构建器(builders)” 原型化。 2016年1月,Edvin Syse重新启动了该计划并发布了TornadoFX。
TornadoFX旨在大大减少构建JavaFX应用程序所需的代码量。 它不仅包括快速布局控件和用户界面的类型安全构建器(type-safe builders),还包括依赖注入,委托属性,控件扩展功能(dependency injection, delegated properties, control extension functions)以及Kotlin使能的其他实用功能。 TornadoFX是Kotlin可以简化代码库的精美展示,它以优雅和简单的方式解决了UI代码的冗长性问题。 它可以与其他流行的JavaFX库(如ControlsFX 和JFXtras)协同工作。 它与反应式框架(如ReactFX)以及RxJava和友库(包括 RxJavaFX, RxKotlin, 和RxKotlinFX) 非常相似 。
读者要求
这本书希望读者能够了解Kotlin的知识,并花了一些时间了解它。 将有一些Kotlin语言功能的覆盖,但仅在一定程度上。 如果您还没有这样做,请阅读JetBrains Kotlin参考资料(JetBrains Kotlin Reference),并花上好几个小时研究它。
熟悉JavaFX肯定是有助的,但这不是一个要求。 也许你刚开始学习JavaFX,但发现其开发体验是乏味的,所以你正在审视TornadoFX,希望它提供了一种更好的方式来构建用户界面。 如果这描述了你的体验,而且你正在学习Kotlin,那么你可能会受益于本指南。
一个撩动你的例子
如果你以前使用过JavaFX,则可能会在某个时候创建一个TableView 。 假设你有一个给定领域类型的Person
。 TornadoFX允许您更简洁地创建类似JavaBeans风格的用于JavaFX的绑定。
class Person(id: Int, name: String, birthday: LocalDate) {
val idProperty = SimpleIntegerProperty(id)
var id by idProperty
val nameProperty = SimpleStringProperty(name)
var name by nameProperty
val birthdayProperty = SimpleObjectProperty(birthday)
var birthday by birthdayProperty
val age: Int get() = Period.between(birthday, LocalDate.now()).years
}
然后,您可以构建一个包含TableView的整个“ View ”,其代码占用空间很小。
class MyView : View() {
private val persons = listOf(
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))
).observable()
override val root = tableview(persons) {
column("ID", Person::idProperty)
column("Name", Person::nameProperty)
column("Birthday", Person::birthdayProperty)
column("Age", Person::age)
}
}
渲染输出:
该代码的一半只是初始化样本数据! 如果您关注声明TableView
的四个列(如下所示)的部分,您将看到它需要一个简单的功能构造来构建TableView
。 它也会自动支持对字段的编辑。
tableview(persons) {
column("ID", Person::idProperty)
column("Name", Person::nameProperty)
column("Birthday", Person::birthdayProperty)
column("Age", Person::age)
}
如下所示,我们可以在TableColumn
上使用cellFormat()
扩展函数,并为“Age”值创建小于18
的条件格式。
tableview<Person> {
items = persons
column("ID", Person::idProperty)
column("Name", Person::nameProperty)
column("Birthday", Person::birthdayProperty)
column("Age", Person::age).cellFormat {
text = it.toString()
style {
if (it < 18) {
backgroundColor += c("#8b0000")
textFill = Color.WHITE
}
}
}
}
渲染输出:
这些声明是纯Kotlin代码,而TornadoFX包含了数十种类似这样的情况的表现力。 这允许您专注于创建解决方案,而不是苦于构建UI代码。 您的JavaFX应用程序不仅可以更快地转变,而且可以维护和演进。