2017-06-20 75 views
0

我有以下问题:“你想选择新值”selectedItemPropertyChanged取消事件

listView.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> { 
      if (!selectionChanged(newV)) { 
       lististView.getSelectionModel().select(oldV); 
      } 

    }); 

的SelectionChanged(newV)只是弹出一个消息框,并将结果作为布尔值返回。当我点击取消它返回false,以便条件成立。但是因为.select(oldV);这将导致循环。我如何取消或回滚javafx listview中的选择?

回答

2

创建一个布尔标志,不要问用户是否没有设置。您需要在Platform.runLater(...)中将更改恢复为原始值(如果用户否决更改),以避免选择模型的selectedItems列表中出现冲突问题(基本上,在处理另一个列表更改时不能更改列表)。

private boolean checkSelectionChange = true ; 

// ... 

listView.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> { 

    if (checkSelectionChange) { 
     checkSelectionChange = false ; 
     Platform.runLater(() -> { 
      if (!selectionChanged(newV)) { 
       lististView.getSelectionModel().select(oldV); 
      } 
      checkSelectionChange = true ; 
     }); 
    } 
}); 

SSCCE:

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.control.Alert; 
import javafx.scene.control.Alert.AlertType; 
import javafx.scene.control.ButtonType; 
import javafx.scene.control.ListView; 
import javafx.stage.Stage; 

public class ListViewSelectionUserVeto extends Application { 

    private boolean checkSelectionChange = true ; 

    @Override 
    public void start(Stage primaryStage) { 
     ListView<String> listView = new ListView<>(); 
     listView.getItems().addAll("One", "Two", "Three", "Four"); 
     listView.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> { 
      if (checkSelectionChange) { 
       checkSelectionChange = false ; 
       Platform.runLater(() -> { 
        if (! verifySelectionChange(newValue)) { 
         listView.getSelectionModel().select(oldValue); 
        } 
        checkSelectionChange = true ; 
       }); 
      } 
     }); 

     Scene scene = new Scene(listView); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private boolean verifySelectionChange(String newValue) { 
     Alert alert = new Alert(AlertType.CONFIRMATION); 
     alert.setContentText("Change selection to "+newValue); 
     return alert.showAndWait().filter(ButtonType.OK::equals).isPresent(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

消息框是显示两次。 – Sduniii

+0

@Sduniii您是否使用更新的答案(使用'Platform.runLater(...)')?这是发生在SSCCE吗? –

+0

好吧,我的错。我添加了一个a.showAndWait()。isPresent()&& a.showAndWait()。get()!= ButtonType.OK两次调用该方框。谢谢 – Sduniii