JavaFX 撤消列表视图选择

JavaFX undo listview selection

我有一个 ListView,当用户更改选择时我会监听 selectedItemProperty。

在这个侦听器中,我向我的 UndoManager 添加了一个事件。当我尝试撤消选择时,selectedItemProperty 会触发 ChangeListener,它会将另一个事件添加到 UndoManger 并创建一个无限循环,因为它会在撤消某些操作时将 ListViewSelectionChange 添加到 UndoManger。

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
    }
}

有人知道如何阻止列表视图调用监听器吗?

塞巴斯蒂安

您可以添加一个简单的标志来指示是否应触发侦听器:

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;
    }
}