首页 > 解决方案 > 有没有办法简单地监听对象的更改,而不是进行了哪些更改?

问题描述

概括

我有一个名为“myClassInstance”的“MyClass”类型的对象,它有一个对象的ArrayList。所有包含的对象都实现了 Serializable 接口并将被写入文件。

我需要能够知道该对象何时以任何方式发生更改,以便在对象发生任何更改时更新 JavaFX ListView(包括它包含的任何对象)。

基本上任何时候“myClassInstance.hashCode”会返回一个不同的数字,我希望能够调用一个更新方法来更新 ui 元素。

背景

我一直在寻找这个问题的解决方案,并发现许多页面似乎都有解决方案,但是我不禁认为这些解决方案似乎都需要对我拥有的模型类进行重大重写,对于我的问题来说完全太复杂了有。

几乎所有似乎都提到了属性更改侦听器,以了解对特定属性/字段的更改,但我不需要任何特定的东西。我只需要知道对象“myClassInstance”是否已更改。“myClassInstance.hashCode”返回的值是否已更改。如果任何属性已更改,或者它包含的对象的属性已更改,但如果“myClassInstance”中的任何内容已更改,则不会。

相关代码片段

需要观察的类:

public class myClass implements Serializable {
private ArrayList<SpecificObjectType> myObjects = new ArrayList<>();

public myClass () {
newSpecificObjectType(); //creates default specific object type
}

// Classes related to changing, retrieving or deleting elements of myObjects
}

FXMLMainDocument.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" "package.FXMLMainController">
   <center>
      <ListView fx:id="listViewObjects" BorderPane.alignment="CENTER" />
   </center>
   <top>
      <Button fx:id="editButton" onAction="#handleEditAction" mnemonicParsing="false" text="Edit" BorderPane.alignment="CENTER" />
   </top>
</BorderPane>

FXMLEditDocument.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>


<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="package.FXMLEditController">
   <center>
      <TextField fx:id="edit" onAction="#handleNameTextField"  promptText="This Edits The Name of One of the Objects in MyClass's ArrayList" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>

FXMLMainController:

@FXML
private ListView listViewObjects;

private MyClass myClassInstance;
private ObservableList<String> obsObjects;

...

public void update() {
        this.obsObjects.setAll(myClassInstance.getMyObjectNames());
    }

@Override
    public void initialize(URL url, ResourceBundle rb) {
        this.myClassInstance = new MyClass();
        obsObjects = FXCollections.observableArrayList(myClassInstance.getMyObjectNames());
        this.listViewObjects.setItems(obsObjects);
        update();
    }

编辑:

我决定尝试 Observable、Observer 路线。辅助控制器现在是可观察的,主控制器是观察者。当在辅助节点中触发某些操作时,主节点会更新。这行得通,虽然我不完全确定它可以做我想做的一切。我可能会坐下来,然后我会标记相关的答案。

标签: javajavafxobservablefxmlchangelistener

解决方案


您的班级似乎没有任何public字段,对吗?难道你不能简单地添加一个BooleanProperty类并从类中的任何设置器更新它吗?

例如:

private BooleanProperty hasChanged = new SimpleBooleanProperty();

然后在您的任何设置器中,更新该属性:

public void setData(String data) {
    this.data = data;
    this.hasChanged.set(true);
}

推荐阅读