在 TableView 中使用 PropertyValueFactory 的值 - JavaFx

Work with Value from PropertyValueFactory in TableView - JavaFx

在我的 JavaFx 项目中,我有一个包含几个视图的场景。对于 window 的页脚,我有一个 class 延伸自 TableView:

public class FooterView extends TableView<Area> implements ViewTemplate {...}

这会显示一个 Table,其中包含来自 .csv 文件的一些数据。

在将特定表示模型 属性 的值分配给单元格时,我是这样做的:

TableColumn<Area,Double> powerColumn = new TableColumn<>("Power Overview");
powerColumn.setCellValueFactory(new PropertyValueFactory<>("powerPerArea"));

this.setItems(filePM.getAreas()); //filePm is my filehandler
this.getColumns().addAll(powerColumn, other_columns);

getAreas() 看起来像这样:

public List<Area> readCantonsFromFile() {
        try (Stream<String> stream = getStreamOfLines(AREA_FILE_NAME)) {
            return stream.skip(1)
                    .map(l -> new Area(l.split(DELIMITER, 12)))
                    .collect(Collectors.toList());
        }
}

Area 的构造函数中,我设置了属性。其中一个属性是提到的 powerPerArea

private final DoubleProperty powerPerArea = new SimpleDoubleProperty();
...
public void setPowerPerCanton(double powerPerCanton) {
    this.powerPerCanton.set(powerPerCanton);
}

我的问题:有没有办法在显示值之前更改FooterView中的值?我试过这样的事情:

powerColumn.setCellValueFactory(Math.round(new PropertyValueFactory<>("powerPerArea")));

但是我好像混淆了DoubleProperty、Double和ObservableDouble。我什至可以修改这里的值吗?

问题:我无法舍入 setter 中的值,因为我通过此函数在循环中添加了一个双精度值:

public void addPowerPerArea(double power){
    double sum = getPowerPerCanton() + power;
    setPowerPerCanton(sum);
}

这里的值四舍五入会给我一个错误的结果。 (四舍五入不够精确)。我需要在所有金额相加后完成

我看到有两种方法可以做到这一点。你可以:

使用 setCellFactory 方法并在 updateItem 方法中对其进行格式化。应该看起来像这样,还没有测试

powerColumn.setCellFactory(column -> {
    return new TableCell<Area, Double>() {
        @Override
        protected void updateItem(Double item, boolean empty) {
            super.updateItem(Math.round(item), empty);
        }
    };
});

或者:您可以为您的 Area class 创建另一个 属性 绑定到现有的 powerOfArea 属性 但 returns四舍五入的价值。我相信这在某种程度上是可能的,你可以覆盖 readOnlyDoubleProperty 的一些功能,但应该有更好的方法。也许通过 DoubleBindings.

您应该使用 cellValueFactory 来确定 哪些数据 显示在单元格中:在这种情况下,您的 PropertyValueFactory 返回的数据是实际数据doublepowerPerAreaProperty().get() 返回的值,这正是您想要的。

如果您想控制如何显示数据,您应该使用cellFactory。所以要以特定格式显示数据,包括限制小数位数,你可以这样做:

powerColumn.setCellFactory(tc -> new TableCell<Area, Double>() {
    @Override
    protected void updateItem(Double power, boolean empty) {
        super.updateItem(power, empty);
        if (empty) {
            setText(null);
        } else {
            setText(String.format("%.0f", power.doubleValue()));
        }
    }
});

这里的重点是你不应该根据你想要的显示方式修改数据; cellValueFactorycellFactory 的目的是将数据的 显示 与实际数据本身分开。

cellFactory 自定义单元格 return 的替代方法是使用自定义 cellValueFactory 到 return 格式为字符串的 属性:

TableColumn<Area, String> powerColumn = new TableColumn<>("Power Overview");
powerColumn.setCellValueFactory(cd -> cd.getValue().powerPerAreaProperty().asString(""%.0f""));