【问题标题】:JavaFX ListView - add items by mouseclick to selectionJavaFX ListView - 通过鼠标单击添加项目到选择
【发布时间】:2016-10-06 12:13:40
【问题描述】:

我想创建一个仅通过鼠标进行多选的 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 listview 已经保存了选定项目的列表,那么您在这里真正需要什么
  • 我只想通过鼠标点击来多选项目。

标签: listview javafx multipleselection


【解决方案1】:

在 JavaFX 中更改控件的行为通常很困难。做到这一点的“正确”方法是创建一个新的皮肤实现,这涉及大量工作,并且由于行为类当前不是公共 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);
    }
}

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

【讨论】:

  • 这正是我想做的!干得好!谢谢您的帮助!我将在我的 GUI 中实现它。
猜你喜欢
  • 2014-01-04
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 2014-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多