繁体   English   中英

(JavaFx)正确的方式表示静态FXML字段(以及为什么这是一个坏主意)

[英](JavaFx) Proper way represent static FXML fields (and why this is a bad idea)

我希望所有类都可以访问FXML字段。 在一个完美的世界中,我会这样做:

public class CanvasController {

    @FXML
    private static final AnchorPane canvas; // This is wrong

    public static AnchorPane getCanvas() {
        return canvas;
    }
}

但是,正如这个类似的问题所解释的,静态字段是一个“糟糕的主意”。

我正在设计一个节点编辑器,如下所示:

在此处输入图片说明

我想从项目的任何位置添加一个node ,作为此AnchorPane的子级。

我想这样做是错的吗? 为什么静态字段不是一个好主意,我应该怎么做呢?

(类似的问题建议使用属性,但是JavaFx没有NodePropertyAnchorPaneProperty )。

对于这个论坛,这个问题可能太基于观点了,但是我认为我在这里表达的观点被广泛接受,足以被接受。

为什么静态字段是个坏主意

假设您在这里做了您想做的事情,并且允许它工作。 想象一下,您的老板在六个月内来到您的办公室,并说“客户喜欢该应用程序,但他们希望能够同时打开多个节点编辑器。您能否制作该应用程序以便他们可以打开新窗口,每个都有一个节点编辑器?”

这种事情在现实生活中发生的时间

因此,从理论上讲,这应该很容易。 您拥有定义布局的FXML和定义了与之关联的逻辑的控制器。 因此,您所需要做的就是拥有一个事件处理程序(在菜单上说),该事件处理程序创建一个新的Stage和一个Scene ,再次加载FXML,并将场景的根设置为FXML的根。

除非它不起作用。 问题是,您将根窗格设置为static 因此,当您再次加载FMXL时,它将用新加载的FXML中的新canvas替换canvas的当前值。 如果现在尝试向第一个画布添加新元素,则不能。

因此,现在您必须重构代码,以便canvas是一个实例变量。 更糟糕的是,您通过static getCanvas()方法公开公开了该方法,该方法可能已在应用程序中的任何位置调用。 因此,您必须跟踪所有这些调用。 您最终在凌晨3点尝试尝试重新编码整个代码库,以找出必须更改的内容。

使事物静态化的问题(一个问题)是,您只承诺拥有该变量的一个副本,并且从根本上讲,您一直都致力于该副本(或者如果您改变主意,则承诺重写许多应用程序)。 该决定向上泄漏:仅拥有一个画布,就只能拥有一个控制器,因此只能拥有一个节点编辑器。 实质上,您已阻止所编写的代码可重复使用。


您的基本假设是错误的。 static关键字确实与可访问性无关:它与范围有关。 static字段的作用域为该类:非静态字段的作用域为该类的每个实例。 通过定义公共getCanvas()方法并使该方法的范围(类)可用(通过将该类公开),使该字段可访问。 如果canvas是一个实例变量,则可以通过类似地定义一个公共getCanvas()方法并使该方法的范围(现在为CanvasController 实例 )可用来CanvasController可访问。 因此,您加载FXML,通过在FXMLLoader上调用getController()来检索控制器,并将控制器实例传递给需要访问它的任何人。 现在注意,您可以在代码中控制谁收到了对控制器的引用,并且如果需要进行任何重构,则至少应遵循一条路径来查找控制器的使用位置。

您提到“ JavaFX没有NodePropertyAnchorPaneProperty :它具有ObjectProperty ,因此如果需要,可以使用ObjectProperty<Node>ObjectProperty<AnchorPane>


不过,总的来说,我认为将视图元素(如canvas )暴露在控制器之外,甚至与应用程序的其他部分共享控制器也是一个坏主意。 您应该考虑使用MVC类型的方法。 您的问题中缺少的是“ M”: 模型 因此,您的模型将使用带有ImageScaleComposite等类的对象模型。这些类应使用JavaFX属性使它们可观察,并使用ObservableList (及类似方法)存储这些对象及其之间的关系的集合。 创建一个模型实例并将其传递给您的控制器。 控制器可以观察模型中的数据并在视图更改时更新视图,并根据用户输入更新模型。 然后与需要访问它的应用程序的其他部分共享模型实例。 这样可以使事情更容易维护:例如,如果您确定canvas需要是Pane而不是AnchorPane ,那么更改现在仅限于FXML和控制器,并且不会泄漏到应用程序的其余部分。 这个问题是JavaFX中的MVC(实际上更是MVP)的一个(简单得多)示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM