我想在JavaFX中创建一个简单的TableView
,其中我的数据是像double[][]
矩阵这样的二维数组,但我不知道如何实现这一点,一些建议?
答案 0 :(得分:3)
正如法比安在评论中所说:
将表格定义为:
TableView<double[]>
将double[][]
数组的元素作为项添加到表中(从double[][]
中提取元素并将其添加到ObservableList<double[]>
)。
为您的表创建列,为每个列提供单元格值工厂。
col.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue()[c]))
其中c
是列索引。
如果您需要格式化单元格项目,还需提供cell factory。
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class MatrixTable extends Application {
private Random random = new Random(42);
private static final int N_COLS = 4;
private static final int N_ROWS = 100;
private static final int MAX_DATA_VALUE = 100;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
ObservableList<double[]> data = generateData();
TableView<double[]> table = new TableView<>(data);
table.getColumns().setAll(createColumns());
table.setPrefSize(200, 250);
stage.setScene(new Scene(table));
stage.show();
}
private ObservableList<double[]> generateData() {
return FXCollections.observableArrayList(
IntStream.range(0, N_ROWS)
.mapToObj(r ->
IntStream.range(0, N_COLS)
.mapToDouble(c -> randomValue())
.toArray()
).collect(Collectors.toList())
);
}
private List<TableColumn<double[], Double>> createColumns() {
return IntStream.range(0, N_COLS)
.mapToObj(this::createColumn)
.collect(Collectors.toList());
}
private TableColumn<double[], Double> createColumn(int c) {
TableColumn<double[], Double> col = new TableColumn<>("C" + (c + 1));
col.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue()[c]));
return col;
}
private long randomValue() {
return Math.round(random.nextDouble() * MAX_DATA_VALUE * 100) / 100.0;
}
}
你能解释一下这行代码吗?
col.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue()[c]))
来自javadoc:
需要设置单元格值工厂以指定如何填充单个TableColumn中的所有单元格。单元格值工厂是一个Callback,它提供TableColumn.CellDataFeatures实例,并期望返回一个ObservableValue。
所以它正在做的是定义一种从行的double[]
数据数据中提取列数据的方法(由param.getValue()
提供)。因为我们在数据值周围使用ReadOnlyObjectWrapper,如果您使表格单元格可编辑(我在此示例中没有这样做),则不会将编辑后的值写回到数组中。包装器是将double数据值转换为ObservableValue(根据单元工厂接口的要求)所必需的。
是的,我知道这很令人困惑,但这是为了让TableViews有效地被数百万个数据项virtualized controls支持而付出的代价。如果您不需要TableView的虚拟化功能和其他功能,则可以始终只使用GridPane中的标签。