在JavaFX自定义控件中,我们应该使用FXML吗?

9

看起来有些奇怪,我认为使用FXML编写自定义组件显然是正确的方式。

但是从ControlsFX、JFXextras甚至书籍“Mastering JavaFX8 Controls”中可以看出,在自定义控件中并没有使用或提到使用FXML。

尽管如此,官方文档仍建议使用FXML创建JavaFX控件。

哪种方式更正确?为什么?

2个回答

19

JavaFX中有两种自定义控件:

  • 基于fx:root的自定义控件:这些自定义控件支持样式(支持CSS),但不支持换肤。

    如果你是应用程序开发者,大部分情况下都会使用这种类型的控件。

    这种控件通常是针对具体的应用程序或组织而设计的。不需要为这些控件提供额外的自定义皮肤,只需要使用CSS即可。

    通常,它们只是将一些控件组合在一起,并提供更好的API以及隐藏内部实现细节。

    相比可换肤的自定义控件,编写此类控件要容易得多。

    我认为这是Swing世界中JPanel子类的一种替代方案。

    我建议将GUI拆分为小而完整的基于fx:root的控件(高内聚,低耦合)。使用中介者模式来结合这些控件(父控件管理/配置其子控件并监听其子控件的事件。子控件互相之间不知道对方)。

    你可以创建整个层次结构的控件。将它们拆分为小控件将使维护更容易(例如,如果需要更改布局或用户交互)。

  • 可换肤的自定义控件:可换肤的自定义控件不仅支持样式(通过CSS),而且可以通过提供自定义皮肤来完全改变其外观和感觉。

    如果你是控件库开发者,那么很可能你想要提供可换肤的自定义控件,以便让库的用户充分利用JavaFX。

    这种控件通常是非常基本、高度可重用的控件,并且通常(但不总是)也使用了一些自定义绘图。

    与基于fx:root的自定义控件相比,编写它们要困难得多。


2
非常好的答案。请注意,使用基于 fx:root 的控件时,您的控件将必须公开一个可修改的子节点列表(例如,它是 Pane 的子类),这是使其不太适合库开发的一个方面。 “可皮肤化的自定义控件”可以是 Control 的子类,因此组成该控件的元素不能由最终用户添加或删除,正如您所指出的,它符合 API 层次结构中的自然位置。 - James_D
2
Oracle在创建SceneBuilder时选择使用(主要)fx:root方法,因此您可以研究SceneBuilder源代码以获取生产质量应用程序代码中使用的具体示例。 - jewelsea

3
没有“正确”的方法。但我们可以将其分解成以下几个部分:
你知道在你的应用程序启动之前需要显示多少JavaFX元素吗?如果是,你可以使用SceneBuilder或直接在编写FXML文件时使用XML构建GUI。对于大多数GUI屏幕设置来说,整体布局(菜单栏、工具栏、内容、侧边栏等)都很明确,并且不会随时间变化而改变。
现在,自定义组件不知道如何显示自己。有许多选项要考虑,大多数自定义组件是动态构建的,或者随用户更改这些选项而发生巨大变化。你不能编写一个单独的FXML文件,而是必须编写许多单独的文件,每个文件构建自定义组件的一小部分。这不太方便管理,因此大多数开发人员选择在代码中直接处理。
另外,还有许多自定义组件使用特殊的布局,这些布局不内置在JavaFX中,为了实现这一点,您必须编写自己的容器,并将它们与自定义组件连接起来,以获得完美的结果。 最终,自定义组件是为了在FXML / SceneBuilder中使用而构建(或者说应该构建)。

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