如何获取具有可编辑列的 TableView 的列总计?

How to get column totals of TableView with editable columns?

我有一个 table 视图,它显示员工在不同项目上的工作时间 sheets,从周一到周五。数据源是时间 sheet 类 的列表,具有一周中每一天的浮点属性。例如,我想显示一个值,该值将 Monday 列中的所有小时数相加并显示 Monday Hours 总数。我认为做一点研究会很容易,因为对我来说,在使用 TableViews 的数据驱动应用程序中,想要列总数很常见,但我似乎找不到一个优雅的答案,或者根本找不到任何答案.如果我可以在 timesheets 列表更改时只计算列总计,那会更容易,但我还必须监听用户编辑列值 change/are 的时间。有什么想法吗?

这里是非tornadofx版本。在 setOnEditCommit 中,更新可观察列表并对列求和。

Main

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class App extends Application
{

    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage)
    {
        Label total = new Label("0");

        ObservableList<Time> data = FXCollections.observableArrayList();
        data.add(new Time(0));
        data.add(new Time(3));

        TableView<Time> tableView = new TableView();
        tableView.setEditable(true);
        tableView.setItems(data);

        total.setText(Integer.toString(data.stream().mapToInt(Time::getHours).sum()));
        TableColumn<Time, Integer> column1 = new TableColumn("Time");
        column1.setCellValueFactory(new PropertyValueFactory<>("hours"));
        column1.setCellFactory(TextFieldTableCell.forTableColumn(new StringConverter<Integer>()
        {
            @Override
            public String toString(Integer t)
            {
                return Integer.toString(t);
            }

            @Override
            public Integer fromString(String string)
            {
                return Integer.parseInt(string);
            }
        }));
        column1.setOnEditCommit((CellEditEvent<Time, Integer> t) -> {
            ((Time) t.getTableView().getItems().get(
                    t.getTablePosition().getRow())).setHours(t.getNewValue());

            total.setText(Integer.toString(data.stream().mapToInt(Time::getHours).sum()));
        });;

        tableView.getColumns().add(column1);

        VBox vbox = new VBox(tableView, total);

        Scene scene = new Scene(vbox);

        primaryStage.setScene(scene);

        primaryStage.show();
    }

}

Time

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;

public class Time
{

    private final IntegerProperty hours = new SimpleIntegerProperty();

    public Time(int hours)
    {
        this.hours.set(hours);
    }

    public IntegerProperty hoursProperty()
    {
        return hours;
    }

    public void setHours(int hours)
    {
        this.hours.set(hours);
    }

    public Integer getHours()
    {
        return this.hours.getValue();
    }

}