listview - JavaFX ListView - 通过鼠标单击将项目添加到选择中

标签 listview javafx multipleselection

我想创建一个仅通过鼠标进行多选的ListView(无需按住ctrl或shift)

单击某个项目应选择该项目。如果选择了其他项目,则将此新项目添加到所选列表中。当之前选择过该项目时,将其取消选择。

我不知道保留所选项目。 SelectionModel 上有一个名为“selectIndices()”的方法,它只接受一个或多个整数,而不是整数列表...

 DataTypesLV.getSelectionModel().selectedItemProperty().addListener(new ChangeListener <String>() {
        @Override
        public void changed(ObservableValue<? extends String> arg0, String oldVal, String newVal) {
            int idx = DataTypesLV.getItems().indexOf(newVal);
            if(newVal.equals(oldVal)){
                DataTypesLV.getSelectionModel().getSelectedIndices().remove(idx);
              } else {
                  DataTypesLV.getSelectionModel().getSelectedIndices().add(idx);
              }
        }
    });

有没有人有想法?

最佳答案

更改 JavaFX 中控件的行为通常很困难。执行此操作的“正确”方法是创建一个新的皮肤实现,这涉及大量工作,并且由于行为类当前不是公共(public) API,因此将涉及大量“重新发明轮子”。合理的技巧是在默认外观类接收鼠标事件之前拦截鼠标事件,并相应地修改选择。您可以使用事件过滤器来执行此操作,使用事件来防止皮肤接收它:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class ListViewModifiedSelection extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView<String> listView = new ListView<>();
        listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        for (int i = 1 ; i <= 25 ; i++) {
            listView.getItems().add("Item "+i);
        }

        listView.setCellFactory(lv -> {
            ListCell<String> cell = new ListCell<String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    setText(empty ? null : item);
                }
            };

            cell.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
                if (cell.isEmpty()) {
                    return ;
                }

                int index = cell.getIndex() ;
                if (listView.getSelectionModel().getSelectedIndices().contains(index)) {
                    listView.getSelectionModel().clearSelection(index);
                } else {
                    listView.getSelectionModel().select(index);
                }

                listView.requestFocus();

                e.consume();
            });

            return cell ;
        });

        primaryStage.setScene(new Scene(listView, 250, 450));
        primaryStage.show();
    }

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

阻止皮肤接收鼠标事件是一种黑客行为,这样做确实有破坏现有功能的风险。另一种更强大的解决方案可能是使用列表单元格中的复选框或类似的东西来管理您自己的“选择”功能。

关于listview - JavaFX ListView - 通过鼠标单击将项目添加到选择中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37665022/

相关文章:

c++ - QTableView高级选择

Android recyclerview-selection 实现?

android - 如何在列表中添加新项目时更新 RecyclerView 适配器数据

firebase - 如何在flutter中唯一标识widgets?

css - 如何将 CSS 样式表附加到 FXML?

gwt - GXT 网格复选框标题全选/取消全选

java - 如何使用条目从 ListView 中获取特定键的值

listview - 按项目和分隔线过滤 ListView

java - 在对象数组上设置监听器

Javascript 桥接/调用 JavaFX(通过 JSObject.setMember() 方法)在分发时中断