JavaFX Tableview-列值依赖于其他列

JavaFX Tableview-列值依赖于其他列,javafx,Javafx,我在JavaFX中有一个TableView。它有一个字段小计,它取决于字段数量和价格的值。我为小计添加了一个新列 我有文本字段可以向表中添加新行。但是,“添加”按钮希望为“小计”列提供另一个textfield,尽管小计列实际上并不需要它 到目前为止,我所尝试的: TableColumn columnCodeProduct = new TableColumn("Product Code"); columnCodeProduct.setMinWidth(100); columnCodeProduct

我在JavaFX中有一个
TableView
。它有一个字段
小计
,它取决于字段
数量
价格
的值。我为
小计添加了一个新列

我有文本字段可以向表中添加新行。但是,“添加”按钮希望为“小计”列提供另一个
textfield
,尽管小计列实际上并不需要它

到目前为止,我所尝试的:

TableColumn columnCodeProduct = new TableColumn("Product Code");
columnCodeProduct.setMinWidth(100);
columnCodeProduct.setCellValueFactory(new PropertyValueFactory<Data , Integer>("productname "));

TableColumn columnProductName = new TableColumn("Product Name");
columnProductName.setMinWidth(140);
columnProductName.setCellValueFactory(new PropertyValueFactory<Data , String>("codeproduct"));

TableColumn columnPrice = new TableColumn("Price");
columnPrice.setMinWidth(100);
columnPrice.setCellValueFactory(new PropertyValueFactory<Data , Integer>("price"));

TableColumn columQuantity = new TableColumn("Quantity");
columQuantity.setMinWidth(100);
columQuantity.setCellValueFactory(new PropertyValueFactory<Data , Integer>("quantity"));


TableColumn columnTotal = new TableColumn("Sub Total");
columnTotal.setMinWidth(100);
columQuantity.setCellValueFactory(new PropertyValueFactory<Data , Integer>("sub"));

tableData.getColumns().addAll(columnCodeProduct , columnProductName , columnPrice ,  columQuantity );

tableData.setItems(data);


addButton = new Button("Add Item");


addButton.setOnAction(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event)
    {
        if(addproCodeTextfield.getText().isEmpty() || addproNameTextfield.getText().isEmpty()
            || addPriceTextfield.getText().isEmpty() || quantityTextField.getText().isEmpty())
        {
            System.out.println("Please Add information to all the fields");
        } else {
            data.add(new Data (

                           addproCodeTextfield.getText(),
                           addproNameTextfield.getText(),
                 addPriceTextfield.getText(),                             
                           quantityTextField.getText()));                             
             methodTotal();
        }
    }
});

您可以从JavaFX绑定
值的能力中获益

实施上述场景时需要注意的几点:

  • POJO类(在您的例子中是
    数据
    )字段必须具有正确的类型。例如,价格和数量必须为
    SimpleIntegerProperty
    ,而不是
    SimpleStringProperty
    。这将帮助我们使用
    绑定
  • 小计
    字段取决于价格和数量的值。实现这一点的最佳方法是将subTotalProperty绑定为价格和数量的倍数绑定
我创建了一个简单的示例basic editable tableview来展示这种方法。它具有您(或其他寻求相同问题的人)可能需要的其他功能,如可编辑单元格;)

导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.binding.NumberBinding;
导入javafx.beans.property.SimpleIntegerProperty;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.geometry.Insets;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.*;
导入javafx.scene.control.TableColumn.CellEditEvent;
导入javafx.scene.control.cell.PropertyValueFactory;
导入javafx.scene.control.cell.TextFieldTableCell;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.VBox;
导入javafx.scene.text.Font;
导入javafx.stage.stage;
导入javafx.util.converter.NumberStringConverter;
公共类TableViewSample扩展了应用程序{
private TableView table=new TableView();
私有最终可观测列表数据=
FXCollections.observableArrayList(
新产品(“笔记本”,10、12),
新产品(“橡皮擦”,20,12),
新产品(“铅笔”,30,12),
新产品(“Pen”,40,12),
新产品(“胶水”,50,12));
最终HBox hb=新HBox();
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公众假期开始(阶段){
场景=新场景(新组());
stage.setTitle(“书店样本”);
舞台设置宽度(650);
舞台设置高度(550);
最终标签=新标签(“书店”);
label.setFont(新字体(“Arial”,20));
table.setEditable(true);
TableColumn名称=新的TableColumn(“名称”);
名称.设置最小宽度(100);
name.setCellValueFactory(
新财产价值工厂(“名称”);
name.setCellFactory(TextFieldTableCell.forTableColumn());
name.setOnEditCommit(
新的EventHandler(){
@凌驾
公共无效句柄(CellEditEvent t){
((产品)t.getTableView().getItems().get(
t、 getTablePosition().getRow())
).setName(t.getNewValue());
}
}
);
TableColumn priceCol=新的TableColumn(“价格”);
价格设置最小宽度(100);
priceCol.setCellValueFactory(
新物业价值工厂(“价格”);
priceCol.setCellFactory(TextFieldTableCell.forTableColumn(新编号stringconverter());
priceCol.setOnEditCommit(
新的EventHandler(){
@凌驾
公共无效句柄(CellEditEvent t){
((产品)t.getTableView().getItems().get(
t、 getTablePosition().getRow())
).setPrice(t.getNewValue().intValue());
}
}
);
TableColumn quantityCol=新的TableColumn(“数量”);
quantityCol.设置最小宽度(200);
quantityCol.setCellValueFactory(
新物业价值工厂(“数量”);
quantityCol.setCellFactory(TextFieldTableCell.forTableColumn(newnumberstringconverter());
quantityCol.setOnEditCommit(
新的EventHandler(){
@凌驾
公共无效句柄(CellEditEvent t){
((产品)t.getTableView().getItems().get(
t、 getTablePosition().getRow())
).setQuantity(t.getNewValue().intValue());
}
}
);
TableColumn小计=新的TableColumn(“小计”);
设置最小宽度小计(200);
setCellValueFactory小计(
新房地产价值工厂(“小计”);
表2.设置项目(数据);
table.getColumns().addAll(名称、价格、数量、小计);
final TextField addName=new TextField();
addName.setPrompText(“名称”);
addName.setMaxWidth(name.getPrefWidth());
最终文本字段addPrice=新文本字段();
addPrice.setMaxWidth(priceCol.getPrefWidth());
addPrice.SetPrompText(“价格”);
最终文本字段addQuantity=新文本字段();
addQuantity.setMaxWidth(quantityCol.getPrefWidth());
addQuantity.setPrompText(“数量”);
最终按钮addButton=新按钮(“添加”);
addButton.setOnAction(新的EventHandler(){
@凌驾
public class Data
{
    private final SimpleStringProperty codeproduct;
    private final SimpleStringProperty productname;
    private final SimpleStringProperty price ;
    private final SimpleStringProperty quantity;



    public Data (String code , String proname ,  String presyo ,  String quant )
    {
        this.codeproduct = new SimpleStringProperty(code);
        this.productname = new SimpleStringProperty(proname);
        this.price = new SimpleStringProperty(presyo);
        this.quantity = new SimpleStringProperty(quant);

    }

    public String getcodeProduct()
    {
        return codeproduct.get();
    }

    public String getproductName()
    {
        return productname.get();
    }

    public String getPrice()
    {
        return price.get();
    }

    public String getQuantity()
    {
        return quantity.get();
    }

}
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.NumberBinding;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;

public class TableViewSample extends Application {

    private TableView<Product> table = new TableView<Product>();
    private final ObservableList<Product> data =
            FXCollections.observableArrayList(
                    new Product("Notebook", 10, 12),
                    new Product("Eraser", 20, 12),
                    new Product("Pencil", 30, 12),
                    new Product("Pen", 40, 12),
                    new Product("Glue", 50, 12));
    final HBox hb = new HBox();

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Book Store Sample");
        stage.setWidth(650);
        stage.setHeight(550);

        final Label label = new Label("Book Store");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);


        TableColumn name = new TableColumn("Name");
        name.setMinWidth(100);
        name.setCellValueFactory(
                new PropertyValueFactory<Product, String>("name"));
        name.setCellFactory(TextFieldTableCell.forTableColumn());
        name.setOnEditCommit(
                new EventHandler<CellEditEvent<Product, String>>() {
                    @Override
                    public void handle(CellEditEvent<Product, String> t) {
                        ((Product) t.getTableView().getItems().get(
                                t.getTablePosition().getRow())
                        ).setName(t.getNewValue());
                    }
                }
        );


        TableColumn priceCol = new TableColumn("Price");
        priceCol.setMinWidth(100);
        priceCol.setCellValueFactory(
                new PropertyValueFactory<Product, String>("price"));
        priceCol.setCellFactory(TextFieldTableCell.<Product, Number>forTableColumn(new NumberStringConverter()));
        priceCol.setOnEditCommit(
                new EventHandler<CellEditEvent<Product, Number>>() {
                    @Override
                    public void handle(CellEditEvent<Product, Number> t) {
                        ((Product) t.getTableView().getItems().get(
                                t.getTablePosition().getRow())
                        ).setPrice(t.getNewValue().intValue());
                    }
                }
        );

        TableColumn quantityCol = new TableColumn("Quantity");
        quantityCol.setMinWidth(200);
        quantityCol.setCellValueFactory(
                new PropertyValueFactory<Product, Number>("quantity"));
        quantityCol.setCellFactory(TextFieldTableCell.<Product, Number>forTableColumn(new NumberStringConverter()));
        quantityCol.setOnEditCommit(
                new EventHandler<CellEditEvent<Product, Number>>() {
                    @Override
                    public void handle(CellEditEvent<Product, Number> t) {
                        ((Product) t.getTableView().getItems().get(
                                t.getTablePosition().getRow())
                        ).setQuantity(t.getNewValue().intValue());
                    }
                }
        );

        TableColumn subTotalCol = new TableColumn("Sub Total");
        subTotalCol.setMinWidth(200);
        subTotalCol.setCellValueFactory(
                new PropertyValueFactory<Product, String>("subTotal"));


        table.setItems(data);
        table.getColumns().addAll(name, priceCol, quantityCol, subTotalCol);

        final TextField addName = new TextField();
        addName.setPromptText("Name");
        addName.setMaxWidth(name.getPrefWidth());
        final TextField addPrice = new TextField();
        addPrice.setMaxWidth(priceCol.getPrefWidth());
        addPrice.setPromptText("Price");
        final TextField addQuantity = new TextField();
        addQuantity.setMaxWidth(quantityCol.getPrefWidth());
        addQuantity.setPromptText("Quantity");

        final Button addButton = new Button("Add");
        addButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
                data.add(new Product(
                        name.getText(),
                        Integer.parseInt(addPrice.getText()),
                        Integer.parseInt(addQuantity.getText())));
                addName.clear();
                addPrice.clear();
                addQuantity.clear();
            }
        });

        hb.getChildren().addAll(addName, addPrice, addQuantity, addButton);
        hb.setSpacing(3);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table, hb);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();
    }

    public static class Product {

        private final SimpleStringProperty name;
        private final SimpleIntegerProperty price;
        private final SimpleIntegerProperty quantity;
        private final SimpleIntegerProperty subTotal;

        private Product(String name, int price, int quantity) {
            this.name = new SimpleStringProperty(name);
            this.price = new SimpleIntegerProperty(price);
            this.quantity = new SimpleIntegerProperty(quantity);
            this.subTotal = new SimpleIntegerProperty();
            NumberBinding multiplication = Bindings.multiply(this.priceProperty(), this.quantityProperty());
            this.subTotalProperty().bind(multiplication);
        }

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

        public SimpleStringProperty nameProperty() {
            return name;
        }

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

        public int getPrice() {
            return price.get();
        }

        public SimpleIntegerProperty priceProperty() {
            return price;
        }

        public void setPrice(int price) {
            this.price.set(price);
        }

        public int getQuantity() {
            return quantity.get();
        }

        public SimpleIntegerProperty quantityProperty() {
            return quantity;
        }

        public void setQuantity(int quantity) {
            this.quantity.set(quantity);
        }

        public int getSubTotal() {
            return subTotal.get();
        }

        public SimpleIntegerProperty subTotalProperty() {
            return subTotal;
        }

        public void setSubTotal(int subTotal) {
            this.subTotal.set(subTotal);
        }
    }
}
TableColumn<Data, Number> subtotalColumn = new TableColumn<>("Sub Total");
subTotalColumn.setCellValueFactory(cellData -> {
    Data data = cellData.getValue();
    return Bindings.createDoubleBinding(
            () -> {
                try {
                    double price = Double.parseDouble(data.getPrice());
                    int quantity = Integer.parseInt(data.getQuantity());
                    return price * quantity ;
                } catch (NumberFormatException nfe) {
                    return 0 ;
                }
            },
            data.priceProperty(),
            data.quantityProperty()
    );
});