0

How do we properly track changes to an object's properties in Java (specifically JavaFX)?

My application allows users to modify the properties of the underlying data model objects. When the user clicks on a "Save" button, I want to save the new state of the object to a database. However, if the user clicks on "Cancel," I need to revert back to the object's original state.

Consider the following example objects (getters omitted for clarity):

class Person {

    private final StringProperty name = new SimpleStringProperty();
    private final StringProperty email = new SimpleStringProperty();
    private final SimpleListProperty<PhoneNumber> phoneNumbers = new SimpleListProperty<>();

    public Person(String name, String email, ObservableList<PhoneNumber> phoneNumbers) {
        this.name.set(name);
        this.email.set(email);
        this.phoneNumbers.set(phoneNumbers);
    }
}

class PhoneNumber {

    private final IntegerProperty areaCode = new SimpleIntegerProperty();
    private final IntegerProperty prefix = new SimpleIntegerProperty();
    private final IntegerProperty lineNumber = new SimpleIntegerProperty();

    public PhoneNumber(int areaCode, int prefix, int lineNumber) {
        this.areaCode.set(areaCode);
        this.prefix.set(prefix);
        this.lineNumber.set(lineNumber);
    }
}

Ideally, I want the GUI to load the original Person object, and make a copy of it to bind to the UI controls (even if I need to write this method myself):

Person editedPerson = copyOf(originalPerson);

Then, if the user clicks "Cancel," do nothing. Upon clicking "Save," however, set originalPerson to be equal to editedPerson.

I have looked into cloning objects, but the general consensus seems to recommend against that as it does not ensure the original object is not changed. Also, unless doing a deep copy, any objects references within Person, for example, would not be properly copied.

The other option I've seen is to use a copy constructor but my real-world application uses much more complex objects than the sample above. There are several levels of objects nested within each object and manually copying the entire hierarchy seems like overkill.

So what is the main question? Is there already an API available (or 3rd party library) that handles this functionality? It seems to be a pretty standard expectation for a user to be able to revert their changes.

Zephyr
  • 9,885
  • 4
  • 28
  • 63
  • Unfortunately, solutions are really what you have listed out. Most of the other API is going to do some kind of value/reference copying. One of the most frequently used is from apache commons - [BeanUtils](https://commons.apache.org/proper/commons-beanutils/), but it's generally suited for non-JavaFX beans. – Jai Jul 04 '18 at 05:22
  • I agree there is no "silver bullet" solution, but one option is to reload the object (from DB etc.) upon cancellation - this may be completely unreasonable in some cases, but may be a reasonable solution in others. – Itai Jul 04 '18 at 06:59

0 Answers0