JavaFX: Füllen Sie TableView mit einer ObservableMap mit einer benutzerdefinierten Klasse für ihre Werte

Ich habe die folgende ObservableMap, die ich in einem @ anzeigen möchTableView:

private ObservableMap<String, Shape> myShapes = FXCollections.observableHashMap();

WoShape ist wie folgt definiert:

public class Shape {

private StringProperty areaFormula = new SimpleStringProperty();
private IntegerProperty numSides = new SimpleIntegerProperty();

public Shape(String areaFormula, int numSides)
{
    this.areaFormula.set(areaFormula);
    this.numSides.set(numSides);
}

public String getAreaFormula() { return areaFormula.get(); }

public void setAreaFormula(String areaFormula) { this.areaFormula.set(areaFormula); }

public StringProperty areaFormulaProperty() { return this.areaFormula; }

public int getNumSides() { return numSides.get(); }

public void setNumSides(int sides) { this.numSides.set(sides); }

public IntegerProperty numSidesProperty() { return this.numSides; }
}

Ich möchte, dass die erste Spalte der TableView der Map Key ist (call itkey), die zweite Spalte istmyShapes.get(key).getAreaFormula() und die dritte Spalte istmyShapes.get(key).getnumSides(). Und ich möchte, dass die TableView automatisch aktualisiert wird, wenn die Map geändert wird.

Es wäre auch sehr schön, die zweite und dritte Spalte des @ zu machTableView Kann vom Benutzer bearbeitet werden, wenn dies möglich ist, wobei diese Änderungen in der Karte aktualisiert werden.

Ich habe stackoverflow bereits gefragt, ob eine TableView mit einer ObservableMap gefüllt werden soll, damit diese bei Änderungen hier aktualisiert wird:Auffüllen einer TableView mit einer HashMap, die aktualisiert wird, wenn sich die HashMap ändert. Wie Sie jedoch in der Diskussion dort sehen können, wird eine benutzerdefinierte Klasse nicht wie hier behandelt.

Hier ist meine Lösung bisher:

        ObservableMap<String, Shape> map = FXCollections.observableHashMap();

        ObservableList<String> keys = FXCollections.observableArrayList();

        map.addListener((MapChangeListener.Change<? extends String, ? extends Shape> change) -> {
            boolean removed = change.wasRemoved();
            if (removed != change.wasAdded()) {
                // no put for existing key
                if (removed) {
                    keys.remove(change.getKey());
                } else {
                    keys.add(change.getKey());
                }
            }
        });

        map.put("square", new Shape("L^2", 4));
        map.put("rectangle", new Shape("LW", 4));
        map.put("triangle", new Shape("0.5HB", 3));

        final TableView<String> table = new TableView<>(keys);

        TableColumn<String, String> column1 = new TableColumn<>("Key");

        column1.setCellValueFactory(cd -> Bindings.createStringBinding(() -> cd.getValue()));

        TableColumn<String, String> column2 = new TableColumn<>("Value");

        column2.setCellValueFactory( ... );

        table.getColumns().setAll(column1, column2);

Der Ort, an dem ich stecke, ist die vorletzte Zeilecolumn2.setCellValueFactory( ... ). Ich würde gernecolumn2, um das @ anzuzeigShape 'sgetAreaFormula() SimpleStringProperty aber ich weiß nicht, wie ich das @ einrichten soCellValueFactory dazu.

Danke für Ihre Hilfe

Antworten auf die Frage(2)

Ihre Antwort auf die Frage