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