我希望所有类都可以访问FXML字段。在一个完美的世界中,我会这样做:
public class CanvasController {
@FXML
private static final AnchorPane canvas; // This is wrong
public static AnchorPane getCanvas() {
return canvas;
}
}
但是,如this similar question所述,静态字段是一个“糟糕的主意”。
我正在设计一个节点编辑器,如下所示:
我想从项目的任何位置添加一个
node
作为此AnchorPane
的子级。我想这样做是错的吗?为什么静态字段不是个好主意,我应该怎么做呢?
(类似的问题建议使用属性,但JavaFx没有
NodeProperty
或AnchorPaneProperty
)。
最佳答案
对于这个论坛,这个问题可能太基于观点了,但是我认为我在这里表达的观点被广泛接受,足以被接受。
为什么静态字段是个坏主意
假设您在这里做了您想做的事情,并且允许它工作。假设您的老板在六个月内来到您的办公室,并说“客户喜欢该应用程序,但他们希望能够同时打开多个节点编辑器。您能否制作该应用程序以便他们可以打开新窗口,每个都有一个节点编辑器?”
这种事情一直在现实生活中发生。
因此,从理论上讲,这应该很容易。您拥有定义布局的FXML和定义了与之关联的逻辑的控制器。因此,您所需要做的就是拥有一个事件处理程序(在菜单上说),该事件处理程序将创建新的Stage
和Scene
,再次加载FXML,并将场景的根设置为FXML的根。
除非它不起作用。问题是,您将根窗格设置为static
。因此,当您再次加载FMXL时,它将用新加载的FXML中的新值替换canvas
的当前值。如果现在尝试将新元素添加到第一个画布,则不能。
因此,现在您必须重构代码,以便canvas
是一个实例变量。更糟糕的是,您通过static getCanvas()
方法公开公开了该方法,该方法可能已在应用程序中的任何位置调用。因此,您必须跟踪所有这些调用。您最终在凌晨3点尝试尝试重复整个代码库,以找出必须更改的内容。
使事物静态化的问题(一个问题)是,您只承诺拥有该变量的一个副本,并且从根本上讲,您一直都致力于该副本(或者如果您改变主意,则承诺重写许多应用程序)。该决定向上泄漏:仅拥有一个画布,就只能拥有一个控制器,因此只能拥有一个节点编辑器。实质上,您已阻止所编写的代码可重复使用。
您的基本假设是错误的。 static
关键字确实与可访问性无关:它与范围有关。 static
字段的作用域为该类:非静态字段的作用域为该类的每个实例。您通过定义公共的getCanvas()
方法并使该方法的范围(类)可用(通过将该类公开)来使字段可访问。如果canvas
是实例变量,则可以通过类似地定义一个公共getCanvas()
方法并使该方法的范围(现在是CanvasController
实例)可用来使其可访问。因此,您加载FXML,通过在getController()
上调用FXMLLoader
检索控制器,然后将控制器实例传递给需要访问它的任何人。注意,现在您可以在代码中控制谁收到了对控制器的引用,并且如果需要进行任何重构,则至少要遵循一条路径来查找控制器的使用位置。
您提到“ JavaFX没有NodeProperty
或AnchorPaneProperty
:它具有ObjectProperty
,因此如果需要,可以使用ObjectProperty<Node>
或ObjectProperty<AnchorPane>
。
不过,总的来说,我认为将视图元素(如您的canvas
)暴露在控制器之外,甚至与应用程序的其他部分共享控制器也是一个坏主意。相反,您应该考虑使用MVC类型的方法。您的问题中缺少的是“ M”:模型。因此,您的模型将使用带有Image
,Scale
,Composite
等类的对象模型。这些类应使用JavaFX properties使它们可观察,并使用ObservableList
(及类似方法)存储这些对象的集合对象和它们之间的关系。创建一个模型实例并将其传递给您的控制器。控制器可以观察模型中的数据,并在视图更改时更新视图,并根据用户输入更新模型。然后与需要访问它的应用程序的其他部分共享模型实例。这样可以使事情更易于维护:例如,如果您确定canvas
需要是Pane
而不是AnchorPane
,则该更改现在仅限于FXML和控制器,并且不会泄漏到其余部分您的应用程序。 this question中有一个(更简单的)JavaFX中的MVC(实际上是更多的MVP)示例。
关于java - (JavaFx)正确的方式表示静态FXML字段(以及为什么这是一个坏主意),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41720572/