JavaFX与WPF相比有何优劣之处?

101

我大部分是C#程序员,大约10年前就停止了编写Java,但我通过阅读文章,与朋友交谈等方式尝试着跟上Java技术的发展。

我听说过一种名为JavaFX的新型富GUI框架,但找不到任何将其与非Java并行技术进行比较的资源。

由于我对C#和WPF非常熟悉,我想了解一下这两种技术在多大程度上相似或不同。

编辑:由于没有答案出现,我将尝试更加具体:

  1. WPF使用XAML创建可视树,JavaFX是否有类似的东西?
  2. 最好将WPF与MVVM模式中的视图模型绑定一起使用,JavaFX是否也广泛使用绑定?
  3. WPF利用GPU进行渲染,JavaFX是否也是如此?
  4. 当在网络PC上通过浏览器运行时,Silverlight与JavaFX相比如何?

...更多内容即将到来...

我将此更改为社区Wiki,以便可以不断更新比较(希望如此)。


11
有趣的是,一个得到83个赞的问题却被认为不够建设性。 - kristianp
2个回答

128
我已经学习了几周的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类似的方式公开这些属性,具有获取和设置属性的方法以及返回属性包装器实例的方法(不像WPF属性那样是静态的)。
可以在多个属性之间创建复杂的绑定。想要一个整数属性成为另外两个属性的和(a = b + c)?没问题,JavaFX提供了一种流畅的API来表达这些关系,例如:
A.Add(B, C);
如果B或C的值发生变化,那么将会引发相应通知,以便系统知道A需要重新评估。请注意,在这种情况下,如果您尝试设置A的值,将会抛出异常,因为它绑定了其他属性,所以在这个上下文中没有意义。
这些表达式可能非常复杂,如a = (b + c) * (d - e),并且可以包含任意数量的属性。流畅的API非常易于阅读和使用,但不像一些Microsoft库提供的流畅API那样好用,但这更多是由于Java语言的限制而不是JavaFX本身造成的。
可以在同一类型的属性之间创建简单的双向绑定,以便如果一个更新了,另一个自动反映更改。
JavaFX还提供了一个低级API,以便自定义绑定,如果您想创建未由API提供的自定义绑定表达式,或者如果您关心性能。
JavaFX和WPF之间最大的区别之一是,在JavaFX中主要在代码中进行绑定,而在WPF中建立绑定的方式则是在标记中。

有关属性和绑定的介绍可以在这里找到。

样式

JavaFX使用CSS来改变场景图中包含的节点的外观。有一个完整的规范可用,其中解释了可以设置在每个节点类型上的类型和属性。

JavaFX还提供了一些附加功能,例如可以定义并在其他地方使用的变量。

.button {
    my-custom-color: RGB(234, 44, 78);
}

.my-control {
    -fx-background-color: my-custom-color
}

它还提供了一些函数,允许您从其他先前定义的颜色中派生颜色,这对于创建渐变等内容非常有用。这意味着可以定义一组基本颜色,其余颜色可以从这些值生成(这就是默认的JavaFX CSS文件所做的)。

JavaFX CSS不允许您定义节点使用的布局类型(截至编写本文时,所有布局都需要在代码中执行)。对我来说,这很好,因为这是我在使用HTML时真正感到痛苦的CSS方面之一。

个人而言,我更喜欢CSS而不是XAML样式,后者对我来说太冗长。

JavaFX CSS指南可以在这里找到。

布局

JavaFX提供了许多布局面板,类似于WPF提供的那些。我注意到的一个区别是,在Region类中进一步定义了测量和布局协定。

如先前所述,布局不能使用CSS进行,但可使用代码、FXML进行表达或使用场景构建器创建(最终转换为FXML)。

控件

JavaFX提供了一个日益壮大的控件库,这是我们所期望的。JavaFX和WPF之间的一个主要区别在于,控件本质上是黑盒子,不能像WPF控件那样重新模板化。它们似乎也暴露出比WPF控件更少的属性。

控件确实向CSS公开了一些具体实现的区域,允许您的样式针对控件的特定区域进行定位。这被称为控件的子结构。例如,CheckBox公开了两个子结构;方框和勾号允许分别为控件的每个部分单独设定样式。请注意,正如前面描述的那样,只能使用CSS更改控件的外观,但不能更改其感觉。例如,您不能通过更改WPF TabControl中的内部布局面板的方式来大幅更改TabPane的内容布局方式。

虽然听起来有点限制,但在JavaFX中创建自定义控件的首选方法似乎是使用组合,沿用布局面板派生标准控件并使用CSS重新设置它们的样式。

结论

总体而言,我对JavaFX目前的表现印象非常深刻。虽然它还远没有WPF成熟,但它正在积极开发中,甲骨文公司肯定在支持这一点。时间会告诉我们它是否成功。

我建议你试试JavaFX。阅读文档,尝试编写一个小应用程序,看看你的想法。

你还应该查看FXExperience.com,这个网站会定期更新开发团队的信息。


9
非常感谢这个,它非常有教育意义。如果您在 JavaFX 方面的知识更加深入并能进一步完善这个答案,那就太好了。 - Aviad P.
5
我很喜欢阅读您的答案,如果您在使用JavaFX时能够发��更多有见地的内容,我会很乐意听取。 - Paul-Sebastian Manole

21

我认为最好的了解JavaFX的方法就是亲自尝试。在JavaFX网站上有一些不错的教程,以下是其中的几个:

它们很简单,能够让您对该语言有一个很好的感觉。如果您对更多教程和文章感兴趣,JavaFX网站上还有许多其他资源。

如果您有具体问题需要回答:

  1. JavaFX有自己的声明性语言用于创建“可视树”,这不是xml的派生物。UI基于场景图,因此可以对图中的任何节点应用各种效果和动画。请参阅教程以获取更多信息。还有一个JavaFX设计工具(我还没有尝试过)。
  2. JavaFX内置了绑定
  3. 桌面上的JavaFX使用Java AWT/Swing,它使用GPU渲染。每个Java版本似乎都会将其图形的更多部分卸载到GPU上。来自Sun的Chris Campbell在博客中谈到了GPU加速。我不确定移动版的JavaFX是否具有GPU加速。我发现早期版本的JavaFX性能不够好,无法满足我的需求,但我知道最新版本相比以前的版本有显着的性能改进,并且他们仍在努力使其更快。
  4. JavaFx使用Java Applets在浏览器中运行。从Java 6更新10开始,Java applet框架已经重做过,虽然它不像Adobe Flash那样无缝,但它有很大的改进。我不确定它与Silverlight的比较情况,除了我在Linux上无法让Silverlight正常工作,但确实让JavaFX在Linux上工作了。

这是另一个相关的问题


15
这个答案已过时,因为JavaFX在Java 7中经历了重大更新。请参见此处 - Zoltán
7
你确定JavaFX使用swing和AWT吗?我认为它有自己的渲染引擎叫做prism。运行JavaFX应用程序时不会创建任何事件派发线程。 - Andy Till

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接