过去几周我一直在学习 JavaFX。以下是我眼中它与 WPF 的比较的高级概述:
我所有的评论都与 JavaFX 2.0 有关。由于该平台还相当不成熟并且正在积极开发中,因此这些信息可能会发生变化。
图形
与 WPF 一样,JavaFX 使用保留的图形渲染系统。用户界面包含一个场景图,该场景图由“节点”组成,可以认为在概念上类似于 WPF 的UIElement
.
如果可用,JavaFX 会将图形渲染卸载到 GPU。图形系统在 Windows 上使用 DirectX,在其他平台上使用 OpenGL。
标记
JavaFX 用户界面既可以用代码创建,也可以通过类似于 XAML 的 FXML 标记创建,因为对象图可以通过嵌套元素创建。
FXML 具有与 XAML 类似的一些特性,例如属性绑定(仅限简单表达式)和绑定到事件处理程序(任何onEvent方法)。事件处理程序可以内联声明,但通常您会绑定到关联控制器中的事件。
FXML 文件可以有一个关联的控制器,它允许您声明复杂的事件处理程序并设置属性之间的绑定。这是 MVC 意义上的控制器,与 WPF 世界中的 viewModel 不同(通常,控制器将引用节点和控件)。
与 WPF 的一个区别是 FXML 似乎没有被编译成像 BAML 这样的中间二进制表示。我还没有注意到任何性能问题,但没有广泛使用该系统。不过我注意到,FXML 通常比任何 XAML 都短,因为该平台仍然鼓励您编写代码并且单独声明样式。
可以在此处找到对 FXML 的介绍。
免费提供了一个场景构建器(如啤酒),因此如果您不喜欢手动编写 UI,您可以拖放元素、设置属性并绑定到控制器中的代码,然后 FXML 将自动生成。显然,场景构建器远没有 Expression Blend 强大,但它仍然比 Visual Studio 提供的“设计器”要好。
捆绑
JavaFX 有一个非常强大的属性和绑定系统。Java Bean 模式已扩展为包括封装属性的类(类似于 WPF 依赖项属性表示属性的方式)。这些类实现了提供失效和更改通知的接口。
失效通知和变更通知是有区别的。失效只是告诉你绑定表达式现在无效,需要重新计算;get()
在您通过其或getValue()
方法请求属性值之前,实际上不会发生重新计算。但是,如果您注册了更改侦听器,则表达式将立即重新评估,并且绑定到该属性的任何内容都将反映更改。
JavaFX 以与 WPF 类似的方式公开这些属性,其中包含一个 get 和 set 属性以及一个返回属性包装器实例的方法(它们不像 WPF 属性那样是静态的)。
可以在多个属性之间创建复杂的绑定。想要一个整数属性是其他两个属性的总和(a = b + c)?没问题,JavaFX 提供了一个 Fluent API 来表达这些关系 EG
A.添加(B,C);
如果 B 或 C 的值发生变化,则会发出适当的通知,以便系统知道 A 需要重新评估。请注意,在这种情况下,如果您尝试设置 A 的值,则会引发异常,因为它绑定到其他属性,因此在此上下文中没有意义。
这些表达式可以是相当复杂的 EG a = (b + c) * (d - e)
,并且可以包含任意数量的属性。Fluent API 相当易于阅读和使用,但不如某些 Microsoft 库提供的 Fluent API 好,但这更多是由于 Java 语言限制而不是 JavaFX 本身。
可以在相同类型的属性之间创建简单的双向绑定,以便在更新一个属性时,另一个会自动反映更改。
如果您想创建 API 未提供的自定义绑定表达式,或者您关心性能,JavaFX 还提供了一个低级 API 来自定义绑定。
JavaFX 和 WPF 之间的最大区别之一是绑定主要在 JavaFX 中的代码中执行,而 WPF 在标记中建立绑定的方式。
可以在此处找到对属性和绑定的介绍。
风格
JavaFX 使用 CSS 来更改场景图中包含的节点的外观。有一个完整的规范可用,它解释了可以在每个节点类型上设置的类型和属性。
JavaFX 还提供了一些有助于改进 CSS 的附加功能,例如可以在其他地方定义和使用的变量 EG
.button {
my-custom-color: RGB(234, 44, 78);
}
.my-control {
-fx-background-color: my-custom-color
}
它还提供了一些函数,允许您从其他先前定义的颜色中派生颜色,这对于创建渐变之类的东西很有用。这意味着可以定义基本调色板,其余的可以从这些值生成(这是默认的 JavaFX CSS 文件所做的)。
JavaFX CSS 不允许您定义节点使用的布局类型(在撰写本文时,所有布局都需要在代码中执行)。这对我来说非常有效,因为这是 CSS 在与 HTML 一起使用时真正让我感到痛苦的一个方面。
就我个人而言,我更喜欢 CSS 而不是 XAML 样式,因为我喜欢这些样式过于冗长。
可以在此处找到 JavaFX CSS 指南。
布局
JavaFX 提供了许多类似于 WPF 提供的布局窗格。我注意到的一个区别是度量和布局契约是在Region
类中的继承链上进一步定义的。
如前所述,Layout 不能使用 CSS 进行,但可以使用代码、FXML 表示或使用场景构建器(最终转换为 FXML)创建。
控件
JavaFX 提供了我们所期望的不断增长的控件库。JavaFX 和 WPF 之间的一个主要区别是控件本质上是黑盒,不能像 WPF 控件那样重新模板化。它们似乎也比 WPF 控件公开的属性少得多。
这些控件确实向 CSS 公开了一些特定于实现的区域,从而允许您的样式以控件的特定区域为目标。这被称为控件的子结构。EG aCheckBox
暴露了两个子结构;框和复选标记允许控件的每个部分独立设置样式。请注意,如前所述,只能使用 CSS 更改控件的外观,但不能更改感觉。例如,您不能像使用 WPF 那样通过改变其内部布局面板来显着改变 aTabPane
布局其内容的方式TabControl
。
虽然这听起来相当有限,但在 JavaFX 中创建自定义控件的首选方式似乎是使用从布局面板派生的组合来定位标准控件并使用 CSS 重新设置它们的样式。
结论
总的来说,我对 JavaFX 目前所提供的东西印象深刻。虽然它远没有 WPF 那样成熟,但它正在积极开发中,而 Oracle 似乎当然支持这一点。时间会证明它是否成功。
我建议尝试一下 JavaFX。阅读文档并尝试组合一个小型应用程序,看看您的想法。
您还应该查看FXExperience.com,该网站会定期更新开发团队的信息。