我有javafx表,其中包含组织的会员每月费用。在此表中,我显示了一些默认金额的费用,以便在任何情况下用户都可以更新金额或按原样继续进行操作。我真正需要的是,如果用户更新任何值,则这些值应立即绑定到表observablelist上。
创建表:
private void initCollectionTable(ObservableList<Member> mList) {
...
total_pay_col.setCellValueFactory(new SubscriptionValueFactory());
detail_view_col.setCellValueFactory(new DisplaySubscriptionFactory());
...
collection_tbl.setItems(mlz);
}
SubscriptionValueFactory类:
public class SubscriptionValueFactory implements Callback<TableColumn.CellDataFeatures<Member, String>, ObservableValue<String>> {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Member, String> param) {
//Here Subscriptions are equal to various member charges
Member ml = param.getValue();
List<MemberSubscriptions> mbrSubs = new ArrayList<>(ml.getMemberSubscriptions());
double sum =mbrSubs.stream().mapToDouble(a -> a.getAmount()).sum();
return new SimpleObjectProperty<>(TextFormatHandler.CURRENCY_DECIMAL_FORMAT.format(sum));
}
}
DisplaySubscriptionFactory类
public class DisplaySubscriptionFactory implements Callback<TableColumn.CellDataFeatures<Member, Button>, ObservableValue<Button>> {
@Override
public ObservableValue<Button> call(TableColumn.CellDataFeatures<Member, Button> param) {
Member ml = param.getValue();
List<MemberSubscriptions> mbrSubs = new ArrayList<>(ml.getMemberSubscriptions());
double sum =mbrSubs.stream().mapToDouble(a -> a.getAmount()).sum();
boolean flag = // SOME BOOLEAN CHECK HERE-----
param.getValue().setTotalSubscription(sum);
Button button = new Button("View Info");
button.setOnAction((evt) -> {
Alert alert_details = new Alert(Alert.AlertType.INFORMATION);
alert_details.setTitle("Subscription Information");
alert_details.setHeaderText("Member Subscription information for each installment");
alert_details.getDialogPane().setContent(createContentGrid(mbrSubs, sum, flag));
alert_details.show();
});
return new SimpleObjectProperty<>(button);
}
此方法创建一个网格以显示文本字段内的会员费用。因此,文本字段内部的任何值更改都应更新表observablelist的自身属性。
private Node createContentGrid(List<MemberSubscriptions> mbrSubs, double sum, boolean flag) {
GridPane grid = new GridPane();
grid.setHgap(20);
grid.setVgap(10);
grid.setPadding(new Insets(20, 20, 10, 10));
Label totLabel = new Label(TextFormatHandler.CURRENCY_DECIMAL_FORMAT.format(sum));
totLabel.setFont(Font.font("System Bold", 21.0));
Label col_h_1 = new Label("Subscription");
col_h_1.setFont(Font.font("System Bold", 17.0));
Label col_h_2 = new Label("Amount");
col_h_2.setFont(Font.font("System Bold", 17.0));
grid.add(col_h_1, 0, 0);
grid.add(col_h_2, 1, 0);
Label[] labels = new Label[mbrSubs.size()];
TextField[] fields = new TextField[mbrSubs.size()];
for (int i = 0; i < mbrSubs.size(); i++) {
MemberSubscriptions get = mbrSubs.get(i);
labels[i] = new Label("label");
fields[i] = new TextField();
fields[i].setTextFormatter(TextFormatHandler.currencyFormatter());
labels[i].setText(get.getMemberSubscription().getFeeName());
fields[i].setText(TextFormatHandler.CURRENCY_DECIMAL_FORMAT.format(get.getAmount()));
grid.add(labels[i], 0, i + 1);
grid.add(fields[i], 1, i + 1);
}
grid.add(totLabel, 1, mbrSubs.size() + 1);
return grid;
}
会员等级:
public class Member {
private Integer id;
private String memberId;
...
private Set<MemberSubscriptions> memberSubscriptions = new HashSet<>();
...
会员订阅类
public class MemberSubscriptions {
private Integer id;
private Member member;
private Double amount;
...
最佳答案
我想我已经找到了您问题的答案。我已经简化了它,所以也许您可以使用它来解决您的问题。
这是我的班级代码:
模型:
public class Model {
private LongProperty id;
private DoubleProperty amount;
private ObjectProperty<SubModel> subModel;
public Model(Long id, Double amount, SubModel subModel) {
this.id = new SimpleLongProperty(id);
this.amount = new SimpleDoubleProperty(amount);
this.subModel = new SimpleObjectProperty<>(subModel);
}
public long getId() {
return id.get();
}
public LongProperty idProperty() {
return id;
}
public DoubleProperty amountProperty() {
return amount;
}
public SubModel getSubModel() {
return subModel.get();
}
public ObjectProperty<SubModel> subModelProperty() {
return subModel;
}
}
子模型:
public class SubModel {
private LongProperty id;
private DoubleProperty xAmount;
private DoubleProperty yAmount;
public SubModel(Long id, Double xAmount, Double yAmount) {
this.id = new SimpleLongProperty(id);
this.xAmount = new SimpleDoubleProperty(xAmount);
this.yAmount = new SimpleDoubleProperty(yAmount);
}
public long getId() {
return id.get();
}
public double getxAmount() {
return xAmount.get();
}
public DoubleProperty xAmountProperty() {
return xAmount;
}
public double getyAmount() {
return yAmount.get();
}
public DoubleProperty yAmountProperty() {
return yAmount;
}
}
纽扣电池:
public class ButtonTableCell<S, T> extends TableCell<S, T> {
private Button button;
public ButtonTableCell() {
this.button = new Button("View Info");
button.setOnAction(event -> {
Model model = (Model) getTableRow().getItem();
Dialog<SubModel> dialog = new AmountDialog(model.getSubModel());
dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
dialog.showAndWait().ifPresent(result -> {
model.amountProperty().set(result.getxAmount() + result.getyAmount());
});
});
}
@Override protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if (empty) {
setGraphic(null);
} else {
setGraphic(button);
}
}
}
对话:
public class AmountDialog extends Dialog<SubModel> {
public AmountDialog(SubModel model) {
setTitle("Title");
setHeaderText("Header");
getDialogPane().setContent(createContent(model));
setResultConverter(button -> {
if (button == ButtonType.OK) {
return model;
}
return null;
});
}
private GridPane createContent(SubModel model) {
GridPane grid = new GridPane();
grid.setHgap(20);
grid.setVgap(10);
grid.setPadding(new Insets(20, 20, 10, 10));
Label sub = new Label("Sub");
Label amount = new Label("Amount");
Label amountX = new Label("AmountX");
Label amountY = new Label("AmountY");
TextField tfAmounX = new TextField(String.valueOf(model.getxAmount()));
TextField tfAmountY = new TextField(String.valueOf(model.getyAmount()));
Bindings.bindBidirectional(tfAmounX.textProperty(), model.xAmountProperty(), new StringDoubleConverter());
Bindings.bindBidirectional(tfAmountY.textProperty(), model.yAmountProperty(), new StringDoubleConverter());
grid.add(sub, 0, 0);
grid.add(amount, 1, 0);
grid.add(amountX, 0, 1);
grid.add(tfAmounX, 1, 1);
grid.add(amountY, 0, 2);
grid.add(tfAmountY, 1, 2);
return grid;
}
private class StringDoubleConverter extends StringConverter<Number> {
@Override public String toString(Number object) {
return object.toString();
}
@Override public Number fromString(String string) {
// You may handle NumberFormatException.
return Double.valueOf(string);
}
}
}
和控制器:
public class Controller implements Initializable {
@FXML
private TableView<Model> table;
@FXML
private TableColumn<Model, Long> colId;
@FXML
private TableColumn<Model, Double> colAmount;
@FXML
private TableColumn<Model, SubModel> colInfo;
@Override
public void initialize(URL location, ResourceBundle resources) {
setupTable();
setupData();
}
private void setupTable() {
colId.setCellValueFactory(data -> data.getValue().idProperty().asObject());
colAmount.setCellValueFactory(data -> data.getValue().amountProperty().asObject());
colInfo.setCellValueFactory(data -> data.getValue().subModelProperty());
colInfo.setCellFactory(factory -> new ButtonTableCell<>());
}
private void setupData() {
SubModel firstSubModel = new SubModel(1L, 0D, 0D);
SubModel secondSubModel = new SubModel(2L, 0D, 0D);
Model fist = new Model(1L, 0D, firstSubModel);
Model second = new Model(2L, 0D, secondSubModel);
ObservableList<Model> tableData = FXCollections.observableArrayList();
tableData.add(fist);
tableData.add(second);
table.setItems(tableData);
}
}
我知道长一点的答案,但我希望它能解决您的问题。对于我来说,它正在按OK(确定)按钮,但是如果您想在更改对话框的任何字段中的值时立即更新,则可以走得更远。
关于java - JavaFX TableView将cellValueFactory内部的更改绑定(bind)到表observablelist,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47429890/