Shihab
Shihab

Reputation: 2679

JAVAFX: TableView get multiple selection data

I have a TableView with some columns. It has multiple row selection support. What I want is get all the selected data.

I know how to get single selected data.

enter image description here

See the image. I want those 3 selected cell's data.

Controller

/*********************
     * TABLE ITEMS
     *********************/
    @FXML
    private TableView<DailySalesTableData> table;
    @FXML
    private TableColumn<DailySalesTableData, String> dateColumn;
    @FXML
    private TableColumn<DailySalesTableData, String> nameColumn;
    @FXML
    private TableColumn<DailySalesTableData, String> addressColumn;
    @FXML
    private TableColumn<DailySalesTableData, String> productColumn;
    @FXML
    private TableColumn<DailySalesTableData, Double> quantityColumn;
    @FXML
    private TableColumn<DailySalesTableData, Double> priceColumn;
    @FXML
    private TableColumn<DailySalesTableData, Double> totalColumn;
    @FXML
    private TableColumn<DailySalesTableData, Double> depositColumn;
    @FXML
    private TableColumn<DailySalesTableData, Double> restColumn;
    @FXML
    private TableColumn<DailySalesTableData, String> checkColumn;
    @FXML
    private TableColumn<DailySalesTableData, Integer> transColumn;

private ObservableList<DailySalesTableData> tableData = FXCollections.observableArrayList();

@Override
    public void initialize(URL arg0, ResourceBundle arg1){
        dateColumn.setCellValueFactory(cellData->new ReadOnlyStringWrapper(cellData.getValue().getdate()));
        nameColumn.setCellValueFactory(cellData->new ReadOnlyStringWrapper(cellData.getValue().getName()));
        addressColumn.setCellValueFactory(cellData->new ReadOnlyStringWrapper(cellData.getValue().getAddress()));
        productColumn.setCellValueFactory(cellData->new ReadOnlyStringWrapper(cellData.getValue().getProduct()));
        quantityColumn.setCellValueFactory(cellData->new ReadOnlyObjectWrapper<Double>(cellData.getValue().getQuantity()));
        priceColumn.setCellValueFactory(cellData->new ReadOnlyObjectWrapper<Double>(cellData.getValue().getRate()));
        totalColumn.setCellValueFactory(cellData->new ReadOnlyObjectWrapper<Double>(cellData.getValue().getTotalPrice()));
        depositColumn.setCellValueFactory(cellData->new ReadOnlyObjectWrapper<Double>(cellData.getValue().getDeposit()));
        restColumn.setCellValueFactory(cellData->new ReadOnlyObjectWrapper<Double>(cellData.getValue().getRest()));
        transColumn.setCellValueFactory(cellData->new ReadOnlyObjectWrapper<Integer>(cellData.getValue().getTrans()));
        checkColumn.setCellValueFactory(cellData->new ReadOnlyStringWrapper(cellData.getValue().getStatus()));
        table.setItems(getPersonData());


        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        table.getSelectionModel().setCellSelectionEnabled(true);

    }

    public ObservableList<DailySalesTableData> getPersonData() {
        return tableData;
    }

How to do that?

Upvotes: 1

Views: 2281

Answers (1)

James_D
James_D

Reputation: 209684

You can get a list of all the positions in the table that are selected by the (fairly badly named) getSelectedCells() method in the selection model. This returns a list of TablePosition objects (so it would really make more sense to have called it getSelectedPositions() or some such, but anyway...); from each of those you can get the table column (either as a TableColumn object with getTableColumn() or as an index, with getColumn()), and the row as an index with getRow().

To get the data is still a little tricky. In your example, you have columns with multiple data types (String, Double, and Integer columns) and of course you can have an arbitrary collection of any cells selected. So you could write code something like this:

for (TablePosition<DailySalesTableData, ?> pos : table.getSelectionModel().getSelectedCells()) {

    int row = pos.getRow();
    DailySalesTableData data = table.getItems().get(row);
    if (pos.getTableColumn() == dateColumn) {
        String date = data.getDate();
        // process date...
    } else if (pos.getTableColumn() == quantityColumn) {
        double quantity = data.getQuantity() ;
        // process quantity...
    }
    // etc etc etc
}

That's a little unwieldy, obviously, but is really the only way to do this in a good typesafe manner.

You can reduce code at the expense of knowing the type of the data as follows:

for (TablePosition<DailySalesTableData, ?> pos : table.getSelectionModel().getSelectedCells()) {

    TableColumn<DailySalesTableData, ?> column = pos.getTableColumn();
    ObservableValue<?> obs = column.getCellObservableValue(pos.getRow());
    Object value = obs.getValue();

    // process value...
}

Upvotes: 2

Related Questions