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

Javafx 如何获取具有可编辑列的TableView的列总数?,javafx,tornadofx,Javafx,Tornadofx,我有一个表格视图,显示了从周一到周五,员工在不同项目上工作时间的时间表。数据源是一周中每一天都具有浮点属性的时间表类列表。例如,我想显示一个值,该值将星期一列中的所有小时相加,并显示星期一小时总数。我认为做一点研究是很容易的,因为对我来说,在使用TableView的数据驱动应用程序中,想要列总数是很常见的,但我似乎找不到一个优雅的答案,或者根本找不到任何答案。如果我可以在时间表列表更改时计算列总数,那就容易多了,但我还必须监听用户更改/编辑列值的时间。有什么想法吗?这是一个非tornadofx版

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

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

主要


你们试过edit committed吗?我知道有一种方法可以抓取表中的项目并选择要添加的属性,但我很难找到一种方法来检测何时进行了更改。我忘记了onEditCommit{/*合计星期一小时数,设置为新的总计*/},所以感谢您的提醒!我猜,因为列表是可观察的,所以可以创建一个属性来绑定列total。我的答案并没有说明这一点。实际上,绑定列总计对我来说有点困难,因为我使用的表视图实际上经常更改数据,并且可以选择添加和减去行,这意味着每当表的列表发生更改时,我必须创建一个新的绑定,并将其重新分配给显示总数的UI组件,除非有更好的方法来实现这一点,我不知道。在这一点上,这似乎是白费力气。我只是想更新一个SimpleFloatProperty。是的,TornadFX的生成器的setOnEditCommit或onEditCommit{/*action*/}就是我想要的!记不起检测更改的好方法。
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();
    }

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

}