I have an ObservableList<MyElement> list = FXCollections.observableArrayList();
public class MyElement
{
private IntegerProperty position;//with getter
//[...]
//somewhere in the constructor taking the list as argument
position.bind(list.indexOf(this));
}
Now I'd like to bind MyElement.position to the actual position in the list i.e. if the position changes in the list (for instance drag and drop in the GUI or anything else) I want the position property to be updated automatically.
Is this possible? Can I make a bidirectional binding between these values?
I don't have a bidirectional binding but if you only want the property to be updated when the position changes in the list, you can use this code:
It adds itself as a listener to the list and reacts on all events. You can then use the property (read-only!) as normal. The time complexity of
indexOf
is O(n), though, so if you have a long list, you'll want to somehow optimize this.I don't know if I correctly understood your question, but I will try to answer it :-).
The thing is, once a ObservableList (javafx.collections) object does not store some kind of "selected" index state, why do we should bind another integer to it?
I think, in this case, your code should be responsible for store the "selected" index state and expose it to a client code. If this is what you are looking for, I suggest you have three attributes to deal with it:
The selected element can be controlled using the
selectedIndex
attribute.Then, create a bind to the
selectedItem
, to "automatically" update it whenselectedIndex
change:Bindings
should have been imported statically:Notice the use of method
Bindings.valueAt(ObservableList<E> list, ObservableIntegerValue index)
. It creates a bind to thelist.get(index.getValue())
element.Finally, you can use it like this:
I also suggest you to take a look to
javafx.scene.control.SelectionModel
class and its subclasses (eg.javafx.scene.control.SingleSelectionModel
). Maybe, it could be easier to extend some of them.