Ich habe javafx Tabelle, die Mitglied enthält monatliche Gebühren einer Organisation enthält. In dieser Tabelle zeige ich einige Gebühren mit ihrem Standardbetrag, so dass Benutzer in jedem Fall den Betrag aktualisieren oder so fortfahren können. Was ich tatsächlich brauche, ist, wenn Benutzer irgendwelche Werte aktualisieren, sollten diese sofort an die Tabelle Observable List gebunden werden.JavaFX TableView bind Änderungen in CellValueFactory zu Tabelle Observablelist
erstellen Tabelle:
private void initCollectionTable(ObservableList<Member> mList) {
...
total_pay_col.setCellValueFactory(new SubscriptionValueFactory());
detail_view_col.setCellValueFactory(new DisplaySubscriptionFactory());
...
collection_tbl.setItems(mlz);
}
SubscriptionValueFactory Klasse:
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 Klasse
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);
}
Diese Methode erstellt ein Raster, um die Mitgliedsgebühren in Textfeldern anzuzeigen. Jede Wertänderung innerhalb des Textfelds sollte daher seine eigene Eigenschaft der Tabelle Observablenliste aktualisieren.
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;
}
Klasse:
public class Member {
private Integer id;
private String memberId;
...
private Set<MemberSubscriptions> memberSubscriptions = new HashSet<>();
...
MemberSubscriptions Klasse
public class MemberSubscriptions {
private Integer id;
private Member member;
private Double amount;
...
Wenn möglich, sollten die 'membersSubscriptions' ein' ObservableSet' und die Eigenschaften von 'MemberSubscription' JavaFX-ähnliche Observables/Properties sein. Ich verstehe auch nicht ganz, warum Sie eine 'MembersSubscriptions'-Klasse mit einem 'MemberSubscription'-Feld brauchen - sollte nicht die Menge in' Member' aus tatsächlichen Abonnements bestehen, anstatt ... was 'MemberSubscriptions' ist? – Itai
Zuerst übergibt 'initCollectionTable() 'in' mList', aber 'setItems()' verwendet 'mlz', das aus dem Nichts kommt.Zweitens sollten Sie keine Schaltfläche in 'setCellValueFactory()' erstellen, sondern in 'setCellFactory()'. Drittens müssen Sie in Ihren Klassen "Member" und "MemberSubscriptions" Eigenschaften wie "IntegerProperty" verwenden. Viertens sollten Sie 'ObservableList' verwenden, das mit' FXCollections.observableArrayList (Callback Extractor) instanziiert wird '. –
Jai
@sillyfly Entschuldigung wegen des Fehlers ... Ich habe die MemberSubscriptions-Klasse aktualisiert. –