2017-05-27 87 views
0

我有一个ListView,并且在用户更改选择时侦听selectedItemProperty。JavaFX撤销列表视图选择

在这个监听器中,我将一个事件添加到我的UndoManager中。当我尝试撤销选择时,selectedItemProperty触发ChangeListener,并将其他事件添加到UndoManger并创建一个infinit循环,因为它会在撤销某些内容时将一个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 
    } 
} 

有人有任何想法如何停止从调用监听器的列表视图?

塞巴斯蒂安

回答

1

你可以添加一个简单的标志,表示如果监听器应该被解雇:

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

我没有想到这一点。 我添加了一个函数接口,它在un/redo之前和之后被调用。在那里,我可以修改一个像pauseListener一样的布尔值。 谢谢 – Frame