kekyc
kekyc

Reputation: 327

How to fill TableView's Column with a values from an array

I have an ObservableList of instances of class GameLogEntry:

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;

In my program I populate TableView's columns with values from this ObservableList. enter image description here

My columns:

@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;

I'm doing it like this in initialize method:

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

But also I need to fill CS(B1), CS(B2), CS(A1) and CS(A2) columns.

CS(B1) should be filled with scoresByB[0],

CS(B2) - with scoresByB[1],

CS(A1) - with scoresByA[0],

CS(A2) - with scoresByA[1].

The question is - can I do it with the same simple methods like I did with other values? And if no, how can I do it in any other ways?

Upvotes: 0

Views: 1757

Answers (1)

fabian
fabian

Reputation: 82461

Simply implement the factory yourself. You could create a helper method to avoid repeating the code:

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

For this to work however you need to change the types of the column to TableColumn<GameLogEntry, Double>. (In fact you should change all the value types for the columns, since not a single property is of type String; all properties are of type Double or Integer.)

Upvotes: 2

Related Questions