JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea

ralfb1105

Bekanntes Mitglied
Hallo zusammen,

ich versuche mich gerade in JavFX einzuarbeiten um meine Applikation die auf Java Swing basiert in JavaFX zu implemntieren. Ich versuche dabei auch das MVC Pattern zu realisieren. Das GUI habe ich mit Hilfe des Scenebuilder realisiert und aufgebaut.
Hier nun mein Problem:
Ich habe eine TextArea in der ich Meldungen ausgeben möchte die z.B. auch in der Model Class entstehen. Ich versuche nun beim drücken eines Button in einem extra Thread, da das UI nicht beeinträchtigt werden soll. eine Aktion durchzuführen. In Java Swing habe ich das mit ProcessWorker realisiert. Mir fehlt nun die richtige Implemntierung für JavaFX. Nachdem ich nun einiges gelesen habe war dies mein erster Versuch:

Der Code der im Controller beim drücken des Button ausgeführt wird:
Java:
public void checkConnectDBButtonTapped() {
        //statusIndicator.setVisible(true);
        //statusIndicator.setImage(statusInProgress);
        messageTextArea.appendText("DB hostname/address: " + dbHostNameAddress.getText() + "\n");
        messageTextArea.appendText("Listener Port: " + listenerPort.getText()  + "\n");
        messageTextArea.appendText("DB SID: " + dbSid.getText()  + "\n");
        messageTextArea.appendText("DB User Name: " + dbUserName.getText()  + "\n");
        messageTextArea.appendText("DB User Password: " + dbUserPassword.getText() + "\n" );
        messageTextArea.appendText("DB sys User Password: " + dbSysUserPassword.getText()  + "\n");
        messageTextArea.appendText("TNS Names Directory: " + tnsnamesDir.getText() + "\n");
        messageTextArea.appendText("TNS Service Name: " + tnsamesServiceName.getText() + "\n");
        Model model = new Model(messageTextArea);
        new Thread(model.task).start();
        //statusIndicator.setImage(statusOK);
    }

Die Model Class ist folgendermaßen implementiert:
Java:
package application;

import javafx.concurrent.Task;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;

public class Model {

    // Fields

    TextArea messageTextArea;
    ProgressBar bar;

    // Constructors

    public Model() {
    }

    public Model(TextArea messageTextArea, ProgressBar bar) {
        super();
        this.messageTextArea = messageTextArea;
        this.bar = bar;
    }

    public Model(TextArea messageTextArea) {
        super();
        this.messageTextArea = messageTextArea;
    }

    // Methods

    Task task = new Task<Void>() {
        @Override
        public void run() {
            final int max = 100;
            for (int i = 1; i <= max; i++) {
                updateProgress(i, max);
                System.out.println("Value: " + i);
                messageTextArea.appendText("Value: " + i + "\n");
            }
        }

        @Override
        protected Void call() throws Exception {
            // TODO Auto-generated method stub
            return null;
        }
    };

}

Wenn ich die Applikation starte und den Button drücke wird auf der Konsole die Ausgabe "Value:1" bis "Value 100" gemacht, in der Message Area kommen ungefähr die Ausgaben bis Value: 4 und es wird eine Exception ausgegeben:
Code:
Value: 1
Exception in thread "JavaFX Application Thread" Value: 2
Value: 3
Value: 4
Value: 5
Value: 6
Value: 7
Value: 8
Value: 9
Value: 10
Value: 11
Value: 12
Value: 13
Value: 14
Value: 15
Value: 16
Value: 17
Value: 18
Value: 19
Value: 20
Value: 21
Value: 22
java.lang.NullPointerException
    at com.sun.javafx.text.PrismTextLayout.addTextRun(PrismTextLayout.java:755)
    at com.sun.javafx.text.GlyphLayout.addTextRun(GlyphLayout.java:140)
    at com.sun.javafx.text.GlyphLayout.breakRuns(GlyphLayout.java:210)
    at com.sun.javafx.text.PrismTextLayout.buildRuns(PrismTextLayout.java:770)
    at com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1021)
    at com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:223)
    at com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:246)
    at javafx.scene.text.Text.getLogicalBounds(Text.java:358)
    at javafx.scene.text.Text.impl_computeGeomBounds(Text.java:1168)
    at javafx.scene.Node.updateGeomBounds(Node.java:3579)
    at javafx.scene.Node.getGeomBounds(Node.java:3532)
    at javafx.scene.Node.getLocalBounds(Node.java:3480)
    at javafx.scene.Node$MiscProperties$2.computeBounds(Node.java:6474)
    at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9308)
    at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9278)
    at javafx.scene.Node.getBoundsInLocal(Node.java:3158)
    at com.sun.javafx.scene.control.skin.TextAreaSkin$ContentView.layoutChildren(TextAreaSkin.java:207)
    at javafx.scene.Parent.layout(Parent.java:1087)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Scene.doLayoutPass(Scene.java:552)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2397)
    at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Unknown Source)
Value: 23
Value: 24
Value: 25
Value: 26
Value: 27
Value: 28
Value: 29
Value: 30
Value: 31
Value: 32
Value: 33
Value: 34
Value: 35
Value: 36
Value: 37
Value: 38
Value: 39
Value: 40
Value: 41
Value: 42
Value: 43
Value: 44
Value: 45
Value: 46
Value: 47
Value: 48
Value: 49
Value: 50
Value: 51
Value: 52
Value: 53
Value: 54
Value: 55
Value: 56
Value: 57
Value: 58
Value: 59
Value: 60
Value: 61
Value: 62
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at com.sun.javafx.text.PrismTextLayout.addTextRun(PrismTextLayout.java:755)
    at com.sun.javafx.text.GlyphLayout.addTextRun(GlyphLayout.java:140)
    at com.sun.javafx.text.GlyphLayout.breakRuns(GlyphLayout.java:210)
    at com.sun.javafx.text.PrismTextLayout.buildRuns(PrismTextLayout.java:770)
    at com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1021)
    at com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:223)
    at com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:246)
    at javafx.scene.text.Text.getLogicalBounds(Text.java:358)
    at javafx.scene.text.Text.impl_computeGeomBounds(Text.java:1168)
    at javafx.scene.Node.updateGeomBounds(Node.java:3579)
    at javafx.scene.Node.getGeomBounds(Node.java:3532)
    at javafx.scene.Node.getLocalBounds(Node.java:3480)
    at javafx.scene.Node.updateTxBounds(Node.java:3643)
    at javafx.scene.Node.getTransformedBounds(Node.java:3426)
    at javafx.scene.Node.updateBounds(Node.java:559)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Parent.updateBounds(Parent.java:1717)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2404)
    at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Unknown Source)
Value: 63
Value: 64
Value: 65
Value: 66
Value: 67
Value: 68
Value: 69
Value: 70
Value: 71
Value: 72
Value: 73
Value: 74
Value: 75
Value: 76
Value: 77
Value: 78
Value: 79
Value: 80
Value: 81
Value: 82
Value: 83
Value: 84
Value: 85
Value: 86
Value: 87
Value: 88
Value: 89
Value: 90
Value: 91
Value: 92
Value: 93
Value: 94
Value: 95
Value: 96
Value: 97
Value: 98
Value: 99
Value: 100

Frage:
Kann mir jemand helfen bei der korrekten Implementierung eines Worker Threads mit JavaFX und MVC Pattern?

LG

Ralf
 

mrBrown

Super-Moderator
Mitarbeiter
Task ist eine JavaFX-spezifische klasse, und sollte damit nicht ins Model, genauso wie ProgressBar und TextArea ;)
Aktuell ist deine Model-Klasse eher ein Controller, den du Model genannt hast.


Überleg dir zu erst, was dein Model können soll: in diesem Fall im Hintergrund eine Zahl hochzählen?
Dann schreib eine Klasse, die genau das macht, völlig ohne irgendwelche View-Spezifischen Dinge (zB alles aus javafx.*).

Wenn das gemacht ist, kannst du eine View hinzufügen. In diesem Fall registriert die sich als Observer/Listener am Model, startet bei einem Button-Klick die asynchrone Methode, und aktualisiert sich, wenn das Observeable aktualisiert wird.
 

ralfb1105

Bekanntes Mitglied
Hallo mrBrown,

leider muss ich eingestehen das ich von Deiner Antwort den Kern der durchzuführenden Implemntierung nicht verstehe.
Die Erklärung zu Model vs. Controller habe ich verstanden, mehr aus Unwissenheit heraus habe ich die FX Komponenten mit im Model.
Ich bräuchte Nachhilfe zu folgendem Satz:
Wenn das gemacht ist, kannst du eine View hinzufügen. In diesem Fall registriert die sich als Observer/Listener am Model, startet bei einem Button-Klick die asynchrone Methode, und aktualisiert sich, wenn das Observeable aktualisiert wird.

Das mit dem Model das zum testen eine Zahl hochzählt verstehe ich noch, doch die Verheiratung der Ausgaben dieser Klasse (Model) mit dem View ist mir nicht klar in Bezug auf JavaFX / Scenebuilder ?

Könntest Du mir hier bitte weiterhelfen, vielleicht konkret mit meinem Beispiel?

Das Model zählt eine Zahl hoch und gibt diese dann zurück. Somit würde mein Model folgenden Code enthalten:
Java:
package application;

public class Model {

    // Methods

    public int countNumber(int startValue, int maxValue) {
        int result = startValue;
        for (int i = startValue; i < maxValue; i++) {
            result ++;
        }
        System.out.println("End Value: " + result);
        return result;
    }
}

Diese Ausgabe könnte ich jetzt auch beim Click auf den Button in der TextArea ausgeben lassen, erst einmal ohne Treat - funktioniert natürlich solange es nicht ewig dauert und somit das UI blokiert - so mein Verständnis - richtig?

Java:
Model model = new Model();

public void checkConnectDBButtonTapped() {
        //statusIndicator.setVisible(true);
        //statusIndicator.setImage(statusInProgress);
        messageTextArea.appendText("DB hostname/address: " + dbHostNameAddress.getText() + "\n");
        messageTextArea.appendText("Listener Port: " + listenerPort.getText()  + "\n");
        messageTextArea.appendText("DB SID: " + dbSid.getText()  + "\n");
        messageTextArea.appendText("DB User Name: " + dbUserName.getText()  + "\n");
        messageTextArea.appendText("DB User Password: " + dbUserPassword.getText() + "\n" );
        messageTextArea.appendText("DB sys User Password: " + dbSysUserPassword.getText()  + "\n");
        messageTextArea.appendText("TNS Names Directory: " + tnsnamesDir.getText() + "\n");
        messageTextArea.appendText("TNS Service Name: " + tnsamesServiceName.getText() + "\n");
        messageTextArea.appendText("Result countNumber: " + model.countNumber(10, 100));
       
        //statusIndicator.setImage(statusOK);
    }

Könntest Du mir an Hand dieses Beispiels erklären/zeigen wie ich das in einen Worker Threat (weiß nicht ob dies die das richtige Wording ist) bekomme, sprich wie die Implementierung Deiner Erklärung aussieht?

LG
Ralf
 

ralfb1105

Bekanntes Mitglied
Hallo,

ich habe nach viel suchen und lesen folgendes implementiert, und es sieht auch schon besser aus als vorher, sprich ich bekomme keine Exception mehr .. dennoch scheint es noch nicht die 100% richtige Lösung zu sein.

Hier mein Code:

1. Das Model mit ein paar Methoden die nur ein bisschen rechnen aber keinerlei FX Komponenten enthalten.

Java:
package application;

import java.util.Random;

public class Model {

    // Methods

    public int countNumber(int startValue, int maxValue) {
        int result = startValue;
        for (int i = startValue; i < maxValue; i++) {
            result++;
        }
        return result;
    }

    public int logKomplex(int n) {
        int result = 0;
        for (int i = 1; i <= n; i = i * 2) {
            System.out.println("Round: " + i);
            result = i;
        }
        return result;
    }
   
    public int getArrayIndex(int index, int max) {
        int [] array1 = new int[max];
        Random rnd=new Random();
        for (int i = 0; i < array1.length; i++) {
            array1[i] = rnd.nextInt(max);
        }
       
        return array1[index];
    }

}

2. Der Controller:

Java:
package application;

import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    Button startButton = new Button();

    @FXML
    Button cancelButton = new Button();

    @FXML
    ProgressIndicator pi = new ProgressIndicator();

    @FXML
    TextArea messageTextArea = new TextArea();

    Model model = new Model();

    public void startButton() {
        pi.progressProperty().bind(workerTask.progressProperty());
        workerTask.messageProperty().addListener((obs, oldMsg, newMsg) -> messageTextArea.appendText(newMsg + "\n"));
        new Thread(workerTask).start();
        cancelButton.setDisable(false);
    }

    public void cancelButton() {
        workerTask.cancel();
    }

    Task<Integer> workerTask = new Task<Integer>() {
        @Override
        protected Integer call() throws Exception {
            updateMessage("Task started ...");
            final int max = 100;
            int counter;
            for (counter = 0; counter <= max; counter++) {
                if (isCancelled()) {
                    updateMessage("Task cancelled!");
                    break;
                }
                updateMessage("Value at index " + counter + ": " + model.getArrayIndex(counter, max));
                updateProgress(counter, max);
                Thread.sleep(1000);
            }
            updateMessage("Task ended!");
            return counter;
        }
    };

}

Ich habe versucht einen Listener auf den workerTask zu legen der die Ausgaben dann in die TextArea schreibt:
Java:
workerTask.messageProperty().addListener((obs, oldMsg, newMsg) -> messageTextArea.appendText(newMsg + "\n"));

Wenn ich den Button drücke werden die Ausgaben von
Java:
updateMessage("Value at index " + counter + ": " + model.getArrayIndex(counter, max));
in der TextArea ausgegeben, allerdings fehlen mir die Ausgaben beim Start "updateMessage("Task started ...");" und beim cancel die "updateMessage("Task cancelled!");" Meldung. Die Meldung "Task ended ..." wird ausgegeben.

Frage:
1. Ist das die richtige Implementierung bezogen auf die Antwort von mrBrown?
2. Warum wird die Start Meldung nicht ausgegeben?

Bin für jeden Tipp dankbar!

Gruß
Ralf
 

ralfb1105

Bekanntes Mitglied
Ich war davon ausgegangen das die Meldungen alle hintereinander „n + \n“ ausgegeben werden? Warum wird denn die erste Meldung überschrieben und bei den anderen Meldungen wie erwartet alles hintereinander geschrieben? Warum kommt denn die Cancel Meldung auch nicht? Wo liegt denn hier mein Verständnis Problem?

Gruß
Ralf
 

mihe7

Top Contributor
Warum wird denn die erste Meldung überschrieben und bei den anderen Meldungen wie erwartet alles hintereinander geschrieben?
Einfach gesagt: es geht in der Regel darum, den aktuellen Fortschritt anzuzeigen und nicht eine Historie. Aus Gründen der Performance können daher Zwischenmeldungen ausgelassen werden. Das Verhalten ist dokumentiert.

Wenn Du die Historie brauchst, musst Du diese selbst verwalten. Entweder, indem Du Dir in Deinem Task den String zusammenbaust und via updateMessage an das UI übergibst (die Message ist also die komplette Historie) oder indem Du eine Struktur verwendest, auf die Du von beiden Thread aus zugreifst. Der Zugriff muss dann natürlich synchronisiert werden.

Warum kommt denn die Cancel Meldung auch nicht?
Aus dem gleichen zeitlichen Grund: Du verlässt mittels break die for-Schleife und direkt im Anschluss wird updateMessage("Task ended!") ausgeführt.
 

ralfb1105

Bekanntes Mitglied
Hallo mihe7,
Vielen Dank für Deine ausführliche Erklärung!! Mit dem Verhalten kann ich leben, die Start Meldung kann ich aus dem Task nehmen und beim drücken des Start Button ausgeben, dann funktioniert es - genauso wie die Cancel Meldung.
Ich wollte nur sicher gehen das die Implementierung des Listener die korrekte Lösung für meine Problemstellung war/ist.

Leider habe ich gerade noch ein weiteres Problem in meinem Code festgestellt :( ich hoffe Du findest ein paar Minuten um Dir das anzusehen und vielleicht hast Du ja eine Lösung für mich:rolleyes:

Problem Beschreibung:
Wenn ich den Start Button drücke wird der Code ausgeführt, der progressIndicator zeigt den Fortschritt an und die Meldungen
Java:
updateMessage("Value at index " + counter + ": " + model.getArrayIndex(counter, max));
werden in der TextArea angezeigt, inklusive der Start Meldung die ich direkt in der Methode die beim ActionEvent des Button ausgeführt wird:
Java:
public void startButton() {
        pi.progressProperty().bind(workerTask.progressProperty());
        workerTask.messageProperty().addListener((obs, oldMsg, newMsg) -> messageTextArea.appendText(newMsg + "\n"));
        messageTextArea.appendText("Task started ...\n");
        new Thread(workerTask).start();
        cancelButton.setDisable(false);
    }
Ich kann das Programm, sprich den Task, nun zu Ende laufen lassen oder über den Cancel Button vorzeitig abbrechen. Das funktioniert Dank Deiner und mrBrown's Hilfe nun einwandfrei.

Wenn ich nach beendigung oder Abbruch des Task erneut auf den Start Button dürcke, wird allerdigs der Task NICHT ein weiteres Mal gestartet ???!!! Es wird die Meldung aus der Methode "startButton()" i die TextArea geschrieben, dann kommen aber keine weiteren Meldungen und auch der ProgressIndicator zählt nicht mehr.

Hat jemand eine Idee was ich hier falsch gemacht habe?

Gruß

Ralf
 

ralfb1105

Bekanntes Mitglied
Hallo mihe7,
ich habe etwas zu meinem Problem gefunden und so wie ich es verstanden habe wird ein Thread nur einmal gestartet:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
The Task class defines a one-time object that cannot be reused. If you need a reusable Worker object, use the Service class.
Ich habe dann meine Controller entsprechend umgebaut - hier der resultierende Code:
Java:
package application;

import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    Button startButton = new Button();

    @FXML
    Button cancelButton = new Button();

    @FXML
    ProgressIndicator pi = new ProgressIndicator();

    @FXML
    TextArea messageTextArea = new TextArea();

    Model model = new Model();

    public void startButton() {
        pi.progressProperty().bind(serviceWorkerTask1.progressProperty());
        serviceWorkerTask1.messageProperty()
                .addListener((obs, oldMsg, newMsg) -> messageTextArea.appendText(newMsg + "\n"));
        messageTextArea.appendText("Task started ...\n");
        if (!serviceWorkerTask1.isRunning()) {
            serviceWorkerTask1.reset();
            serviceWorkerTask1.start();
            cancelButton.setDisable(false);
        }
    }

    public void cancelButton() {
        if (serviceWorkerTask1.isRunning()) {
            serviceWorkerTask1.cancel();
        }
        messageTextArea.appendText("Task will be cancelled ...\n");
    }

    @SuppressWarnings("rawtypes")
    Service serviceWorkerTask1 = new Service() {
        @Override
        protected Task createTask() {
            return new Task() {
                @Override
                protected Void call() throws Exception {
                    // Start enetering execution code here ...
                    final int max = 100;
                    int counter;
                    for (counter = 1; counter <= max; counter++) {
//                        if (isCancelled()) {
//                            break;
//                        }
                        updateMessage("Value at index " + counter + ": " + model.getArrayIndex(counter, max));
                        updateProgress(counter, max);
                        Thread.sleep(100);
                    }
                    updateMessage("Task ended!");
                    // End entering execution code here ...
                    return null;
                }
            };
        }
    };

}
Ergebnis:
Beim drücken des Start Button wird der Service/Thread gestartet und die vorher werden die Ausgaben gemacht. Beim 2x drücken des Start Button wird wie beim ersten Mal der Service/Thread gestartet und die Ausgaben werden gemacht.

Problem:
Leider werden alle Ausgaben aus dem Service Thread ZWEI MAL ausgegeben ????
Code:
Task started ...
Value at index 1: 82
Value at index 2: 83
Value at index 3: 26
Value at index 4: 71
Value at index 5: 56
Task will be cancelled ...
Task started ...


Value at index 1: 85
Value at index 1: 85
Value at index 2: 75
Value at index 2: 75
Value at index 3: 22
Value at index 3: 22
Value at index 4: 20
Value at index 4: 20
Value at index 5: 56
Value at index 5: 56
Value at index 6: 77
Value at index 6: 77
Task will be cancelled ...
Bei jedem weiteren Start wird auch die Ausgabe der einzelnen Zeilen dupliziert :confused:

Ist unter Umständen die Implemntierung des Listenera auf dem service das Problem?

Java:
serviceWorkerTask1.messageProperty()
                .addListener((obs, oldMsg, newMsg) -> messageTextArea.appendText(newMsg + "\n"));

Hat hierzu jemand eine Erklärung??

Gruß

Ralf
 

ralfb1105

Bekanntes Mitglied
Hallo mihe7,
;) upss, da hätte ich auch selbst drauf kommen könne/müssen ...
DANKE das Du mich drauf gestoßen hast.

Ich habe es jetzt im Konstruktor des Controller gemacht und es scheint zu funktionieren - ist es das was Du gemeint hast .. nur um sicher zu gehen das ich nicht auf einem falschen Pfad unterwegs bin:
Java:
public Controller() {
        super();
        serviceWorkerTask1.messageProperty().addListener((obs, oldMsg, newMsg) -> messageTextArea.appendText(newMsg + "\n"));
    }

Gruß
Ralf
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P thread nimmt veränderte boolean nicht AWT, Swing, JavaFX & SWT 7
N JFrame loescht alles, sobald der Thread zuende ist AWT, Swing, JavaFX & SWT 22
M Server/Client thread von GUI Trennen AWT, Swing, JavaFX & SWT 2
K JavaFx, Sound Aufnahme und Thread AWT, Swing, JavaFX & SWT 0
T Exception in thread "main" java.lang.NoClassDefFoundError AWT, Swing, JavaFX & SWT 4
G Exception javafx Thread -> caused by removing children while in EventHandler AWT, Swing, JavaFX & SWT 28
H Event Handling Thread - Abruf der get-Methode AWT, Swing, JavaFX & SWT 5
J "Exception in thread "AWT-EventQueue-0"" Fehler AWT, Swing, JavaFX & SWT 3
G Thread starten Swing AWT, Swing, JavaFX & SWT 5
C Thread verwalten AWT, Swing, JavaFX & SWT 2
A Swing Exception in thread "AWT-EventQueue-0" AWT, Swing, JavaFX & SWT 1
S JavaFX Exception in thread "JavaFX Application Thread" AWT, Swing, JavaFX & SWT 3
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
ralfb1105 JavaFX Alert Confirmation Dialog aus einem Service Thread AWT, Swing, JavaFX & SWT 8
D Swing SwingUtils / Thread Problem AWT, Swing, JavaFX & SWT 3
J Thread per Button starten AWT, Swing, JavaFX & SWT 10
J Thread kennt JButton nicht. AWT, Swing, JavaFX & SWT 11
T JavaFX Task / Thread / FXThread Komplikationen AWT, Swing, JavaFX & SWT 5
O Swing Event Dispatch Thread AWT, Swing, JavaFX & SWT 1
L JavaFX UI Thread block AWT, Swing, JavaFX & SWT 13
X Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 AWT, Swing, JavaFX & SWT 6
sandaime Swing Thread für CMD auslesen AWT, Swing, JavaFX & SWT 16
E JavaFX JavaFX Application in Thread ausführen AWT, Swing, JavaFX & SWT 1
D JavaFX UI-Thread und DB-Thread trennen um z.B. Ladebalken anzuzeigen AWT, Swing, JavaFX & SWT 15
T JavaFX Controller im extra Thread AWT, Swing, JavaFX & SWT 0
T Swing 2 Thread.sleep parallel laufen lassen AWT, Swing, JavaFX & SWT 4
L Zweites Fenster mit Thread AWT, Swing, JavaFX & SWT 0
E JavaFX Stage.show() in ursprünglichem Thread starten AWT, Swing, JavaFX & SWT 7
L Swing Frame in Thread wird nicht gezeichnet AWT, Swing, JavaFX & SWT 2
N Programm mit Swing und Thread, Figur bewegen sich nicht AWT, Swing, JavaFX & SWT 6
C Im ActionListener Buttons disablen, einen Thread starten, dann Buttons enablen AWT, Swing, JavaFX & SWT 2
C Thread-/ Simulations- Problem AWT, Swing, JavaFX & SWT 18
T Swing Button bleibt grau [=> UI hat sich aufgehängt, Aufgabe in Thread auslagern] AWT, Swing, JavaFX & SWT 3
M Thread-Frage in SWT AWT, Swing, JavaFX & SWT 1
Q GUI außerhalb GUI-Thread updaten - GUI friert ein AWT, Swing, JavaFX & SWT 18
C Thread in Klassen starten AWT, Swing, JavaFX & SWT 4
L exception in thread awt-eventqueue-0 java.lang.nullpointerexception AWT, Swing, JavaFX & SWT 2
S Swing Exception in thread "AWT-EventQueue-0" bei Jlabel AWT, Swing, JavaFX & SWT 4
D SWT SWT Elemente aus anderen Klassen aufrufen - Invalid thread access AWT, Swing, JavaFX & SWT 6
K JavaFX Tableview mit fxml ohne Aktualiserung trotz Thread AWT, Swing, JavaFX & SWT 13
K Event Handling 2 Buttons und Thread stop AWT, Swing, JavaFX & SWT 3
C Swing Update von swing-TableModels per Thread. Eins geht, das andere nicht, warum? AWT, Swing, JavaFX & SWT 12
V JLabel bzw. GUI aus externen Thread ansteuern AWT, Swing, JavaFX & SWT 3
J Applet Paralleles Thread Handling AWT, Swing, JavaFX & SWT 3
H Swing JfreeChart aktualisieren - mit daten aus thread AWT, Swing, JavaFX & SWT 3
T Java Swing Main GUI Thread AWT, Swing, JavaFX & SWT 3
C Event Handling Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException AWT, Swing, JavaFX & SWT 43
T Table-Zeilen mit Thread einfärben AWT, Swing, JavaFX & SWT 15
F Swing GUI-Thread für automatisches Update nutzen AWT, Swing, JavaFX & SWT 10
Y KeyListener, GUI Thread, repaint AWT, Swing, JavaFX & SWT 7
V Nullpointerexception (etwas mit thread und jframe) AWT, Swing, JavaFX & SWT 3
P Problem Thread.sleep() und JProgressBar AWT, Swing, JavaFX & SWT 7
S SWT GUI-Thread AWT, Swing, JavaFX & SWT 11
A Thread und sleep(1000); AWT, Swing, JavaFX & SWT 7
B Swing Thread+Animation AWT, Swing, JavaFX & SWT 7
S Timer oder Thread.sleep AWT, Swing, JavaFX & SWT 3
M Exception in thread "Thread-3" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 18
B Über SWT Button Thread beenden AWT, Swing, JavaFX & SWT 2
C SWT Gui Thread hängt sich auf AWT, Swing, JavaFX & SWT 3
lumo SWT Exception in thread "main" org.eclipse.swt.SWTError: No more handles AWT, Swing, JavaFX & SWT 3
Luk10 Swing Problem mit Zeichen-Thread AWT, Swing, JavaFX & SWT 8
G 2D-Grafik Von Thread aus Zeichnen AWT, Swing, JavaFX & SWT 5
U Swing JLabel bewegen mittels Thread AWT, Swing, JavaFX & SWT 3
M JProgressBar für einen Thread AWT, Swing, JavaFX & SWT 14
R JTable und Thread AWT, Swing, JavaFX & SWT 4
K Thread.sleep in GUI AWT, Swing, JavaFX & SWT 4
J Thread funktioniert nicht AWT, Swing, JavaFX & SWT 10
D JPanel mit Thread in JPanel AWT, Swing, JavaFX & SWT 4
F Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: null AWT, Swing, JavaFX & SWT 5
P Teil einer Swing GUI in eigenem Thread AWT, Swing, JavaFX & SWT 4
S Thread.sleep() in einer methode fürs zeichen AWT, Swing, JavaFX & SWT 3
O JTree/TreeModel/DefaultMutableTreeNodes thread safe machen AWT, Swing, JavaFX & SWT 3
P repaint während Thread läuft AWT, Swing, JavaFX & SWT 9
F SWT table refresh per Thread AWT, Swing, JavaFX & SWT 2
V Swing remove(Component) blockiert Thread sehr lange. AWT, Swing, JavaFX & SWT 6
J AWT Artefakte bei AWT-Rendering durch parallelen Thread AWT, Swing, JavaFX & SWT 4
H Thread-Problem mit der Darstellung beim Sperren des Fensters AWT, Swing, JavaFX & SWT 2
T Event Dispatch Thread und noch ein Thread AWT, Swing, JavaFX & SWT 7
Burny91 Swing Thread mit wait() und notify() steuern AWT, Swing, JavaFX & SWT 22
N SWT - über Thread Composite erstellen und Anhängen AWT, Swing, JavaFX & SWT 6
K Vom Gui aus auf einen Thread warten AWT, Swing, JavaFX & SWT 4
X Problem bei JTextArea und Thread.sleep() AWT, Swing, JavaFX & SWT 8
F Merkwürdiges Verhalten zeichnen sperater Thread AWT, Swing, JavaFX & SWT 13
B Swing Swing und Thread.sleep() AWT, Swing, JavaFX & SWT 6
N Exception Behandlung mit setDefaultUncaughtExceptionHandler, insbesondere im EventDispatcher Thread AWT, Swing, JavaFX & SWT 4
Q Neuer Thread zum Öffnen AWT, Swing, JavaFX & SWT 2
P Swing GUI im Thread? AWT, Swing, JavaFX & SWT 5
T GUI JFrame - neuer Thread AWT, Swing, JavaFX & SWT 2
data89 Was mache ich mit "Dispatched Event Thread"/Substance falsch? AWT, Swing, JavaFX & SWT 4
0x7F800000 Allg. Frage zum ev. dispatch thread, wie korrekt auf reaktion der Listener warten? AWT, Swing, JavaFX & SWT 4
S Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 7
T thread.sleep Sprung Problem AWT, Swing, JavaFX & SWT 24
N Server mit Thread und Statusbox AWT, Swing, JavaFX & SWT 3
S Objektverhalten in einen Thread legen AWT, Swing, JavaFX & SWT 4
G JProgressBar actionPerformedMethode und SwingUI thread AWT, Swing, JavaFX & SWT 36
E Komponenten in Event Dispatch Thread erzeugen? AWT, Swing, JavaFX & SWT 4
J Thread in GUI einbauen AWT, Swing, JavaFX & SWT 2
Lony AbstractTableModel Exception in thread "AWT-EventQueue- AWT, Swing, JavaFX & SWT 3
A Ticker als Thread AWT, Swing, JavaFX & SWT 3
G Auf Ergebnis vom Thread warten AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben