-1

I have some code which I don't understand the result :

ObservableList<Integer> li = FXCollections.observableArrayList();
        li.add(1);
        li.add(2);
        IntegerProperty intProp = new SimpleIntegerProperty(5);

        li.add(intProp.getValue());

        li.add(li.get(0) + li.get(2));
        System.out.println(li);
        li.addListener((ListChangeListener<Integer>) change -> {
            li.set(3, li.get(0) + li.get(2));
        });
        intProp.setValue(3);
        System.out.println(intProp.get());
        System.out.println(li.get(2));
        System.out.println(li);

I don't understand why the changing value of intProp doesn't affect affect the observableList, I mean the int in the position 2 should be the value of the property so the second and third sysout must me the same, and the first must be different from the last, but it isn't the case, and it gives me :

[1, 2, 5, 6]
3
5
[1, 2, 5, 6]

I tried to do some changes by writing this :

        ObservableList<Integer> li = FXCollections.observableArrayList();
        li.add(1);
        li.add(2);

        li.add(5);

        li.add(li.get(0) + li.get(2));
        System.out.println(li);
        li.addListener((ListChangeListener<Integer>) change -> {
            li.set(3, li.get(0) + li.get(2));
        });
        li.set(2, 3);
        System.out.println(li);

it apparently works, but it gives me many errors which I don't understand.

Thanks !

R.J. Dunnill
  • 2,049
  • 3
  • 10
  • 21
Ino
  • 15
  • 4
  • https://stackoverflow.com/questions/26838183/how-to-monitor-changes-on-objects-contained-in-an-observablelist-javafx – SedJ601 May 29 '19 at 03:30

1 Answers1

1

At a fundamental level, you seem to be expecting the following:

IntegerProperty property = new SimpleIntegerProperty(5);
int i = property.get();
property.set(10);
System.out.println(i);

To print out 10 instead of 5. This cannot happen in Java because Java is always pass-by-value. The same is true when adding the value to an ObservableList; all you've done is taken the value of the property at the time and added it to the list. After that, the property and the list are completely separate entities.

There's no fundamental way to observe variables for changes in Java. In order to be notified of changes there has to be code that implements that behavior. An IntegerProperty is basically just a wrapper around an int that intercepts code changing the value and notifying observers of the change. Something like:

public void set(int newValue) {
    this.value = newValue;
    notifyObservers();
}

Note: The actual implementation of IntegerProperty is more complicated than that.

The same is true of ObservableList. All the core implementations are simply wrappers around a regular List and the ObservableList simply intercepts calls and notifies observers of a change. This is why, if you wrap your own List using FXCollections.observableList(List), you can't modify the List directly anymore because that bypasses the wrapping ObservableList and thus no change events will be fired.

If you want the ObservableList to update when the IntegerProperty changes, you'd have to add a listener to the IntegerProperty which updates the ObservableList appropriately. If you want to be aware of changes to contained elements via the ObservableList, you need to use an extractor—see this answer.


it apparently works, but it gives me many errors which I don't understand.

Ignoring the contradiction between "apparently works" and "gives me many errors", you don't actually provide the errors you get. Without the errors it's difficult to know what is going wrong. However, you have the following (which may or may not be related to your errors):

li.addListener((ListChangeListener<Integer>) change -> {
    li.set(3, li.get(0) + li.get(2));
});

This is modifying the the ObservableList that fired the change event. You must not do this:

Warning: This class directly accesses the source list to acquire information about the changes.
This effectively makes the Change object invalid when another change occurs on the list.
For this reason it is not safe to use this class on a different thread.
It also means the source list cannot be modified inside the listener since that would invalidate this Change object for all subsequent listeners.

Slaw
  • 37,820
  • 8
  • 53
  • 80