【问题标题】:How to fill TableView's Column with a values from an array如何用数组中的值填充 TableView 的列
【发布时间】:2025-12-13 13:15:01
【问题描述】:

我有 ObservableListGameLogEntry 的实例:

public class GameLogEntry {
    private int gameNumber;

    private int chosenStratA;
    private int chosenStratB;

    private Double[] scoresByB;
    private Double[] scoresByA;

    private double higherPrice;
    private double lowerPrice;
    private double averagePrice;

    private int maxIndex;

在我的程序中,我使用来自这个 ObservableList 的值填充 TableView 的列。

我的专栏:

@FXML
    private TableColumn<GameLogEntry, String> colGameNum;

    @FXML
    private TableColumn<GameLogEntry, String> colChosenStratA;

    @FXML
    private TableColumn<GameLogEntry, String> colScoreByBOne;

    @FXML
    private TableColumn<GameLogEntry, String> colScoreByBTwo;

    @FXML
    private TableColumn<GameLogEntry, String> colChosenStratB;

    @FXML
    private TableColumn<GameLogEntry, String> colScoreByAOne;

    @FXML
    private TableColumn<GameLogEntry, String> colScoreByATwo;

    @FXML
    private TableColumn<GameLogEntry, String> colLowerPrice;

    @FXML
    private TableColumn<GameLogEntry, String> colHigherPrice;

    @FXML
    private TableColumn<GameLogEntry, String> colAveragePrice;

我在initialize 方法中这样做:

colGameNum.setCellValueFactory(new PropertyValueFactory<GameLogEntry, String>("gameNumber"));
colChosenStratA.setCellValueFactory(new PropertyValueFactory<GameLogEntry, String>("chosenStratA"));
colChosenStratB.setCellValueFactory(new PropertyValueFactory<GameLogEntry, String>("chosenStratB"));
colHigherPrice.setCellValueFactory(new PropertyValueFactory<GameLogEntry, String>("higherPrice"));
colLowerPrice.setCellValueFactory(new PropertyValueFactory<GameLogEntry, String>("lowerPrice"));
colAveragePrice.setCellValueFactory(new PropertyValueFactory<GameLogEntry, String>("averagePrice"));

但我还需要填写 CS(B1)、CS(B2)、CS(A1) 和 CS(A2) 列。

CS(B1) 应该用 scoreByB[0] 填充,

CS(B2) - 使用 scoreByB[1],

CS(A1) - 使用 scoreByA[0],

CS(A2) - 使用 scoreByA[1]。

问题是 - 我可以使用与其他值相同的简单方法吗?如果没有,我该如何以其他方式做到这一点?

【问题讨论】:

标签: java javafx tableview


【解决方案1】:

只需自己实现工厂。您可以创建一个辅助方法以避免重复代码:

static <S, T> Callback<TableColumn.CellDataFeatures<S, T>, ObservableValue<T>> createArrayValueFactory(Function<S, T[]> arrayExtractor, final int index) {
    if (index < 0) {
        return cd -> null;
    }
    return cd -> {
        T[] array = arrayExtractor.apply(cd.getValue());
        return array == null || array.length <= index ? null : new SimpleObjectProperty<>(array[index]);
    };
}
colScoreByBOne.setCellValueFactory(createArrayValueFactory(GameLogEntry::getScoresByB, 0));
colScoreByBTwo.setCellValueFactory(createArrayValueFactory(GameLogEntry::getScoresByB, 1));
colScoreByAOne.setCellValueFactory(createArrayValueFactory(GameLogEntry::getScoresByA, 0));
colScoreByATwo.setCellValueFactory(createArrayValueFactory(GameLogEntry::getScoresByA, 1));

为此,您需要将列的类型更改为TableColumn&lt;GameLogEntry, Double&gt;。 (事实上​​,您应该更改所有列的值类型,因为没有一个属性是String 类型;所有属性都是Double 或@ 类型987654326@.)

【讨论】:

  • 感谢您指出字符串类型错误。我对此有些怀疑。
  • 当然可以,但是:如果数组的各个元素具有某种意义,则应在日志的适配器中对它们进行建模,而不是在实用方法中临时建模
  • @kleopatra 你能解释一下你所说的适配器是什么意思吗?我是 Java 新手。