Programmeinstellungen für Anwendung??

Bitte aktiviere JavaScript!
Methoden zur Verarbeitung von Werten kommen weiterhin in das Modell!
Der View ruft Methoden aus dem ViewModel auf, wenn Aktionen auftreten wie Button gedrückt. Das ViewModel entscheidet was passieren soll, wenn die Methode aufgerufen wurde. Beispielsweise führst du im ViewModel eine Validierung durch, setzt eine Fehlerproperty, die dafür sorgt, dass im View der Fehler sichtbar wird oder rufst letztlich eine Methode aus dem Modell auf.
Das Serialisieren der Werte wird dann nur mit dem Modell durchgeführt, also dort implements Serializable?
Ja
Habe dann mal unter ViewModel im Netz nachgesehen und da tauchte dann das Konzept des MVVM auf
Ja, es handelt sich im groben um das Konzept. Da ich nicht alle Nuancen kenne und damit sicher nicht einhalte bezeichne ich mein Beispiel aber nicht als MVVM Beispiel.
Wie du die Klassen zusammenpackst ist Geschmackssache. Kommt auch drauf an, ob du ein Master-Detail UI hast, ein Form auslagerst, welches du in View, Update und Edit einbindest oder nur über Button navigierst und jedes mal ein neues Fenster öffnest. Für sowas kleines reicht vermutlich die Struktur
in src
proj.Application.java
proj.model.Einstellungen.java
proj.ui.einstellungen.EinstellungenView.java
proj.ui.einstellungen.EinstellungenViewModel.java
und in resources
proj.ui.einstellungen.EinstellungenView.fxml
proj.ui.einstellungen.style.css
 
Das minimale Beispiel mit der Serveradresse habe ich jetzt mal in mein Projekt mit Dateien übertragen.
Es funktioniert zwar soweit, aber die Abwicklung hat sich mir noch nicht so ganz erschlossen.
Ich Dokumentiere zwar sehr viel, das ist aber erstmal ein Hilfmittel für mich um es besser zu verstehen.

Auszug der Klasse Einstellungen (Java-Standardlib)
Java:
private String pfadQuelle;
private String pfadZiel;

// Methode für das einsetzen von Standard Werten
    public static Einstellungen standardWerte() {
        String heimVerzeichnis = System.getProperty("user.home");
        // return new Einstellungen().schreibePfadQuelle(homeVerzeichnis+"\\Dateien\\01 Quelle");
        Einstellungen standardWerte = new Einstellungen();
        standardWerte.schreibePfadQuelle(heimVerzeichnis+"\\Dateien\\01 Quelle");
        standardWerte.schreibePfadZiel(heimVerzeichnis+"\\Dateien\\02 Ziel");    
        return standardWerte;
    } // Methode für das einsetzen von Standard Werten

public String holePfadQuelle() {
        return pfadQuelle;
    }
   
    public Einstellungen schreibePfadQuelle(final String quellVerzeichnis) {
        pfadQuelle = quellVerzeichnis;
        return this;
    }
   
    public String holePfadZiel() {
        return pfadZiel;
    }

    public void schreibePfadZiel(String zielVerzeichnis) {
        pfadQuelle = zielVerzeichnis;
    }
Jedoch habe ich Schwierigkeiten zu verstehen warum bei der schreibePfadQuelle der Datentp Einstellungen gewählt wurde?
Es wird doch nur den Pfad der einen String enthält zurück gegeben!
Normalerweise definiere ich so wie bei schreibePfadZiel eine Methode die nichts zurückgibt mit "void" bei einer Set-Methode?

Auszug der Klasse EinstellungenFM (ViewModell)
Java:
private final StringProperty pfadQuelle = new SimpleStringProperty();
private final StringProperty pfadZiel = new SimpleStringProperty();

// Erstellt das Einstellungen Fenster Modell
    public EinstellungenFM(Einstellungen einstellungen){
        pfadQuelle.set(einstellungen.holePfadQuelle());
        pfadZiel.set(einstellungen.holePfadZiel());
    }

public String holePfadQuelle() {
        return pfadQuelle.get();
    }
   
    public StringProperty pfadQuelleProperty() {
        return pfadQuelle;
    }
   
    public void schreibePfadQuelle(final String pfadQuelle) {
        this.pfadQuelle.set(pfadQuelle);
    }
   
    public StringProperty holePfadZiel() {
        return pfadZiel;
    }
    public StringProperty pfadZielProperty() {
        return pfadZiel;
    }

    public void schreibePfadZiel(String zielVerzeichnis) {
        pfadQuelle.set(zielVerzeichnis);
    }
Bei EinstellungenFM wird ein Kosntruktor aufgerufen der einen Parameter einstellungen enthält.
Ich denke mal hier wird ein Objekt Erzeugtder aus dem Bauplan von Einstellungen der Standardlib erzeugt wird und direkt Werte zugewiesen bekommt. Zu diesem Zeitpunkt ist mir nicht bekannt, ob sich bereit Werte darin enthalten? Ich denke nicht, da die Methode standardWerte() noch nicht aufgerufen wurde?
Ich verstehe aber schon das im ViewModell alles enthalten sein soll was für den Fensteraufbau und deren verhalten notwendig ist.

Auszug der Klasse EinstellungenFK (ViewController)
Java:
@FXML
private Label lblQuellverzeichnis;
@FXML
private Label lblZielverzeichnis;

private EinstellungenFM fensterModell;

// Konstruktor um das Fenstermodell zu erzeugen
    public EinstellungenFK() {
        // Laedt die Standardwerte aus dem Modell
        Einstellungen einstellungen = Einstellungen.standardWerte();
        // Erstellt das Modell des Fenstermodells
        this.fensterModell = new EinstellungenFM(einstellungen);
    } // Konstruktor um das Fenstermodell zu erzeugen

public void initialize(URL url, ResourceBundle rb) {
        LOG.info("Einstellungen werden initialisiert");
        lblQuellverzeichnis.textProperty().bind(fensterModell.pfadQuelleProperty());
    } // initialize

@FXML
    private void sucheQuellverzeichnis(ActionEvent event) {
        LOG.info("sucheQuellverzeichnis wurde aufgerufen");
        String verzeichnis = Datei.auswahlVerzeichnis("Wähle das Quellverzeichnis");
        fensterModell.schreibePfadQuelle(verzeichnis);
        lblQuellverzeichnis.textProperty().bind(fensterModell.pfadQuelleProperty());
        LOG.info("Selektiertes Quellverzeichnis " + fensterModell.holePfadQuelle());
    } // sucheQuellverzeichnis

    @FXML
    private void sucheZielverzeichnis(ActionEvent event) {
        LOG.info("sucheZiellverzeichnis wurde aufgerufen");
        String verzeichnis = Datei.auswahlVerzeichnis("Wähle das Zielverzeichnis");
        fensterModell.schreibePfadZiel(verzeichnis);
        lblZielverzeichnis.textProperty().bind(fensterModell.pfadZielProperty());
        LOG.info("Selektiertes Zielverzeichnis " + fensterModell.pfadZielProperty());
    } // sucheZielverzeichnis
Der Fenster Kontroller soll also nur die Daten vom Modell zum Fenster verbinden.
Also wird EinstellungenFM mit der variable fensterModell definiert, welche dann im Konstruktor irgendwie gefüllt werden?
Der Konstruktor so wie er da ist verstehe ich nicht so ganz. Ich weiß das dort durch die Methode die Pfade gesetzt werden.
Es wird ein Objekt einstellungen erzeugt und dort die die Werte übergeben.
Aber einstellungen wird doch nach dem Bauplan erzeugt. Wird in diesem Objekt tatsächlich Quellverzeichnis und Zielverzeichnis in den entsprechenden Platzhalter erzeugt und übergeben so wie es in der Vorgabe definiert wurde?

Wenn ich mein Programm mit beiden Daten (Quellverzeichnis und Zielverzeichnis) ausführe dann erhalte ich im Textfeld des Fensters nur den letzten also Zielverzeichnis.
Im label Quellverzeichnis wird der Pfad des Zielverzeichnisses angezeigt und im label Zielverzeichnis nichts.
 
Jedoch habe ich Schwierigkeiten zu verstehen warum bei der schreibePfadQuelle der Datentp Einstellungen gewählt wurde?
Es wird doch nur den Pfad der einen String enthält zurück gegeben!
Normalerweise definiere ich so wie bei schreibePfadZiel eine Methode die nichts zurückgibt mit "void" bei einer Set-Methode?
Ich habe hier bloß "fluent-Setter" benutzt (z.B. hier erklärt).
Zu diesem Zeitpunkt ist mir nicht bekannt, ob sich bereit Werte darin enthalten? Ich denke nicht, da die Methode standardWerte() noch nicht aufgerufen wurde?
Du gibst doch in den Konstruktor des ViewModels ein Einstellungs-Objekt rein, welches im Kontroller erzeugt wurde:
public EinstellungenFK() { // Laedt die Standardwerte aus dem Modell Einstellungen einstellungen = Einstellungen.standardWerte(); // Erstellt das Modell des Fenstermodells this.fensterModell = new EinstellungenFM(einstellungen); } // Konstruktor um das Fenstermodell zu erzeugen
standardWerte wurde zu dem Zeitpunkt aufgerufen, und das Einstellungs-Objekt auf die Werte gesetzt, die in standardWerte gesetzt werden. Das natürlich nur für dieses minimale Beispiel. Später liest du die Einstellungen aus einer Datei oder Properties (java.util).
Aber einstellungen wird doch nach dem Bauplan erzeugt. Wird in diesem Objekt tatsächlich Quellverzeichnis und Zielverzeichnis in den entsprechenden Platzhalter erzeugt und übergeben so wie es in der Vorgabe definiert wurde?
Auch hier: Es wird das gesetzt, was in standardWerte definiert ist.

Wenn ich mein Programm mit beiden Daten (Quellverzeichnis und Zielverzeichnis) ausführe dann erhalte ich im Textfeld des Fensters nur den letzten also Zielverzeichnis.
Du hast im Konstruktor nur eins von zwei Textfeldern gebunden und bindest in den Action-Handlern erneut Properties.
Die Bindings erledigst du ausschließlich im Konstruktor.
In den Action-Handlern setzt du die neuen Verzeichnispfade im ViewModel über die Setter ( schreibePfadZiel usw. ) und der View aktualisiert sich aufgrund der Bindings selbstständig.
 
Ich hab es mir jetzt noch mal angeschaut und bin ein bisschen durcheinander.
Vielleicht hat jemand Zeit in form einer Nachhilfestunde mir das an meinem Code über Teamviever zu erklären.
Ich bin auch gerne bereit die Stunde zu bezahlen, bitte einfach eine PN senden.
 
Mittlerweile habe ich es geschafft alle Werte in der Methode standardWerte() zu definieren und in das ViewModel zu transferieren und werden auch dort im Fenster angezeigt. Im Fenster kann ich durch meine Button Methoden die Verzeichnisse ändern und durch Logeinträge konnte ich kontrollieren, das die neuen Pfade auch tatsächlich im VielModell enthalten sind.

Ich weiß jetzt wie es in etwa funktionieren sollte, aber es herrscht bei mir immer noch in den ein oder anderen Punkten Unklarheiten.
Wobei im MVC auf ein Muster mit Model, View und Controller beschrieben wird, kann es für JavaFX anwendungen so nicht verwendet werden. Zumindest habe ich das jetzt so interpretiert, da die Properties nicht Model platziert werden können, wenn es auch um Persistente Speicherung der Modell-Daten geht?!?
Beim MVVM basiert der Entwurf auf ein Model, VieModel und der View. Hier im Forum habe ich jetzt gelernt zu diesem Entwurf noch einen ViewContoller hinzu zu nehmen der nur die Bindung übernimmt. Das macht es etwas übersichtlicher. So wie ich es auf der Wikipedia Seite gelesen habe, aber nicht nötig, da die Bindung, die Steuerung und Geschäftslogik im ViewController sein darf.
Mittlerweile habe ich aus dem Netz, aus Büchern und Tutorials unterschiedliche Informationen. Ich tue mich ein bisschen schwer damit um zu gehen, weil ich noch keine Erfahrung in GUI Programmierung gemacht habe und erst mit dieser Beispielapplikation damit angefangen habe.

Ich weiß jetzt, daß die View (Fenster) durch die Property Bindung im Controller mit dem ViewModel verbunden ist und jede Eingabe im Textfield automatisch aktualisiert wird. Jedoch ist mir nicht klar wie dann die Aktualisierung mit dem Modell der Standardlib in der ich implements Serializable verwendet habe?

Schließlich möchte ich die gesamten Daten im Einstellungen Fenster gerne auf Festplatte permanent speichern.
Um den Ablauf besser zu verstehen, habe ich mir einen kleine Hilfe erstellt.
Einstellungen.png
Ich habe Schwierigkeiten zu verstehen, wie ich die Daten Serialisieren kann, da ich nicht verstehe, wie die Daten aus dem ViewModel in mit dem Modell abgeglichen werden.
 
Zuletzt bearbeitet:
Wobei im MVC auf ein Muster mit Model, View und Controller beschrieben wird, kann es für JavaFX anwendungen so nicht verwendet werden. Zumindest habe ich das jetzt so interpretiert, da die Properties nicht Model platziert werden können, wenn es auch um Persistente Speicherung der Modell-Daten geht?!?
Doch, kann man schon machen, aber gibt halt Wildwuchs, in meinen Augen. Ich rate davon ab und bin für eine Trennung. MVVM bekommt diese Trennung in meinen Augen am leichtesten hin.

So wie ich es auf der Wikipedia Seite gelesen habe, aber nicht nötig, da die Bindung, die Steuerung und Geschäftslogik im ViewController sein darf.
Also alles in den ViewController? Das ist ja Quatsch. Das ViewModel enthält die Logik für die Darstellung und delegiert an das Model für die Geschäftslogik. Der einzige Job des (View)Controllers ist es die in MVVM zentrale Rolle des Binders einzunehmen und die Action Handler zu definieren, die wiederum nur an das ViewModel delegieren. Der Binder stellt die Bindings zwischen View und ViewModel her. Dank der Properties in JavaFX hat der Binder nicht viel zutun als eine Property des View mit der zugehörigen Property des ViewModels zu verbinden. Hätten wir keine Properties, würden wir im Binder vermutlich das Oberserver-Pattern nutzen und manuell Änderungen durch Listener mappen. Ich will mir gar nicht vorstellen, wie hässlich das im Vergleich wäre.
Ein View ist erstmal kein Fenster. Du kannst z.B. mehrere Instanzen eines Views im gleichen Fenster anzeigen. FensterModell ist deshalb auch keine gute Übersetzung, fällt mir auf.
Jedoch ist mir nicht klar wie dann die Aktualisierung mit dem Modell der Standardlib in der ich implements Serializable verwendet habe?
Du definierst in deiner View eine Action (z.B. Klick auf Button 'Speichern'), dazu definierst du einen Action-Handler im Controller. Der Controller delegiert die Action an das ViewModel. Das ViewModel validiert nun die Anfrage in Kooperation mit dem Modell. Beispielsweise wenn auf Speichern geklickt wurde sollen doch bitte alle Felder ausgefüllt sein. Falls ok: Speichern, falls nicht ok: nicht Speichern. Je nach Validierungsergebnis werden
  1. die Werte des ViewModels in das Modell übertragen
  2. die Geschäftslogik des Models aufgerufen (speichern) bzw. wird das Modell an einen für die Persistierung zuständigen Service weitergegeben
  3. Properties aktualisiert (z.B. eine Fehler-Property oder "Alles OK und erfolgreich gespeichert")
Deine Grafik, kann ich leider nicht ganz deuten. Die Pfeile sind nicht definiert und ein Pfeil ist orange(?). Manche Pfeile gehen in eine Richtung und manche in zwei.
Ich habe Schwierigkeiten zu verstehen, wie ich die Daten Serialisieren kann, da ich nicht verstehe, wie die Daten aus dem ViewModel in mit dem Modell abgeglichen werden.
Das habe ich nun beantwortet. Ab da musst du nur noch das Schreiben und Lesen in ein File anstoßen.
 
Mit der Grafik habe ich mir einen überblick verschafft, was passiert nachdem das JavaFX Programm ausgeführt wird.
Wie gesagt, ist JavaFX und die GUI Programmierung für mich neu.
Linien mit Doppelpfeilen sollen veranschaulichen, das die Daten hin und zurück gehen.
Der Roten Linien war das wo ich nicht wie es geregelt wird damit das Model die Daten vom VielModell aktualisiert.
Du hast mir gesagt, des es im Speicher Button passiert. Also Dort muss ich alle Variablen vom Modell Viel auf das Model übertragen und dann das Modell Speichern.

Ich werde den Button Code posten wenn ich es fertig habe.
 
Der Code für den Button speichern, indem ich einen Variableninhalt von einem Modell in das andere Kopiere und einen Logeintrag mit dem Wert erzeuge und dann das Modell auf Festplatte Speichern.

Java:
public static void schreibeEinstellungenHD(Einstellungen einstellungen) {
        OutputStream ausgabeStreamDatei = null;
        try {
            ausgabeStreamDatei = new FileOutputStream(einstellungen.holePfadEinstellungen()+"\\Einstellungen.ser");
            ObjectOutputStream ausgabeStreamObjekt = new ObjectOutputStream(ausgabeStreamDatei);
            ausgabeStreamObjekt.writeObject(einstellungen);
            ausgabeStreamDatei.close();
            LOG.info("Einstellungen wurden auf Festplatte gespeichert");
        } catch (Exception e) {
            LOG.info("Es trat ein Fehler beim schreiben der Programmeinstellungen auf", e);
        }
    } // schreibeEinstellungenHD

Java:
@FXML
    private void einstellungenSpeichern(ActionEvent event) throws IOException {
        LOG.info("Methode einstellungenSpeichern wurde aufgerufen");
        // Alle gemachten Einstellungen werden dauerhaft gespeichert
        einstellungen.schreibePfadQuelle(fensterModell.holePfadQuelle());
        LOG.info("Modell Einstellungen Pfad Quelle : " + einstellungen.holePfadQuelle());    
        Einstellungen.schreibeEinstellungenHD(einstellungen);
    } // einstellungenSpeichern
Der Code gibt in der Netbeans iDE keine Fehler an, erzeugt aber beim ausführen folgende Fehler in der Konsole.
Die Meldung ist ziemlich umfangreich, wenn man bedenkt, das ich nur eine Variablen von einem Model ins andere Modell kopiere und einen LOG ausgeben wollte.
Der Logeintrag wurde nicht erzeugt.
FXML Loader hat doch was mit dem Fenster zu tun?
Das Fenster wurde ordnungsgemäß erstellt und dargestellt, mit dem Speichern Button wird weder einen neues Fenster erzeugt oder dargestellt.

Code:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8865)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3876)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    ... 47 more
Caused by: java.lang.NullPointerException
    at einstellungen.EinstellungenFK.einstellungenSpeichern(EinstellungenFK.java:165)
    ... 58 more
 
Du bist im zweiten Code offensichtlich im Controller, hier solltest du die Einstellungen nicht anfassen. Alles geht über das ViewModel. Lies hierzu erneut:
Du definierst in deiner View eine Action (z.B. Klick auf Button 'Speichern'), dazu definierst du einen Action-Handler im Controller. Der Controller delegiert die Action an das ViewModel. Das ViewModel validiert nun die Anfrage in Kooperation mit dem Modell. Beispielsweise wenn auf Speichern geklickt wurde sollen doch bitte alle Felder ausgefüllt sein. Falls ok: Speichern, falls nicht ok: nicht Speichern. Je nach Validierungsergebnis werden
  1. die Werte des ViewModels in das Modell übertragen
  2. die Geschäftslogik des Models aufgerufen (speichern) bzw. wird das Modell an einen für die Persistierung zuständigen Service weitergegeben
  3. Properties aktualisiert (z.B. eine Fehler-Property oder "Alles OK und erfolgreich gespeichert")
Im Action Handler einstellungenSpeichern setzt du immer noch Bindings, die eigentlich nur im Konstruktor einmalig gesetzt werden sollen. Ich dachte das hatte ich im vorhergehenden Beiträgen schon bemängelt.

Eine NullPointerException deutet darauf hin, dass eins deiner Attribute null ist. Das kann leicht passieren, wenn man ein Feld anders als im FXML benennt, denn das Mapping passiert über den Namen. Ansonsten steht in der Exception explizit die Quelle des Übels ((EinstellungenFK.java:165)).
 
Aktuell habe ich noch ein Problem mit dem Binden der Textfelder im FensterKontroller.
Ich hatte bisher immer nur die Labels gebunden und das funktioniert auch soweit ganz gut.
Nun habe ich auch die TextFelder eingebunden (TextField) und ab dem Zeitpunkt kann ich keine Eingaben mehr im Fenster machen wenn das Programm läuft?

Auszug aus "EinstellungenFensterKontroller"
Java:
// Einstellungen Fenster Kontroller
@FXML
    private Label lblQuellverzeichnis;
    @FXML
    private Label lblZielverzeichnis;
    @FXML
    ...
    ...

    @FXML
    private TextField tfDBServeradresse;
    @FXML
    private TextField tfDBDatenbankname;
    @FXML
    private TextField tfDBBenutzername;
    @FXML
    private TextField tfDBPasswort;
    ...
    ...

    // Datenmodelle
    private EinstellungenFM fensterModell;
    private Einstellungen einstellungen;

    // Konstruktor um das Fenstermodell zu erzeugen
    public EinstellungenFK() {
        // Erzeugt ein Modell-Objekt Einstellungen mit Standardwerten
        this.einstellungen = Einstellungen.standardWerte();

        // Erzeugt ein Fenster-Modell aus dem Einstellungen Model-Objekt
        this.fensterModell = new EinstellungenFM(einstellungen);
    } // Konstruktor um das Fenstermodell zu erzeugen

    /**
     * Initialisierung der Kontroller Klasse.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        LOG.info("Einstellungen werden initialisiert");
        // Binden der Werte an das Fenster
        lblQuellverzeichnis.textProperty().bind(fensterModell.pfadQuelleProperty());
        lblZielverzeichnis.textProperty().bind(fensterModell.pfadZielProperty());
        ...
        ...
        tfDBServeradresse.textProperty().bind(fensterModell.dbServeradresseProperty());
        tfDBDatenbankname.textProperty().bind(fensterModell.dbDatenbanknameProperty());
        tfDBBenutzername.textProperty().bind(fensterModell.dbBenutzernameProperty());
        tfDBPasswort.textProperty().bind(fensterModell.dbPasswortProperty());
   } // initialize

...
@FXML
    private void einstellungenSpeichern(ActionEvent event) throws IOException {
        LOG.info("Methode einstellungenSpeichern wurde aufgerufen");
        EinstellungenFM.einstellungenSpeichernHD(fensterModell, einstellungen);
    } // einstellungenSpeichern
...
} // Einstellungen Fenster Kontroller
Auszug aus "Einstellungen Fenster Modell"
Java:
// Einstellungen Fenster Modell
...
    private final StringProperty pfadEinstellungen = new SimpleStringProperty();
    private final StringProperty pfadQuelle = new SimpleStringProperty();
    ...
    // Erstellt das Fenster Modell Einstellungen
    public EinstellungenFM(Einstellungen einstellungen) {
        // Holt die Werte aus den Variablen in das Fenster Modell
        pfadEinstellungen.set(einstellungen.holePfadEinstellungen());
        pfadQuelle.set(einstellungen.holePfadQuelle());
        ...
        dbServeradresse.set(einstellungen.holeDbServeradresse());
        dbDatenbankname.set(einstellungen.holeDbDatenbankname());
        dbBenutzername.set(einstellungen.holeDbBenutzername());
        dbPasswort.set(einstellungen.holeDbPasswort());
    } // Konstruktor Fenster Modell
   
        public static void einstellungenSpeichernHD(EinstellungenFM fensterModell, Einstellungen einstellungen) {
        einstellungen.schreibePfadQuelle(fensterModell.holePfadQuelle());
        ...
        einstellungen.schreibeDbServeradresse(fensterModell.holeDbServeradresse());
        einstellungen.schreibeDbDatenbankname(fensterModell.holeDbDatenbankname());
        einstellungen.schreibeDbBenutzername(fensterModell.holeDbBenutzername());
        ...      
        LOG.info("Modell Einstellungen Pfad Quelle : " + einstellungen.holePfadQuelle());
        LOG.info("Modell Einstellungen Pfad Ziel : " + einstellungen.holePfadZiel());
        ...      
        LOG.info("Modell Einstellungen DB Serveradresse : " + einstellungen.holeDbServeradresse());
        LOG.info("Modell Einstellungen DB Datenbankname : " + einstellungen.holeDbDatenbankname());
        LOG.info("Modell Einstellungen DB Benutzername : " + einstellungen.holeDbBenutzername());
        ...
        Einstellungen.schreibeEinstellungenHD(einstellungen);
    } // einstellungenSpeichernHD
   
     public String holePfadEinstellungen() {
        return pfadEinstellungen.get();
    }
   
    public StringProperty pfadEinstellungenProperty() {
        return pfadEinstellungen;
    }
   
    public void schreibePfadEinstellungen(String pfadEinstellungen) {
        this.pfadEinstellungen.set(pfadEinstellungen);
    }
    ...
Auszug aus Einstellungen
Java:
// Einstellungen
public class Einstellungen implements Serializable {

    private String pfadEinstellungen;
    private String pfadQuelle;
    ...
    private String dbServeradresse;
    private String dbDatenbankname;
    private String dbBenutzername;
    private String dbPasswort;
    ...
    // Methode für das einsetzen von Standard Werten
    public static Einstellungen standardWerte() {
        String heimVerzeichnis = System.getProperty("user.home");
        Einstellungen standardWerte = new Einstellungen();
        standardWerte.schreibePfadQuelle(heimVerzeichnis+"\\Dateien\\01 Quelle");
        standardWerte.schreibePfadZiel(heimVerzeichnis+"\\Dateien\\02 Ziel");  
        ...
        return standardWerte;
    } // Methode für das einsetzen von Standard Werten
   
public String holePfadQuelle() {
        return pfadQuelle;
    }
   
    public Einstellungen schreibePfadQuelle(String quellVerzeichnis) {
        this.pfadQuelle = quellVerzeichnis;
        return this;
    }
...
public static void schreibeEinstellungenHD(Einstellungen einstellungen) {
        OutputStream ausgabeStreamDatei = null;
        try {
            ausgabeStreamDatei = new FileOutputStream(einstellungen.holePfadEinstellungen()+"\\Einstellungen.ser");
            ObjectOutputStream ausgabeStreamObjekt = new ObjectOutputStream(ausgabeStreamDatei);
            ausgabeStreamObjekt.writeObject(einstellungen);
            ausgabeStreamDatei.close();
            LOG.info("Einstellungen wurden auf Festplatte gespeichert");
        } catch (Exception e) {
            LOG.info("Es trat ein Fehler beim schreiben der Programmeinstellungen auf", e);
        }
    } // schreibeEinstellungenHD
...
} // Einstellungen
Ich habe versucht die Aufgabe zu lösen wie looparda es beschrieben hat.
1. Eine Klasse Einstellungen erstellt mit allen benötigten Parameter im Standard Java
2. Ein Klasse EinstellungenFensterModell die im alle Parameter enthält wie in 1. nur das die Werte Getter und Setter in Properties definiert sind
3. Eine Klasse EinstellungenFensterKontroller der zum Binden des Fenster Modelles und dem Fenster dient.

Im FensterKontroller Konstruktor wird ein EinstellungenObjekt erstellt, welches die Standard Werte aus dem Konstruktor holt.
Weiter wird im Konstruktor ein FensterModell Objekt erstellt, welches auf dem EinstellungenObjekt Basiert.

In der Initialisierung des FensterKontrollers wird das Fenster mit dem FensterModell gebunden.
Wenn im Fenster auf Speichern geklickt wird, dann wird im FensterKontroller die Methode "EinstellungenSpeichern" ausgeführt, worin eine Methode ausgeführt wird die im FensterModell Klasse definiert wurde. Als Parameter werden die im FensterKontroller erzeugten Einstellungen Objekt und fensterModell Objekt übergeben.
In der Methode der FensterModell Klasse werden dann die Daten vom FensterModell in das Einstellungen Objekt übertragen, wobei dann noch die Methode "schreibeEinstellungenHD" ausgeführt wird mit dem Paramter des einstellungen objektes.
Die Methode ist definiert in der Klasse Einstellungen und schreibt dort das Objekt Einstellungen auf die Festplatte.

Aktuell funktioniert das noch nicht wirklich so, da erst mal das Problem des TextFields gelöst werden muss um keine leeren Datenobjekte zu haben.

Ich hoffe, das ich das ganze so richtig verstanden habe?
 
kann ich keine Eingaben mehr im Fenster machen wenn das Programm läuft?
Das Binding ist unidirektional. Benutze .bindBidirectional, um Änderungen in beide Richtungen zu ermöglichen - sorry, das hatte ich falsch in meinem Snippet vorgegeben.

EinstellungenFM.einstellungenSpeichernHD(fensterModell, einstellungen);
Du kannst im ViewModell ganz normal eine Methode anbieten, denn im ViewModel hast du die benötigten Objekte einstellungen und den Zustand des ViewModell selbst - also keine Notwenigkeit static zu nutzen. viewmodel.einstellungenSpeichernHD();

Die Implementierung von einstellungenSpeichernHD wiederum gehört dort nicht rein sondern in das Model oder einen externen Service. Lies dazu erneut:
Der View ruft Methoden aus dem ViewModel auf, wenn Aktionen auftreten wie Button gedrückt. Das ViewModel entscheidet was passieren soll, wenn die Methode aufgerufen wurde. Beispielsweise führst du im ViewModel eine Validierung durch, setzt eine Fehlerproperty, die dafür sorgt, dass im View der Fehler sichtbar wird. [Dann mappst du das ViewModel ins Model] und rufst letztlich eine Methode aus dem Modell [oder einen Service zum Speichern] auf.
Ich habe die Implementierungen jetzt nicht genau gelesen sondern bin eher über den Datenfluss und die Struktur geflogen. Ansonsten sieht das jetzt schon viel besser aus!
 
Vielen Dank, das hat jetzt funktioniert.
Bei den Labels ging es Unidirektional weil ich direkt in das Modell geschrieben habe, was sich im Label aktualisiert hat.
Bei den Textfeldern hat Bidirektional gut funktioniert.
Auch die Datei "Einstellungen.ser" wurde ohne Fehlermeldungen in einem geänderten Pfad geschrieben.

Ich muss mich jetzt noch mal für die tolle Unterstützung bedanken, sowas als Beispiel habe ich nirgendwo finden können und bin froh das es jetzt funktioniert. Auch gelernt habe ich super viel davon und sehe das es nicht so ganz easy ist.

Morgen mache ich mich ran die Datei zu lesen.
Jetzt habe ich einen funktionierenden Einstellungen Dialog in dem Standardverzeichnisse enthalten sind, die ich sogar ändern kann und Eingaben durch Textfelder. Die Daten werden jetzt zwar auf Festplatte gespeichert, aber wie mache ich dann all die Daten im gesamten Programm verfügbar?
Gebe ich das Einstellungen Objekt jetzt Klasse für Klasse weiter?
Lade ich es von Festplatte wenn ich Daten davon Benötige?
 
Die Daten werden jetzt zwar auf Festplatte gespeichert, aber wie mache ich dann all die Daten im gesamten Programm verfügbar?
Eine Möglichkeit ist es die Einstellungen bei Programmstart einzulesen und sicherzustellen, dass es im gesamten Verlauf nur ein einziges Objekt davon gibt (Umsetzung mit Singleton-Pattern), welches global überall zugreifbar ist. Das erzeugt jedoch eine hohe Kopplung zwischen der Einstellungen-Klasse und den Klassen, wo sie genutzt wird. Es verhindert gut testbaren Code zu schreiben. Ich bin mir unsicher, ob ich dir wirklich zum Singleton raten sollte.
So lange du an keine Grenzen stößt würde ich es verwenden. Spätestens wenn du dich ernsthaft mit Testen auseinandersetzt fällt es dir auf die Füße und du wirst nach Alternativen suchen.

Eine Alternative dazu wäre erstmal ein Interface für die Einstellungen einzuführen, um die Kopplung zu lösen (Dependency Inversion) und die Einstellungen (von einem Dependency Injection Framework erzeugen lassen oder selbst erzeugen) und in die abhängigen Klassen zu injecten (Dependency Injection).
Weiterhin würde man dann versuchen die Einstellungen in verschiedene Sichten aufzusplitten (z.B. Pfade, Datenbankeinstellungen, Sicherheitseinstellungen) (Interface segregation principle), um die Kopplung weiter zu verringern.
Hier wird es erst richtig spannend und da lerne selbst noch ständig dazu. Mich würden auch andere Alternative oder Meinungen zum Singleton interessieren.
 
Aktuell bin ich jetzt dabei die Programmeinstellungen zu laden.
Ich habe im Einstellungen Fenster einen Lade Button platziert der beim Drücken die Einstellungen von der Festplatte laden soll.
Da beim Aufruf des Einstellungen Fenster alles Standardwerte geladen werden kann ich beim drücken vom Lade Button sehen ob die Funktion korrekt arbeitet, denn dann müssten sich die Pfade ändern.
Der Lade Button wird später entfernt da ich dann beim Programmstart die Einstellungen automatisch von Festplatte laden möchte, wenn die Einstellungen Datei existiert.

Die aktuelle Fehlermeldung beim Laden
Code:
INFO  einstellungen.Einstellungen - Es trat ein Fehler beim laden der Einstellungen auf
java.lang.ClassCastException: einstellungen.Einstellungen cannot be cast to einstellungen.EinstellungenFM
    at einstellungen.Einstellungen.ladeEinstellungenHD(Einstellungen.java:207) ~[DMS.jar:1.0]
    at einstellungen.EinstellungenFM.einstellungenLadenHD(EinstellungenFM.java:93) ~[DMS.jar:1.0]
    at einstellungen.EinstellungenFK.einstellungenLaden(EinstellungenFK.java:176) ~[DMS.jar:1.0]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76) ~[javafx.base:?]
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:564) ~[?:?]
    at com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275) ~[javafx.base:?]
    at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83) ~[javafx.fxml:?]
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782) ~[javafx.fxml:?]
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670) ~[javafx.fxml:?]
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) ~[javafx.base:?]
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) ~[javafx.base:?]
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) ~[javafx.base:?]
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) ~[javafx.base:?]
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) ~[javafx.base:?]
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) ~[javafx.base:?]
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) ~[javafx.base:?]
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) ~[javafx.base:?]
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) ~[javafx.base:?]
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) ~[javafx.base:?]
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) ~[javafx.base:?]
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) ~[javafx.base:?]
    at javafx.event.Event.fireEvent(Event.java:198) ~[javafx.base:?]
    at javafx.scene.Node.fireEvent(Node.java:8865) ~[javafx.graphics:?]
    at javafx.scene.control.Button.fire(Button.java:200) ~[javafx.controls:?]
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206) ~[javafx.controls:?]
    at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274) ~[javafx.controls:?]
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) ~[javafx.base:?]
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) ~[javafx.base:?]
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) ~[javafx.base:?]
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) ~[javafx.base:?]
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) ~[javafx.base:?]
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) ~[javafx.base:?]
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) ~[javafx.base:?]
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) ~[javafx.base:?]
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) ~[javafx.base:?]
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) ~[javafx.base:?]
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) ~[javafx.base:?]
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) ~[javafx.base:?]
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) ~[javafx.base:?]
    at javafx.event.Event.fireEvent(Event.java:198) ~[javafx.base:?]
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3876) ~[javafx.graphics:?]
    at javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604) ~[javafx.graphics:?]
    at javafx.scene.Scene.processMouseEvent(Scene.java:1874) ~[javafx.graphics:?]
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613) ~[javafx.graphics:?]
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397) ~[javafx.graphics:?]
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295) ~[javafx.graphics:?]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434) ~[javafx.graphics:?]
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) ~[javafx.graphics:?]
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433) ~[javafx.graphics:?]
    at com.sun.glass.ui.View.handleMouseEvent(View.java:556) ~[javafx.graphics:?]
    at com.sun.glass.ui.View.notifyMouse(View.java:942) ~[javafx.graphics:?]
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) ~[javafx.graphics:?]
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175) ~[javafx.graphics:?]
    at java.lang.Thread.run(Thread.java:844) [?:?]
INFO  start.Hauptfenster - Programm beenden wurde im Menue ausgewaehlt
INFO  start.Start - Programm-Ende wird ausgeführt stop()-Methode
Methode im Einstellungen Fenster Kontroller
Java:
 @FXML
    private void einstellungenLaden(ActionEvent event) {
        LOG.info("einstellungenLaden wurde aufgerufen");
        fensterModell.einstellungenLadenHD(einstellungen);
    } // einstellungenLaden
Methode im Einstellungen Fenster Modell
Java:
public EinstellungenFM einstellungenLadenHD(Einstellungen einstellungen){
        EinstellungenFM fensterModell = null;
        Einstellungen.ladeEinstellungenHD(einstellungen);
        return fensterModell;
    } // einstellungenLadenHD
Methode in der Klasse Einstellungen
Java:
public static EinstellungenFM ladeEinstellungenHD(Einstellungen einstellungen) {
         InputStream eingabeStreamDatei = null;
         EinstellungenFM fensterModell = null;
         try {
             LOG.info("Einstellungen Pfad : " + einstellungen.holePfadEinstellungen());
             eingabeStreamDatei = new FileInputStream(einstellungen.holePfadEinstellungen()+"\\Einstellungen.ser");
             ObjectInputStream eingabeStreamObjekt = new ObjectInputStream(eingabeStreamDatei);
             fensterModell = (EinstellungenFM) eingabeStreamObjekt.readObject();
             LOG.info("Die Einstellungen wurden in das Modell geladen");
             LOG.info("Quellverzeichnis im Modell : " + fensterModell.holePfadQuelle());
             LOG.info("Verzeichnis Einstellungen im Modell : " + fensterModell.holePfadEinstellungen());
             return fensterModell;
         } catch (Exception e) {
             LOG.info("Es trat ein Fehler beim laden der Einstellungen auf" , e);
         }
     } // ladeEinstellungenHD
Es wurde schon mal angesprochen, dass ich meine Variablen bezüglich der Modelle nicht wirklich gut benannt habe, aber das wird sich ändern wenn ich das Prinzip und und die Funktionsweise besser verstanden habe. :)
 
Die Fehlermeldung sagt es doch schon:
java.lang.ClassCastException: einstellungen.Einstellungen cannot be cast to einstellungen.EinstellungenFM

Du versuchst eine Instanz vom Typ Einstellungen in einer Variablen vom Typ EinstellungenFM zu speichern und der Cast scheint nicht möglich.

Deine Klassen Einstellungen und EinstellungenFM kenne ich aber nicht ebenso weiss ich nicht, was du in deiner Datei wie gespeichert hast. Aber die Zeile mit der Fehlermeldung ("at einstellungen.Einstellungen.ladeEinstellungenHD(Einstellungen.java:207)")
scheint die folgende zu sein:
fensterModell = (EinstellungenFM) eingabeStreamObjekt.readObject();
 
Es wurde schon mal angesprochen, dass ich meine Variablen bezüglich der Modelle nicht wirklich gut benannt habe, aber das wird sich ändern wenn ich das Prinzip und und die Funktionsweise besser verstanden habe.
Andersrum ist’s einfacher :) Alles so gut wie möglich zu benennen macht das Verstehen deutlich einfacher...
 
Die Schreib Methode die zuvor Diskutiert wurde arbeitet ohne Fehler und schreibt ein Objekt auf die Festplatte.
Demnach müsste es doch ausreichen, wenn ich in der Lese Methode das Objekt erstelle und es dann mit
Code:
fensterModell = (EinstellungenFM) eingabeStreamObjekt.readObject();
wieder ein zu lesen.
 
Offensichtlich schreibst du ein Einstellungen-Objekt und versuchst es als EinstellungenFM zu lesen, das klappt natürlich nicht ;)

Halte EinstellungenFM gänzlich aus deinem Model raus, dann gibt es solche Fehler erst gar nicht ;)
 
Ach ja, das Stimmt.
Du hast recht, das schreiben der Objekt-Datei war ein Einstellungen Objekt.
Ich erinnere mich das die Methode writeObjekt nicht mit Properties umgehen kann.
Ich komme damit immer noch etwas durcheinander, mir fehlt halt die Übung.
Ich schreibe die Methoden neu und hoffe das es diesmal klappt :)
Danke
 
Zuletzt bearbeitet:
Die Laden Methode funktioniert soweit.
Code:
INFO  start.Start - Das Programm wird initialisiert init()-Methode
INFO  start.Start - Das Programm-Hauptfenster wird initialisiert start()-Methode
INFO  start.Hauptfenster - Einstellungen wurde im Menue ausgewaehlt
INFO  einstellungen.EinstellungenFK - Einstellungen werden initialisiert
INFO  einstellungen.EinstellungenFK - einstellungenLaden wurde aufgerufen
INFO  einstellungen.Einstellungen - Pfad zum  laden von Einstellungen : C:\Users\Michael\JApp\Einstellungen.ser
INFO  einstellungen.Einstellungen - Die Einstellungen wurden in das Modell geladen
INFO  einstellungen.Einstellungen - Quellverzeichnis im Modell : B:\01 Quelle
INFO  start.Hauptfenster - Programm beenden wurde im Menue ausgewaehlt
INFO  start.Start - Programm-Ende wird ausgeführt stop()-Methode
Nachdem ich dann im Einstellungen Fenster Modell die werte des Einstellungen Modell in das Fenster Modell übertragen wollte, trat dann wieder ein Fehler in der Konsole auf. Im Log waren keine Fehler ausgegeben worden.

Methode Laden aus der Klasse Einstellungen
Java:
 public static Einstellungen leseEinstellungenHD(Einstellungen einstellungen) {
         InputStream eingabeStreamDatei = null;
         Einstellungen hdEinstellungen = new Einstellungen();
         String dateiEinstellungen = einstellungen.holePfadEinstellungen()+"\\Einstellungen.ser";
         LOG.info("Pfad zum  laden von Einstellungen : " + dateiEinstellungen);
         try {
             eingabeStreamDatei = new FileInputStream(dateiEinstellungen);
             ObjectInputStream eingabeStreamObjekt = new ObjectInputStream(eingabeStreamDatei);
             hdEinstellungen = (Einstellungen) eingabeStreamObjekt.readObject();
           
             LOG.info("Quellverzeichnis von HD geladen : " + hdEinstellungen.holePfadQuelle());
         } catch (Exception e) {
             LOG.info("Es trat ein Fehler beim laden der Einstellungen auf" , e);
         }
         return hdEinstellungen;
     } // ladeEinstellungenHD
Methode aus Einstellungen Fenster Modell
Java:
public EinstellungenFM einstellungenLadenHD(Einstellungen einstellungen){
        EinstellungenFM fensterModell = null;
        Einstellungen einstellungenHD = new Einstellungen();
        einstellungenHD = Einstellungen.leseEinstellungenHD(einstellungen);
       
        // Werte in das Fenster-Modell übetragen
        fensterModell.schreibePfadQuelle(einstellungenHD.holePfadQuelle());
        fensterModell.schreibePfadZiel(einstellungenHD.holePfadZiel());
        fensterModell.schreibePfadOCR(einstellungenHD.holePfadOCR());
        fensterModell.schreibePfadOhneDokumentArt(einstellungenHD.holePfadOhneDokumentArt());
        fensterModell.schreibePfadLoeschen(einstellungenHD.holePfadLoeschen());
        fensterModell.schreibePfadGeschuetzt(einstellungenHD.holePfadGeschuetzt());
        fensterModell.schreibePfadBild(einstellungenHD.holePfadBild());
        fensterModell.schreibePfadEinstellungen(einstellungenHD.holePfadEinstellungen());
       
        fensterModell.schreibeDbServeradresse(einstellungenHD.holeDbServeradresse());
        fensterModell.schreibeDbDatenbankname(einstellungenHD.holeDbDatenbankname());
        fensterModell.schreibeDbBenutzername(einstellungenHD.holeDbBenutzername());
        fensterModell.schreibeDnbToken(einstellungenHD.holeDnbToken());
       
        return fensterModell;
    } // einstellungenLadenHD
Fehler in der Konsole
Code:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8865)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3876)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    ... 47 more
Caused by: java.lang.NullPointerException
    at einstellungen.EinstellungenFM.einstellungenLadenHD(EinstellungenFM.java:96)
    at einstellungen.EinstellungenFK.einstellungenLaden(EinstellungenFK.java:176)
    ... 58 more
 
Zuletzt bearbeitet:
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben