JavaFX TableView und ObservableList - Wie aktualisiere ich die Tabelle automatisch?

Ich weiß, dass ähnliche Fragen gestellt wurden, und zwar zu verschiedenen Terminen, aber ich werde hier eine SSCCE eintragen und versuchen, dies einfach zu stellen.

Ich möchte in der Lage sein, das Datenmodell zu aktualisieren und alle Ansichten darauf automatisch aktualisieren zu lassen, sodass jedem Aufrufer, der das Modell aktualisiert, nicht bekannt ist, welche Ansichten derzeit vorliegen. Dies ist, was ich bisher gelernt / versucht habe, und ohne @ anzurufTableView.refresh() es wird nicht aktualisiert. Was vermisse ich

main.java:

package application;

import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;

public class Main extends Application {
    @Override
    public void start(Stage stage) {

        // data
        ObservableList<Crew> data = FXCollections.observableArrayList();
        data.addAll(new Crew(1, "A"), new Crew(2, "B"));

        // table
        TableColumn<Crew, Integer> crewIdCol = new TableColumn<Crew, Integer>("Crew ID");
        crewIdCol.setCellValueFactory(new PropertyValueFactory<Crew, Integer>("crewId"));
        crewIdCol.setMinWidth(120);
        TableColumn<Crew, String> crewNameCol = new TableColumn<Crew, String>("Crew Name");
        crewNameCol.setCellValueFactory(new PropertyValueFactory<Crew, String>("crewName"));
        crewNameCol.setMinWidth(180);
        TableView<Crew> table = new TableView<Crew>(data);
        table.getColumns().addAll(crewIdCol, crewNameCol);
        table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        // button
        Button button = new Button(" test ");
        button.setOnAction(ae -> {
            // test
            StringProperty nameProp = data.get(0).crewName();
            if(nameProp.get().equals("A")) {
                data.get(0).setCrewName("foo");
                // table.refresh();
                System.out.println("foo");
            } else {
                data.get(0).setCrewName("A");
                // table.refresh();
                System.out.println("A");
            }
        });

        VBox box = new VBox(10);
        box.setAlignment(Pos.CENTER);;
        box.getChildren().addAll(table, button); 
        Scene scene = new Scene(box);
        stage.setScene(scene);
        stage.show();
    }

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

}

Crew.java

package application;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Crew {
    private final IntegerProperty crewId = new SimpleIntegerProperty();
    private final StringProperty crewName = new SimpleStringProperty();

    Crew(int id, String name) {
        crewId.set(id);
        crewName.set(name);
    }

    public IntegerProperty crewId() { return crewId; }
    public final int getCrewId() { return crewId.get(); }
    public final void setCrewId(int id) { crewId.set(id); }

    public StringProperty crewName() { return crewName; }
    public final String getCrewName() { return crewName.get(); }
    public final void setCrewName(String name) { crewName.set(name); }

}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage