JavaFX mvvmfx - Model

Bela B.

Aktives Mitglied
Hallo zusammen,

ich baue gerade meine Software mit mvvmfx, aber bin mir unsicher, wie ich denn das Model an die/das ViewModel binde.

Was macht mein Programm: Ich will damit meine Offsite-Backups meiner Mediendateien verwalten. Diese sind ausgelagert, d.h. ich erstelle von meiner Live-Version eine JSON, die ich dann, wenn ich zu meinem Offsite-Backup fahre, lade ich dann die JSON und lasse mir die Diff zu dem Backupstand ausgeben.
Das funktioniert alles soweit. Dafür habe ich einige Klassen (wie z.B. Movie, TV-Show, Video) und erstelle mir damit dann Collections, die ich dann in die JSON über GSON ausleite.

Ohne GUI habe ich es soweit lauffähig, aber ich kapiere einfach nicht so recht, wie und wo ich nun die Verbindung zu den ViewModels machen soll.
mvvmfx bietet ja den ModelWrapper an, aber was gebe ich da an? Kennt jemand eine Beispielanwendung, die nicht all zu kompliziert ist, aber mit mvvmfx ein Model mit mehreren Klassen hat? Bisher habe ich immer welche gefunden, bei denen dann das Model immer nur aus einer Klasse z.B. Person oder Task oder Meeting bestand. (das wäre dann ja gleichbedeutend, wenn ich nur eine Klasse Video z.B. hätte).

Vielen Dank, komme da überhaupt nicht weiter.
 
Wie sieht denn deine Klassenstruktur aus und was willst du anzeigen? Gib einen View und deine Daten vor und dann kann man zeigen, wie du das Binding machst.

Im Grunde besteht dein ViewModel einfach aus Properties, die mit dem View über Bindings verbunden werden. Im ViewModel hast du eine Methode, die im einfachsten Fall ein Model entgegennimmt und die Werte auf die Properties setzt.
 
Wie sieht denn deine Klassenstruktur aus und was willst du anzeigen? Gib einen View und deine Daten vor und dann kann man zeigen, wie du das Binding machst.
Ich habe z.B. eine Klasse Video, die folgende Attribute hat:
Java:
public class Video {
    private static final Logger LOGGER = LoggerFactory.getLogger(Video.class.getName());

    private UUID id;
    private String user;
    private String name;
    private File path;
    private String hash;
    private long size;

//[...weitere Methoden, z.B. zur Ermittlung der Größe der Datei um size zu setzen]
}
Diese Klasse befindet sich in einem Package namens media. Bisher habe ich in meiner Main-Methode als nun über ein Verzeichnis iteriert und dabei für jedes Unterverzeichnis (=> Videoverzeichnis) ein neues Objekt davon erzeugt und in einer Collection<Video> videoList = new ArrayList() abgelegt.

Diese Collection will ich dann in einem TreeTableView anzeigen. Die View dazu liegt in einem Package ui, also dann eine RootView.class und eine RootViewModel.class und bei den Resources entsprechend auch mit Package-Struktur die RootView.fxml.

Meine Frage jetzt hier zu: Wo mache ich denn jetzt am besten das Iterieren über das Verzeichnis zur Erzeugen der Collection<Video> und wie funktioniert dann das Binding?
Bis habe ich mich nur etwas mit dem Property-Binding bei Standardtypen (wie String, Integer, ...) beschäftigt, aber habe noch keine Ahnung, wie ich eine Collection oder ähnliches binde.
 
Meine Frage jetzt hier zu: Wo mache ich denn jetzt am besten das Iterieren über das Verzeichnis zur Erzeugen der Collection<Video> und wie funktioniert dann das Binding?
Bis habe ich mich nur etwas mit dem Property-Binding bei Standardtypen (wie String, Integer, ...) beschäftigt, aber habe noch keine Ahnung, wie ich eine Collection oder ähnliches binde.
Dein TreeTableView hält Instanzen von z.B. "VideoItemViewModel". Mit der CellValueFactory machst du das Mapping zwischen View und ViewModel.
Java:
@FXML private TreeTableColumn<VideoItemViewModel, String> uuidCol;
...
uuidCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("uuid"));
Dein ViewModel ist wirklich ganz einfach:
Java:
public class VideoItemViewModel implements ViewModel  {

    private final StringProperty uuid = new SimpleStringProperty(this,"uuid");
    private final StringProperty name = new SimpleStringProperty(this, "name");
    private final StringProperty user = new SimpleStringProperty(this, "user");
    ...

    public VideoItemViewModel(Video video) {
        uuid.set(video.getId().toString());
        name.set(video.getName());
        user.set(video.getUser());
    }

    public StringProperty uuidProperty() {
        return uuid;
    }

    public StringProperty nameProperty() {
        return name;
    }

    public StringProperty userProperty() {
        return user;
    }
}
Dem TreeTableView gibst du ja nur ein root TreeItem<T> und die Kinder sind einem Item/einer Node immer bekannt. Du musst also über die TreeItem<T> Klasse einen Weg finden deine VideoItemViewModel pro Video zu erzeugen.
Auf Anhieb habe ich dazu eine Klasse gefunden, vom Maintainer von mvvmFX: https://gist.github.com/lestard/011e9ed4433f9eb791a8

Du liest dein Verzeichnis mit Unterverzeichnissen rekursiv ein und packst deine Videos in einen Baum. Der RecursiveTreeItem holt sich dann immer die Kindelemente und mappt sie zu ViewItems.
 

Zurück
Oben