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