首页 文章

JavaFX与WPF相比如何? [关闭]

提问于
浏览
84

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

我听说过一个名为JavaFX的新的丰富的GUI框架,但找不到任何资源与非Java的相似之处 .

由于我对C#和WPF非常熟悉,所以我想了解两种技术的相似或不同之处 .

编辑:看到没有答案,我会尝试更具体:

  • WPF使用XAML创建可视树,JavaFX有类似的东西吗?

  • WPF最适合与MVVM模式中的视图模型绑定,JavaFX是否也广泛使用绑定?

  • WPF利用GPU进行渲染,JavaFX也这样做吗?

  • 当通过网络上的浏览器运行时,Silverlight与JavaFX相比如何?

......更多......

我正在将此更改为社区维基,以便比较可以不断更新(希望如此) .

2 回答

  • 112

    我在过去几周一直在学习JavaFX . 以下是我在眼中与WPF进行比较的高级概述:

    我的所有评论都与JavaFX 2.0有关 . 由于平台仍然相当不成熟并且正在积极开发,因此这些信息可能会发生变化 .

    Graphics

    与WPF一样,JavaFX使用保留的图形渲染系统 . 用户界面包括一个场景图,它由'nodes'组成,可以被认为在概念上类似于WPF的 UIElement .

    如果可用,JavaFX会将图形渲染卸载到GPU . 图形系统在Windows上使用DirectX,在其他平台上使用OpenGL .

    Markup

    JavaFX用户界面既可以通过代码创建,也可以通过FXML标记创建,类似于XAML,因为对象图可以通过嵌套元素创建 .

    FXML具有一些与XAML类似的功能,例如属性绑定(仅限简单表达式)和绑定到事件处理程序(任何onEvent方法) . 事件处理程序可以在线声明,但通常会绑定到关联控制器中的事件 .

    FXML文件可以有一个关联的控制器,允许您声明复杂的事件处理程序并设置属性之间的绑定 . 这是MVC意义上的控制器,与WPF世界中的viewModel不同(通常控制器将引用节点和控件) .

    与WPF的一个区别是,似乎FXML没有被编译成像BAML这样的中间二进制表示 . 我还没有注意到任何性能问题,但没有广泛使用该系统 . 我注意到,FXML通常比任何XAML都短,因为平台仍然鼓励你编写代码并且样式是单独声明的 .

    可以找到FXML的介绍here .

    场景构建器是免费提供的(如啤酒中所示),因此如果您不喜欢手动编码UI,您可以拖放元素,设置属性并绑定到控制器中的代码,并自动生成FXML . 显然,场景构建器远没有Expression Blend那么强大,但它仍然比Visual Studio提供的“设计器”更好 .

    Binding

    JavaFX具有非常强大的属性和绑定系统 . Java Bean模式已扩展为包含封装属性的类(类似于WPF依赖属性表示属性的方式) . 这些类实现了提供失效和更改通知的接口 .

    无效通知和更改通知之间存在区别 . 无效只是告诉您绑定表达式现在无效,需要重新计算;在您通过 get()getValue() 方法请求属性值之前,实际上不会发生重新计算 . 但是,如果已注册更改侦听器,则将立即重新计算表达式,并且绑定到该属性的任何内容都将反映更改 .

    JavaFX以类似于WPF的方式公开这些属性,具有get和set属性以及返回属性包装器实例的方法(不像WPF属性那样是静态的) .

    可以在多个属性之间创建复杂绑定 . 想要一个整数属性是另外两个的总和(a = b c)?没问题,JavaFX提供了一个Fluent API来表达这种关系E.G.

    A.添加(B,C);

    如果B或C的值发生更改,则会发出相应的通知将被提出,以便系统知道A需要重新评估 . 请注意,在这种情况下,如果您尝试设置A的值,因为它绑定到其他属性,将抛出异常,因此在此上下文中没有意义 .

    这些表达式可能相当复杂 . a = (b + c) * (d - e) 并且可以包含任意数量的属性 . 流畅的API相当容易阅读和使用,但不如某些Microsoft库提供的一些Fluent API那么好,但这更多的是Java语言限制而不是JavaFX本身 .

    可以在相同类型的属性之间创建简单的双向绑定,以便在更新一个属性时,另一个自动反映更改 .

    如果要创建API未提供的自定义绑定表达式或者您关心性能,JavaFX还提供了一个低级API来自行自定义绑定 .

    JavaFX和WPF之间最大的区别之一是绑定主要在JavaFX中的代码中执行,而WPF在标记中 Build 绑定的方式 .

    可以找到属性和绑定的介绍here .

    Styles

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

    JavaFX还提供了一些有助于改进CSS的附加功能,例如可在其他地方定义和使用的变量 .

    .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指南here .

    Layout

    JavaFX提供了许多与WPF提供的布局窗格类似的布局窗格 . 我注意到的一个区别是度量和布局 Contract 是在 Region 类的继承链中进一步定义的 .

    如前所述,布局不能使用CSS执行,但可以使用代码,FXML表示或使用场景构建器(最终转换为FXML)创建 .

    Controls

    JavaFX提供了我们期待的不断增长的控件库 . JavaFX和WPF之间的一个主要区别是控件本质上是黑盒子,并且不能以WPF控件的方式重新模板化 . 它们似乎也暴露出比WPF控件少得多的属性 .

    控件确实将一些特定于实现的区域暴露给CSS,从而允许控件的特定区域由您的样式定位 . 这被称为对照的子结构 . 例如 . a CheckBox 暴露了两个子结构;框和复选标记允许控件的每个部分独立设置样式 . 请注意,如前所述,只能使用CSS更改控件的外观,但感觉不能 . 例如 . 你无法通过改变WPF TabControl 的方式来改变其内部布局面板,从而大大改变了 TabPane 的内容 .

    虽然这听起来相当有限,但在JavaFX中创建自定义控件的首选方法似乎是使用从布局面板派生的位置来定位标准控件并使用CSS重新设置样式 .

    Conclusion

    总的来说,我对JavaFX目前所提供的内容印象非常深刻 . 虽然它不像WPF那样成熟,但它正在积极开发,而甲骨文肯定似乎支持这一点 . 时间将证明它是否成功 .

    我建议尝试一下JavaFX . 阅读documentation并尝试整理一个小应用程序,看看你的想法 .

    您还应该查看FXExperience.com,它会定期更新,并提供开发团队提供的信息 .

  • 20

    我认为了解JavaFX的最佳方法就是尝试一下 . JavaFX网站上有一些很好的教程 . 这是一对夫妇:

    它们非常快,让您对语言有一种良好的感觉 . 如果您对更多教程和文章感兴趣,JavaFX网站上还有很多其他内容 .

    有关您问题的具体答案:

    • JavaFX有自己的声明性语言来创建"visual tree",它不是xml衍生物 . UI基于场景图,因此您可以将各种效果和动画应用于图形中的任何节点 . 有关更多信息,请参阅教程 . 还有一个JavaFX的设计工具(我还没有尝试过) .

    • JavaFX has binding built into the language .

    • 桌面上的JavaFX使用Java AWT / Swing,它使用GPU渲染 . 每个版本的Java似乎都会将更多的图形卸载到GPU上 . 来自Sun的Chris Campbell在博客上写了一些关于GPU acceleration的内容 . 我的性能足够我所需要的,但我知道最新版本确实比以前的版本有显着的性能改进,他们仍在努力使其更快 .

    • JavaFx使用Java Applet在浏览器中运行 . 从Java 6更新10开始,Java applet框架已被重新设计,虽然它不像Adobe Flash那样无缝,但它得到了很大的改进 . 我没有让Silverlight在Linux上工作,但确实让JavaFX在Linux上运行 .

    Here's another related question .

相关问题