I've got a ListView and I listen to the selectedItemProperty for when the user changes the selection.
In this listener I add an event to my UndoManager. When I try to undo the selection, the selectedItemProperty fires the ChangeListener and it will add an other event to the UndoManger and creating an infinit loop because it will add a ListViewSelectionChange to the UndoManger when it undoes something.
public class DeviceConfigurationController {
@FXML private ListView<DeviceConfiguration> device_list;
@FXML
private void initialize() {
device_list.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
UndoManager.add(new ListViewSelectionChange<>(oldValue, device_list));
});
}
//redo/undo stuff
@FXML
private void undo() {
UndoManager.undo(); //calls the last Change
}
}
public class ListViewSelectionChange<T> implements Change {
privateT lastValue;
private T redoValue;
ListView<T> listView;
public ListViewSelectionChange(T lastValue, ListView<T> listView) {
this.lastValue = lastValue;
this.listView = listView;
}
//gets called from the undomanager
@Override
public void undo() {
redoValue = listView.getSelectionModel().getSelectedItem();
listView.getSelectionModel().select(lastValue); //fires the selection listener again, thus adding a ListViewSelection to the UndoManager
}
}
Does someone has any idea how to stop the listview from calling the listener?
Sebastian
You could add a simple flag to indicate if the listener should be fired:
public class DeviceConfigurationController {
@FXML private ListView<DeviceConfiguration> device_list;
private boolean pauseListener;
@FXML
private void initialize() {
device_list.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if(!pauseListener)
UndoManager.add(new ListViewSelectionChange<>(oldValue, device_list));
}
});
}
@FXML
private void undo() {
pauseListener = true;
UndoManager.undo();
pauseListener = false;
}
}