簡體   English   中英

單擊時取消選擇javafx ListView上的項目

[英]Deselect an item on an javafx ListView on click

我在JavaFX應用程序中使用ListView控件。 它被設置為MULTIPLE選擇模式。 我知道作為用戶,我可以按住Ctrl鍵單擊一個項目以取消選擇它,但這對我的用戶來說不夠直觀。 我想要一種方法來第二次點擊取消選擇它。 換句話說,點擊一次 - 選擇; 單擊所選項目,它將被取消選中。

我嘗試過使用ChangeListener和onMouseClicked事件。 兩者都不是很好。 以下是每個代碼片段。

的ChangeListener:

效果 - 列表中的第一項永遠不會被選中。 我點擊它並保持不被點擊。 對項目2..n沒有影響

listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<SpecificAlgorithmData>() {
    @Override
    public void changed(final ObservableValue observableValue, final SpecificAlgorithmData oldData, final SpecificAlgorithmData newData) {

        //if already selected then deselect it
        int selectedIndex = listView.getSelectionModel().getSelectedIndex();
        System.out.println("selected " + selectedIndex);
        System.out.println("all selected" + listView.getSelectionModel().getSelectedIndices());
        if (!selecting && !listView.getSelectionModel().getSelectedIndices().contains(selectedIndex)){


            Iterator <Integer> iterator = listView.getSelectionModel().getSelectedIndices().iterator();
            selecting = true;
            listView.getSelectionModel().select(-1);//deselect all

            while (iterator.hasNext()){
                int index = iterator.next();
                if (index!= selectedIndex){
                    listView.getSelectionModel().select(index);
                }
            }
            selecting = false;
        }
    }
}

的onClick:

沒有效果,因為我不知道如何獲得我剛剛點擊的索引。 由於硬編碼,這完全不允許選擇第2項。

listView.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(final MouseEvent mouseEvent) {
        int selectedItem = 2; //FIXME: How to I get the index of clicked item?
        if (listView.getSelectionModel().isSelected(selectedItem)){
            listView.getSelectionModel().clearSelection(selectedItem);
        }
    }
});

在JavaFX中更改控件的行為非常困難 - 在API中當前實際上沒有鈎子進入行為類。

通過向列表中的單元格注冊事件過濾器,直接實現選擇行為以及使用事件,以下似乎可行。

雖然感覺有點脆弱(例如,如果未來版本決定在鼠標點擊時實現默認行為,而不是鼠標按下,或者更好,如果未來版本決定添加鼠標事件處理的其他功能,該怎么辦)。 所以請使用此解決方案,並附上一些“買家提防”通知。

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

public class DeselectableList extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView<String> list = new ListView<>();
        MultipleSelectionModel<String> selectionModel = list.getSelectionModel();
        selectionModel.setSelectionMode(SelectionMode.MULTIPLE);
        for (int i=1; i<=20; i++) {
            list.getItems().addAll("Item "+i);
        }
        list.setCellFactory(lv -> {
            ListCell<String> cell = new ListCell<>();
            cell.textProperty().bind(cell.itemProperty());
            cell.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
                list.requestFocus();
                if (! cell.isEmpty()) {
                    int index = cell.getIndex();
                    if (selectionModel.getSelectedIndices().contains(index)) {
                        selectionModel.clearSelection(index);
                    } else {
                        selectionModel.select(index);
                    }
                    event.consume();
                }
            });
            return cell ;
        });
        BorderPane root = new BorderPane(list);
        Scene scene = new Scene(root, 150, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

顯然你比我更了解你的用戶,但我可能更喜歡在ListView上有一個很好的工具提示,向他們解釋如何使用它...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM