最近两周我一直在学习JavaFX。这是我眼中与WPF相比的高级概述:
我所有的评论都与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的介绍可以在这里找到。
场景构建器是免费提供的(例如在啤酒中),因此,如果您不喜欢手动编码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
类中的继承链的更上方定义的。
如前所述,不能使用CSS来执行布局,而可以使用FXML代码来表示布局,也可以使用场景生成器(最终将其转换为FXML)来创建布局。
控制项
JavaFX提供了我们不断期望的不断增长的控件库。JavaFX和WPF之间的一个主要区别是控件本质上是黑盒,并且无法以WPF控件的方式重新进行模板化。它们似乎还比WPF控件公开了更少的属性。
控件确实向CSS公开了一些特定于实现的区域,从而允许您的样式将控件的特定区域作为目标。这就是控件的子结构。EG a CheckBox
暴露了两个子结构;框和复选标记允许控件的每个部分都可以独立设置样式。请注意,如前所述,仅控件的外观可以使用CSS进行更改,但是感觉无法更改。例如,您不能像TabPane
使用WPF那样通过改变其内部布局面板来显着改变布局内容的方式TabControl
。
尽管这听起来很有限,但是在JavaFX中创建自定义控件的首选方法似乎是沿着从布局面板派生来定位标准控件并使用CSS重新样式化的方式使用合成。
结论
总的来说,我对JavaFX目前提供的功能印象深刻。尽管它没有WPF那样成熟,但它正在积极开发中,Oracle显然支持这一点。时间会证明它是否成功。
我建议尝试一下JavaFX。阅读文档并尝试将一个小型应用程序放在一起,看看您的想法。
您还应该查看FXExperience.com,该网站会定期使用开发团队的信息进行更新。