如何使用JavaFX TableView显示基于列的数据集

时间:2014-12-16 03:02:31

标签: javafx tableview

我正在尝试从Swing切换到JavaFX并遇到TableView问题。

我在内存中有一个基于通用列的数据结构,如List<DataColumn> dataColumns = new ArrayList<DataColumn>();

其中DataColumn是一个表列,它是一个基元数组的包装器。对于JTable,我实现了一个自定义TableModel来处理这个数据结构。

我在TableView中看到的所有内容都基于行列表而不是列。

如何使用TableView可视化此类数据而不将其复制到基于行的数据结构中?谢谢。

1 个答案:

答案 0 :(得分:2)

这是一个使用基于列的数据的非常简单的示例;也许这会给你足够的进展。此示例中的基本思想是使表类型为Integer,因此每个列的值由工厂计算,该工厂只将索引映射到DataColumn结构,并检索相应的值。索引。

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);
    }
}