有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何将TableView中TableColumn的和绑定到外部标签textProperty()?

有一个订单表视图,其中有一列用于表示订单成本。订单对象的成本属性可以在TableView中更改。这意味着Order列单元格可以使用TextFieldTableCell进行更改。此外,TableView之外还有一个标签,它应该表示订单成本的总和。现在,问题是我不知道如何将order costs列的总和绑定到Label的text属性()

下面是一些代码来澄清问题:

     class Order {
            private SimpleStringProperty name;
            private SimpleIntegerProperty cost;

            public String getName() {
                return this.name.get();
            }

            public void setName(String name) {
                this.name.set(name);
            }

            public SimpleStringProperty nameProperty() {
                return this.name;
            }

            public Integer getCost() {
                return this.cost.get();
            }

            public void setCost(Integer cost) {
                this.cost.set(cost);
            }

            public SimpleIntegerProperty costProperty() {
                return this.cost;
            }
        }

        TableView<Order> tableView = new TableView<>();

        TableColumn<Order, String> nameColumn = new TableColumn<>();
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());

        TableColumn<Order, String> costColumn = new TableColumn<>();
        costColumn.setCellValueFactory(new PropertyValueFactory<>("cost"));
        costColumn.setCellFactory(TextFieldTableCell.forTableColumn());

        tableView.getColumns().addAll(nameColumn, costColumn);

        Label totalCostLabel = new Label("Total cost should be updated in this label");

        VBox vBox = new VBox();
        vBox.getChildren().addAll(tableView, totalCostLabel);

共 (1) 个答案

  1. # 1 楼答案

    您可以执行以下操作:

    1. 创建一个ObservableList^{}映射到costProperty(),并将其用作表的items列表:

      tableView.setItems(FXCollections.observableArrayList(
          order -> new Observable[] { order.costProperty() }));
      

      这确保了当列表中的costProperty个元素发生更改时,列表会触发更新事件(除了在列表中添加或删除元素时触发的常规事件,等等)

    2. 创建一个绑定到列表的DoubleBinding,并计算总成本:

      DoubleBinding totalCost = Bindings.createDoubleBinding(() -> {
          double total = 0 ;
          for (Order order : tableView.getItems()) {
              total = total + order.getCost();
          }
          return total ;
      }, tableView.getItems());
      
    3. 将标签的textProperty()绑定到总成本:

      totalCostLabel.textProperty().bind(totalCost.asString());
      

    如果您希望对asString()方法的显示方式有更多的控制,那么可以向该方法提供^{}

    以下是根据您的代码改编的完整示例:

    import javafx.application.Application;
    import javafx.beans.Observable;
    import javafx.beans.binding.Bindings;
    import javafx.beans.binding.DoubleBinding;
    import javafx.beans.property.IntegerProperty;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.TableColumn;
    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.converter.IntegerStringConverter;
    
    
    public class SummingTable extends Application {
    
    
        @Override
        public void start(Stage stage) {
            TableView<Order> tableView = new TableView<>();
    
            tableView.setItems(FXCollections.observableArrayList(
                    order -> new Observable[] { order.costProperty() }));
    
            tableView.getItems().addAll(
                    new Order("Order 1", 10),
                    new Order("Order 2", 20));
    
            tableView.setEditable(true);
    
    
            TableColumn<Order, String> nameColumn = new TableColumn<>();
            nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
            nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
    
            TableColumn<Order, Integer> costColumn = new TableColumn<>();
            costColumn.setCellValueFactory(cellData -> cellData.getValue().costProperty().asObject());
            costColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
    
            tableView.getColumns().addAll(nameColumn, costColumn);
    
            Label totalCostLabel = new Label("Total cost should be updated in this label");
    
            DoubleBinding totalCost = Bindings.createDoubleBinding(() -> {
                double total = 0 ;
                for (Order order : tableView.getItems()) {
                    total = total + order.getCost();
                }
                return total ;
            }, tableView.getItems());
    
            totalCostLabel.textProperty().bind(totalCost.asString());
    
            VBox vBox = new VBox();
            vBox.getChildren().addAll(tableView, totalCostLabel);
    
            Scene scene = new Scene(vBox);
            stage.setScene(scene);
            stage.show();
    
        }
    
        public class Order {
            private final StringProperty name = new SimpleStringProperty();
            private final IntegerProperty cost = new SimpleIntegerProperty();
    
            public Order(String name, int cost) {
                setName(name);
                setCost(cost);
            }
    
            public String getName() {
                return this.name.get();
            }
    
            public void setName(String name) {
                this.name.set(name);
            }
    
            public StringProperty nameProperty() {
                return this.name;
            }
    
            public Integer getCost() {
                return this.cost.get();
            }
    
            public void setCost(Integer cost) {
                this.cost.set(cost);
            }
    
            public IntegerProperty costProperty() {
                return this.cost;
            }
        }
    
        public static void main(String[] args) {
            launch();
        }
    
    }