如何使用更改侦听器JavaFX在两个ListView之间移动项目

时间:2016-09-27 01:55:42

标签: java listview javafx listener

我有两个ListViewallStudentsList已经填充了其中的项目,currentStudentList没有。我的目标是当用户选择allStudentList中的某个项目时,该项目会移至currentStudentList。我通过在allStudentList

的选择模型上放置一个监听器来完成此操作

我得到IndexOutOfBoundsException,我不确定为什么会这样。从测试来看,似乎这个问题与此方法的最后4行隔离,但我不确定原因。

allStudentsList.getSelectionModel().selectedItemProperty()
        .addListener((observableValue, oldValue, newValue) -> {
            if (allStudentsList.getSelectionModel().getSelectedItem() != null) {

                ArrayList<String> tempCurrent = new ArrayList<>();
                for (String s : currentStudentList.getItems()) {
                    tempCurrent.add(s);
                }

                ArrayList<String> tempAll = new ArrayList<>();
                for (String s : allStudentsList.getItems()) {
                    tempAll.add(s);
                }

                tempAll.remove(newValue);
                tempCurrent.add(newValue);

                // clears current studentlist and adds the new list
                if (currentStudentList.getItems().size() != 0) {
                    currentStudentList.getItems().clear();
                }
                currentStudentList.getItems().addAll(tempCurrent);

                // clears the allStudentList and adds the new list
                if (allStudentsList.getItems().size() != 0) {
                    allStudentsList.getItems().clear();
                }
                allStudentsList.getItems().addAll(tempAll);
            }
        });

1 个答案:

答案 0 :(得分:3)

作为快速修复,您可以将修改项目列表的代码部分包装到Platform.runLater(...)块中:

Platform.runLater(() -> {
    // clears current studentlist and adds the new list
    if (currentStudentList.getItems().size() != 0) 
        currentStudentList.getItems().clear();

    currentStudentList.getItems().addAll(tempCurrent);
});

Platform.runLater(() -> {
    // clears the allStudentList and adds the new list
    if (allStudentsList.getItems().size() != 0) 
        allStudentsList.getItems().clear();

    allStudentsList.getItems().addAll(tempAll);
});

问题是您在处理选择更改时无法更改选择。当您使用allStudentsList.getItems().clear();删除所有元素时,选择将更改(所选索引将为-1),将满足上述条件。这就是Platform.runLater(...)块的使用将阻止&#34;推迟&#34;修改。

但是您的整个处理程序可以与

交换
allStudentsList.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
    if (newValue != null) {

        Platform.runLater(() -> {
            allStudentsList.getSelectionModel().select(-1);
            currentStudentList.getItems().add(newValue);
            allStudentsList.getItems().remove(newValue);
        });
    }
});

它将所选索引设置为-1:在ListView中未选择任何内容以避免在删除当前项目时更改为其他项目(这是通过清除列表在您的版本中隐式完成的) ,然后它将当前选中的元素添加到s&#34;选择列表&#34;,然后从&#34;所有项目列表&#34;中删除当前元素。所有这些操作都包含在提到的Platform.runLater(...)块中。