Clear Selection in table view on clicking on empty rows in javafx
Asked Answered
W

2

6

I have a TableView with some rows. The user can select any row but when he clicks on empty rows or anywhere on the Stage, I want to clear his current selection of the TableView.

Wiener answered 28/1, 2017 at 8:15 Comment(0)
D
3

You can store the last selected row, and check with a mouse listener on the scene if the click was on the selected row or somewhere else:

    ObjectProperty<TableRow<MyRowClass>> lastSelectedRow = new SimpleObjectProperty<>();

    myTableView.setRowFactory(tableView -> {
        TableRow<MyRowClass> row = new TableRow<MyRowClass>();

        row.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                lastSelectedRow.set(row);
            } 
        });
        return row;
    });


    stage.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {
            if (lastSelectedRow.get() != null) {
                Bounds boundsOfSelectedRow = lastSelectedRow.get().localToScene(lastSelectedRow.get().getLayoutBounds());
                if (boundsOfSelectedRow.contains(event.getSceneX(), event.getSceneY()) == false) {
                    myTableView.getSelectionModel().clearSelection();
                }
            }
        }
    });
Daiseydaisi answered 28/1, 2017 at 10:22 Comment(3)
Thanks a lot for your answer but I am getting null pointer exception at line stage.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {Wiener
If you have access to the scene object, just replace stage.getScene() in the code above with scene. Otherwise have a look at this question: #30464738Daiseydaisi
yes i had access to stage as well. It is now working fine. Thanks a lotWiener
T
5

You can add a event filter to the Scene that uses the selection model of the TableView to clear the selection, if the click was on a empty row or anywhere outside of a TableView:

scene.addEventFilter(MouseEvent.MOUSE_CLICKED, evt -> {
    Node source = evt.getPickResult().getIntersectedNode();

    // move up through the node hierarchy until a TableRow or scene root is found 
    while (source != null && !(source instanceof TableRow)) {
        source = source.getParent();
    }


    // clear selection on click anywhere but on a filled row
    if (source == null || (source instanceof TableRow && ((TableRow) source).isEmpty())) {
        tableView.getSelectionModel().clearSelection();
    }
});
Timetable answered 28/1, 2017 at 10:13 Comment(0)
D
3

You can store the last selected row, and check with a mouse listener on the scene if the click was on the selected row or somewhere else:

    ObjectProperty<TableRow<MyRowClass>> lastSelectedRow = new SimpleObjectProperty<>();

    myTableView.setRowFactory(tableView -> {
        TableRow<MyRowClass> row = new TableRow<MyRowClass>();

        row.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                lastSelectedRow.set(row);
            } 
        });
        return row;
    });


    stage.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {
            if (lastSelectedRow.get() != null) {
                Bounds boundsOfSelectedRow = lastSelectedRow.get().localToScene(lastSelectedRow.get().getLayoutBounds());
                if (boundsOfSelectedRow.contains(event.getSceneX(), event.getSceneY()) == false) {
                    myTableView.getSelectionModel().clearSelection();
                }
            }
        }
    });
Daiseydaisi answered 28/1, 2017 at 10:22 Comment(3)
Thanks a lot for your answer but I am getting null pointer exception at line stage.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {Wiener
If you have access to the scene object, just replace stage.getScene() in the code above with scene. Otherwise have a look at this question: #30464738Daiseydaisi
yes i had access to stage as well. It is now working fine. Thanks a lotWiener

© 2022 - 2024 — McMap. All rights reserved.