看起来有些奇怪,我认为使用FXML编写自定义组件显然是正确的方式。
但是从ControlsFX、JFXextras甚至书籍“Mastering JavaFX8 Controls”中可以看出,在自定义控件中并没有使用或提到使用FXML。
尽管如此,官方文档仍建议使用FXML创建JavaFX控件。
哪种方式更正确?为什么?
JavaFX中有两种自定义控件:
基于fx:root的自定义控件:这些自定义控件支持样式(支持CSS),但不支持换肤。
如果你是应用程序开发者,大部分情况下都会使用这种类型的控件。
这种控件通常是针对具体的应用程序或组织而设计的。不需要为这些控件提供额外的自定义皮肤,只需要使用CSS即可。
通常,它们只是将一些控件组合在一起,并提供更好的API以及隐藏内部实现细节。
相比可换肤的自定义控件,编写此类控件要容易得多。
我认为这是Swing世界中JPanel子类的一种替代方案。
我建议将GUI拆分为小而完整的基于fx:root的控件(高内聚,低耦合)。使用中介者模式来结合这些控件(父控件管理/配置其子控件并监听其子控件的事件。子控件互相之间不知道对方)。
你可以创建整个层次结构的控件。将它们拆分为小控件将使维护更容易(例如,如果需要更改布局或用户交互)。
可换肤的自定义控件:可换肤的自定义控件不仅支持样式(通过CSS),而且可以通过提供自定义皮肤来完全改变其外观和感觉。
如果你是控件库开发者,那么很可能你想要提供可换肤的自定义控件,以便让库的用户充分利用JavaFX。
这种控件通常是非常基本、高度可重用的控件,并且通常(但不总是)也使用了一些自定义绘图。
与基于fx:root的自定义控件相比,编写它们要困难得多。
fx:root
的控件时,您的控件将必须公开一个可修改的子节点列表(例如,它是Pane
的子类),这是使其不太适合库开发的一个方面。 “可皮肤化的自定义控件”可以是Control
的子类,因此组成该控件的元素不能由最终用户添加或删除,正如您所指出的,它符合 API 层次结构中的自然位置。 - James_D