I have a read-only TableView in JavaFX 8, and I don't want' the users to select rows.
They should still be able to sort the columns and scroll, just not to select any rows.
How can I achieve this?
- 375
 - 1
 - 3
 - 10
 
- 
                    technically, you could null the selectionModel - might disable navigation, though (can't try right now). Also, copy would not be possible. Curious: why do you want to detoriate user experience? – kleopatra Dec 08 '14 at 11:28
 - 
                    1@kleopatra Setting the SelectionModel to null will throw exceptions when the user sorts the columns. – BioRoy Dec 09 '14 at 12:54
 - 
                    1good to know, thanks for the info :-) Sounds like a bug to me (null selectionModel is a valid value), so filed an issue: https://javafx-jira.kenai.com/browse/RT-39624 – kleopatra Dec 09 '14 at 14:14
 
4 Answers
You can disable selection, by setting selectionModel to null. 
table.setSelectionModel(null);
- 4,979
 - 1
 - 24
 - 38
 
- 522
 - 5
 - 15
 
- 
                    7
 - 
                    2It throws for me with ListView with JavaFX 8, any ways to disable selection? – Ivan Yurov Feb 17 '17 at 03:56
 - 
                    14TableView.java, method: sort(), row 1531, calls getSelectionModel().startAtomic(); this answer does lead to a nullpointerexception – billdoor Mar 21 '17 at 08:10
 - 
                    
 
After a while I found how to solve it so posting it here for future users.
The solution is based on this answer:
JavaFX8 - Remove highlighting of selected row
After adding the following lines to your css, selected lines will look exactly as unselected lines, achieving the same effect I wanted in the same place:
.table-row-cell:filled:selected { 
  -fx-background: -fx-control-inner-background ;
  -fx-background-color: -fx-table-cell-border-color, -fx-background ;
  -fx-background-insets: 0, 0 0 1 0 ;
  -fx-table-cell-border-color: derive(-fx-color, 5%);
}
.table-row-cell:odd:filled:selected {
  -fx-background: -fx-control-inner-background-alt ;
}
- 375
 - 1
 - 3
 - 10
 
I've just hit this issue myself. I think the best way to solve it is to provide a null implementation of TableViewSelectionModel.
Then you can simply say tableView.setSelectionModel(new NullTableViewSelectionModel(tableView));
A sample null implementation is below...
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
public class NullTableViewSelectionModel extends TableView.TableViewSelectionModel {
    public NullTableViewSelectionModel(TableView tableView) {
        super(tableView);
    }
    @Override
    public ObservableList<TablePosition> getSelectedCells() {
        return FXCollections.emptyObservableList();
    }
    @Override
    public void selectLeftCell() {
    }
    @Override
    public void selectRightCell() {
    }
    @Override
    public void selectAboveCell() {
    }
    @Override
    public void selectBelowCell() {
    }
    @Override
    public void clearSelection(int i, TableColumn tableColumn) {
    }
    @Override
    public void clearAndSelect(int i, TableColumn tableColumn) {
    }
    @Override
    public void select(int i, TableColumn tableColumn) {
    }
    @Override
    public boolean isSelected(int i, TableColumn tableColumn) {
        return false;
    }
    @Override
    public ObservableList<Integer> getSelectedIndices() {
        return FXCollections.emptyObservableList();
    }
    @Override
    public ObservableList getSelectedItems() {
        return FXCollections.emptyObservableList();
    }
    @Override
    public void selectIndices(int i, int... ints) {
    }
    @Override
    public void selectAll() {
    }
    @Override
    public void clearAndSelect(int i) {
    }
    @Override
    public void select(int i) {
    }
    @Override
    public void select(Object o) {
    }
    @Override
    public void clearSelection(int i) {
    }
    @Override
    public void clearSelection() {
    }
    @Override
    public boolean isSelected(int i) {
        return false;
    }
    @Override
    public boolean isEmpty() {
        return false;
    }
    @Override
    public void selectPrevious() {
    }
    @Override
    public void selectNext() {
    }
    @Override
    public void selectFirst() {
    }
    @Override
    public void selectLast() {
    }
}
- 3,146
 - 13
 - 24
 
- 
                    
 - 
                    I like this approach, however I am still seeing a (focus?) rectangle when I click in the `TableView`. – davidrmcharles Dec 12 '18 at 18:40
 
I found here another solution for the same problem but for a ListView. The pattern is: listen the selection change event, and then clear the selection. It works also for the TableView. Code example:
    _tableView.getSelectionModel()
               .selectedIndexProperty()
               .addListener((observable, oldvalue, newValue) -> {
        Platform.runLater(() -> {
            _tableView.getSelectionModel().clearSelection();
        });
    });
- 221
 - 3
 - 4