本杰明的答案可能是最好的答案:您应该使用底层模型,该模型可以轻松检查相关状态是否已更改。在应用程序开发的某个阶段,您会意识到这是做事的正确方法。看来你已经到了那个地步。
但是,如果您想进一步推迟不可避免地重新设计应用程序(并在您确实达到这一点时使其更加痛苦;)),您可以考虑使用另一种方法。
显然,您有某种东西Pane
正在握住正在绘制的对象。用户必须正在创建这些对象,并且您在某个时候将它们添加到窗格中。只需创建一个处理该添加的方法,并在您这样做时使用感兴趣的属性注册一个失效侦听器。该结构将如下所示:
private final ReadOnlyBooleanWrapper unsavedChanges =
new ReadOnlyBooleanWrapper(this, "unsavedChanged", false);
private final ChangeListener<Object> unsavedChangeListener =
(obs, oldValue, newValue) -> unsavedChanges.set(true);
private Pane drawingPane ;
// ...
Button saveButton = new Button("Save");
saveButton.disableProperty().bind(unsavedChanges.not());
// ...
@SafeVarArgs
private final <T extends Node> void addNodeToDrawingPane(
T node, Function<T, ObservableValue<?>>... properties) {
Stream.of(properties).forEach(
property -> property.apply(node).addListener(unsavedChangeListener));
drawingPane.getChildren().add(node);
}
现在你可以做类似的事情
Rectangle rect = new Rectangle();
addNodeToDrawingPane(rect,
Rectangle::xProperty, Rectangle::yProperty,
Rectangle::widthProperty, Rectangle::heightProperty);
和
Text text = new Text();
addNodeToDrawingPane(text,
Text::xProperty, Text::yProperty, Text::textProperty);
即,您只需指定添加新节点时要观察的属性。您也可以创建一个删除侦听器的删除方法。除了您已经拥有的代码之外,额外代码的数量非常少,因为(可能,我还没有看到您的代码)是重构。
同样,你真的应该有一个单独的视图模型等。我想发布这个以表明@kleopatra 对这个问题的第一条评论(“监听相关状态的无效”)如果你接近,不一定涉及很多工作它以正确的方式。起初,我认为这种方法与@Tomas Mikula 提到的撤消/重做功能不兼容,但您甚至可以使用这种方法作为基础。