Хорошо, учитывая ваше требование, я думаю, что сначала вам нужно определить свои свойства как IntegerProperty, а не оборачивать Integer в ObjectProperty (согласно стандартам javafx).Таким образом, для добавления вы можете напрямую использовать привязку номера, предоставленную IntegerProperty.Конечно, с этим изменением вам нужно определить тип данных TableColumn как Number.
Если вы очень хотите определить тип данных столбца как только Integer, то вы можете вызвать метод asObject () в своей ячейке cellValueFactory.Лично я не предпочитаю дополнительный уровень создания объекта с использованием asObject () и приведение к IntegerBinding:)
IntegerProperty part1 = new SimpleIntegerProperty();
TableColumn<Download, Integer> part1Col = new TableColumn<>("Part 1");
part1Col.setCellValueFactory(param -> param.getValue().part1Property().asObject());
TableColumn<Download, Integer> totalCol = new TableColumn<>("Total");
totalCol.setCellValueFactory(param -> ((IntegerBinding)param.getValue().part1Property().add(param.getValue().part2Property())).asObject());
Ниже приведен обновленный код (немного более чистый) предыдущей демонстрации с вышеуказанными изменениями, которыйобновит значение Part1 первой строки, а общее значение столбца обновится автоматически.
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
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 javafx.util.Duration;
public class CustomCellValueFactoryDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Download> downloads = FXCollections.observableArrayList();
downloads.add(new Download(23, 56));
downloads.add(new Download(56, 43));
downloads.add(new Download(97, 3));
downloads.add(new Download(67, 23));
TableView<Download> tableView = new TableView<>();
TableColumn<Download, Number> part1Col = new TableColumn<>("Part 1");
part1Col.setCellValueFactory(param -> param.getValue().part1Property());
TableColumn<Download, Number> part2Col = new TableColumn<>("Part 2");
part2Col.setCellValueFactory(param -> param.getValue().part2Property());
TableColumn<Download, Number> totalCol = new TableColumn<>("Total");
totalCol.setCellValueFactory(param -> param.getValue().part1Property().add(param.getValue().part2Property()));
tableView.getColumns().addAll(part1Col, part2Col, totalCol);
tableView.setItems(downloads);
Scene sc = new Scene(tableView);
primaryStage.setScene(sc);
primaryStage.show();
// Updating the value dynamically.
Download firstRow = downloads.get(0);
Timeline tl = new Timeline(new KeyFrame(Duration.millis(1000), e -> firstRow.setPart1(firstRow.getPart1() + 1)));
tl.setCycleCount(50);
tl.play();
}
class Download {
IntegerProperty part1 = new SimpleIntegerProperty();
IntegerProperty part2 = new SimpleIntegerProperty();
public Download(int p1, int p2) {
part1.set(p1);
part2.set(p2);
}
public int getPart1() {
return part1.get();
}
public IntegerProperty part1Property() {
return part1;
}
public void setPart1(int part1) {
this.part1.set(part1);
}
public int getPart2() {
return part2.get();
}
public IntegerProperty part2Property() {
return part2;
}
public void setPart2(int part2) {
this.part2.set(part2);
}
}
}