1

I am trying to switch from Swing to JavaFX and have a problem with TableView.

I have a general column based data structure in memory like List<DataColumn> dataColumns = new ArrayList<DataColumn>();

where DataColumn is a table column that is a wrapper around array of primitives. For JTable I have implemented a custom TableModel to handle this data structure.

Everything I saw in TableView is based on list of rows not columns.

How to visualize such data using TableView without copying it into a row based data structure? Thank you.

Dyrandz Famador
  • 4,499
  • 5
  • 25
  • 40
abond3800
  • 11
  • 2

1 Answers1

2

Here's a very simple example that uses data based in columns; maybe this will give you enough to proceed. The basic idea in this example is to make the table type Integer, so the value for each column is calculated by a factory that just maps the index into the DataColumn structure, and retrieves the corresponding value for the index.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ColumnBasedTable extends Application {

    @Override
    public void start(Stage primaryStage) {
        final int numRows = 20 ;
        final int numCols = 12 ;

        List<DataColumn<Integer>> data = new ArrayList<>();

        for (int colIndex = 1; colIndex <= numCols; colIndex++) {
            Integer[] colData = new Integer[numRows];
            for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {
                colData[rowIndex] = (rowIndex+1)*colIndex ;
            }
            DataColumn<Integer> dataColumn = new DataColumn<>(colData);
            data.add(dataColumn);
        }

        TableView<Integer> table = new TableView<>();
        for (int i=0; i<numRows; i++) {
            table.getItems().add(i);
        }

        for (int i=0; i<numCols; i++) {
            TableColumn<Integer, Number> col = new TableColumn<>(Integer.toString(i+1));
            final int colIndex = i ;
            col.setCellValueFactory(cellData -> {
                int rowIndex = cellData.getValue();
                DataColumn<Integer> dataColumn = data.get(colIndex);
                return new ReadOnlyIntegerWrapper(dataColumn.getData(rowIndex));
            });
            table.getColumns().add(col);
        }

        primaryStage.setScene(new Scene(new BorderPane(table), 600, 400));
        primaryStage.show();
    }

    public static class DataColumn<T> {
        private final T[] data ;
        public DataColumn(T[] data) {
            this.data = Arrays.copyOf(data, data.length);
        }
        public T getData(int index) {
            return data[index];
        }
        public int getSize() {
            return data.length ;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322