如何使用变更侦听器JavaFX在两个ListView之间移动项目 [英] How to move items between two ListViews with change listener JavaFX

查看:213
本文介绍了如何使用变更侦听器JavaFX在两个ListView之间移动项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个ListViewallStudentsList中已经填充了项目,currentStudentList中没有任何项目.我的目的是当用户在allStudentList中选择一个项目时将其移动到currentStudentList中.通过在allStudentList的选择模型上放置一个侦听器来完成此操作.

I have two ListViews, allStudentsList has items already populated within it, currentStudentList has none. My aim for when the user selects an item in allStudentList is for that item be moved into currentStudentList. I have done this by placing a listener on the selection model of the allStudentList.

我得到一个IndexOutOfBoundsException,我不确定为什么会这样.从测试来看,这个问题似乎仅限于此方法的最后4行,但我不确定为什么.

I get an IndexOutOfBoundsException and I am not sure why this is occurring. From testing, it seems that this problem is isolated to the last 4 lines of this method yet I am not sure why.

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

推荐答案

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

As a quick fix you can wrap the code parts that modify the item lists into a Platform.runLater(...) block:

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(...)块的用法将通过推迟"修改来防止的.

The problem is that you cannot change the selection while a selection change is being processed. As you remove all elements with allStudentsList.getItems().clear();, the selection will change (the selected index will be -1), the mentioned condition will met. This is what the usage of the Platform.runLater(...) block will prevent by "postponing" the modification.

但是您的整个处理程序都可以与之交换

But your whole handler could be exchanged with

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中未选择任何内容,以避免在删除当前项时更改为其他项(这在您的版本中是通过清除列表来隐式完成的),然后添加将当前选择的元素添加到选定列表"中,然后从所有项目列表"中删除当前元素.所有这些动作都包装在提到的Platform.runLater(...)块中.

It sets the selected index to -1: nothing is selected in the ListView to avoid changing to a different item when removing the current one (this was done implicitly in your version by clearing the list), then it adds the currently selected element to the s"elected list", then it removes the current element from the "all item list". All of these actions are wrapped in the mentioned Platform.runLater(...) block.

这篇关于如何使用变更侦听器JavaFX在两个ListView之间移动项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆