JavaFX Probleme bei Service-Klasse beim ändern der GUI

da921610

Aktives Mitglied
Hey Leute, ich bin gerade am verzweifeln ...

Und zwar habe ich ein Problem mit der JavaFx Service Klasse.

Ich habe eine GUI mit einer Progress-Bar. Die GUI soll initialisiert werden und währenddessen soll die Progressbar durchlaufen.

Ich habe hier mal einen kleinen Code-Schnipsel, an dem ich das gerne testen würde:
Java:
package application.controller;

import java.net.URL;
import java.util.ResourceBundle;

import application.MainTestProj;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.Cursor;
import javafx.scene.control.*;
import javafx.stage.Stage;
public class MainViewController extends SuperController {
   
    @FXML private Button btn_startProg;
    @FXML private Button btn_zuruecksetzen;
    @FXML private TextField txt_delay;
    @FXML private ProgressBar progBar;
    @FXML private Label lbl1;
    @FXML private Label lbl2;
    @FXML private Label lbl3;   
    @FXML private TextField txt1;
    @FXML private TextField txt2;
    @FXML private TextField txt3;
   
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {

    }
   
    @FXML
    private void btn_startProg_afterClick() {
       
        progBarSimu service = new progBarSimu();
        service.setCursor(Cursor.WAIT);
        service.initOwner(MainTestProj.getPrimaryStage());
        service.setDelay(Long.parseLong(this.txt_delay.getText()));
        service.setOnRunning(event -> {
           
        });
        service.setOnSucceeded(event -> {
            try {
//                Eigentlich Verarbeitung. Allerdings komm ich hier nicht an die Progressbar dran
                lbl1.setText("Es");
                Thread.sleep(1000);
                txt1.setText("scheint");
                Thread.sleep(1000);
                txt2.setText("wohl");
                Thread.sleep(1000);
                txt3.setText("zu");
                Thread.sleep(1000);
                lbl2.setText("funktionieren");
                Thread.sleep(1000);
                lbl3.setText(":)");
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("Fertig");
        });
        progBar.progressProperty().bind(service.progressProperty());
        service.start();
    }
   
    /*
     *
     * Service, der einfach nur den Cursor auf Wait setzt und die ProgressBar durchlaufen lässt
     */
    private static class progBarSimu extends Service<Void> {
       
        private Stage stage;
        private Cursor cursor;
        private Cursor lastCursor;
        private long delay;
       
        public void setDelay(long argDelay) {
            this.delay = argDelay;
        }
       
        public void setCursor(Cursor argCursor) {
            this.cursor = argCursor;
        }
       
        public void initOwner(Stage argStage) {
            this.stage = argStage;
        }
       
        @Override
        protected Task<Void> createTask() {
            return new Task<Void> () {
                @Override
                protected Void call() throws Exception {
                    lastCursor = stage.getScene().getCursor();
                    stage.getScene().setCursor(cursor);
                    for (int i = 0; i <= 100; i++) {                   
                        try {
                            Thread.sleep(delay);
//                        Progressbar läuft durch, komme aber nicht an meine Controls, weil hier die eigentliche Verarbeitung stattfinden soll   
                            updateProgress(i, 100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    return null;   
                }               
            };
           
           
        }
       
    }
   
    @FXML
    private void btn_zuruecksetzen_afterClick() {
        this.progBar.setProgress(0.001);
    }

    @Override
    public void setMainApp(MainTestProj mainApp) {
       
    }   
}

Mein Problem an der Geschichte ist, dass ich in der createTask()-Methode nicht an meine GUI Elemente komme und dass ich dann außerhalb der Methode die ProgressBar nicht aktualisieren kann. Ich habe die Stellen im Code nochmal Kommentiert, welche ich meine.

Ich hoffe ihr könnt eine Lösung finden, dass ich gleichzeitig meine GUI Controlls initialisieren kann und dass der ProgressBar durchläuft.
 

da921610

Aktives Mitglied
Achja kleiner Nachtrag,
ich brauche es nicht, dass die einzelnen Elemente immer nach und nach (optisch) initialisiert werden. Wichtig ist eigentlich nur, dass der Progressbar durchläuft und die Eieruhr zu sehen ist :)
Also Sprich eine solche Call-Methode innerhalb createTask ()bräuchte ich eigentlich, aber ist nicht zulässig

Code:
protected Void call() throws Exception {
                    lastCursor = stage.getScene().getCursor();
                    stage.getScene().setCursor(cursor);
                    for (int i = 0; i <= 100; i++) {                  
                        try {
                            Thread.sleep(delay);
//                        Progressbar läuft durch, komme aber nicht an meine Controls, weil hier die eigentliche Verarbeitung stattfinden soll  
                              lbl1.setText("Es");
                              txt1.setText("scheint");
                              txt2.setText("wohl");
                              txt3.setText("zu");
                              lbl2.setText("funktionieren");
                              lbl3.setText(":)");

                            updateProgress(i, 100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    return null;  
                }
 

da921610

Aktives Mitglied
Ich konnte mir jetzt anders helfen....
Ich habe anstatt nem kompletten Service nur den Task implementiert.

Code:
@FXML
private void btn_startProg_afterClick() {

    Task<Void> task = new Task<Void>() {
        private long delay = 1000;
        @Override
        protected Void call() throws Exception {
           
            MainTestProj.getPrimaryStage().getScene().setCursor(Cursor.WAIT);
           
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    lbl1.setText("Es");
                    updateProgress(1, 6);
                }
            });
            Thread.sleep(delay);
            txt1.setText("scheint");
            updateProgress(2, 6);
            Thread.sleep(delay);
            txt2.setText("wohl");
            updateProgress(3, 6);
            Thread.sleep(delay);
            txt3.setText("zu");
            updateProgress(4, 6);
            Thread.sleep(delay);
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    lbl2.setText("funktionieren");
                }
            });
            updateProgress(5, 6);
            Thread.sleep(delay);
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    lbl3.setText(":)");
                }
            });
            updateProgress(6, 6);
            MainTestProj.getPrimaryStage().getScene().setCursor(Cursor.DEFAULT);
            return null;
        }
    };
    progBar.progressProperty().bind(task.progressProperty());
    Thread t = new Thread(task);       
    t.start();
}

Nur eine Frage habe ich da noch. Und zwar muss ich, wenn ich ein Label neu beschriften möchte, es in Platform.runLater(...) packen. Wenn ich dies nicht tue, wird folgende Exception geworfen:

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread;

Meine Frage ist nun, warum ich ein Textfeld neu beschriften kann, aber kein Label...!?
 

dzim

Top Contributor
Zum Service: Schau mal bitte hier im Thread Meine ProgBar und ProgIndi werden nicht aktualisiert.
Da habe ich mal ein Progress-Beispiel (mit Service) gebaut, dass du als Basis nutzen kannst. Ich war auch kurz davor auf Task zurück zu gehen, hab es aber doch hinbekommen.
Zur Exception: Es steht doch da "Not on FX application thread". Du hast versucht die UI von einem anderen als dem "JavaFX application thread" (dem UI-Thread) upzudaten. Konrekt: sämtliche #setText und #setCursor (mit zwei oder drei Ausnahmen). Die einzige Methode, die du nicht auf dem UI-Thread ausführen musst ist updateProgress(x, y); Darum kümmert sich die API selbst. Alles andere wird in die Platform#runLater(Runnable) Aufrufe verpackt, wie du es ein paar Mal gemacht hast. Um das etwas übersichtlicher zu machen, solltest du jedoch Lambdas nutzen:
Java:
Platform.runLater(() -> lbl3.setText(":)"));
 

da921610

Aktives Mitglied
@dzim :
ich habe jetzt folgenden Code von deinem Beispiel mal genommen:
Java:
private static class MyFancyService extends Service<Long> {
      
        private LongProperty countTo = new SimpleLongProperty(0L);
        private LongProperty current = new SimpleLongProperty(0L);
      
        public MyFancyService(long countTo) {
            this.countTo.set(countTo);
        }
      
        @SuppressWarnings("unused")
        public LongProperty countToProperty() {
            return countTo;
        }
      
        @SuppressWarnings("unused")
        public LongProperty currentProperty() {
            return current;
        }
      
        @Override
        protected Task<Long> createTask() {
            return new Task<Long>() {
                @Override
                protected Long call() throws Exception {
                    current.set(0L);
                    try {
                        Platform.runLater(() -> lbl2.setText("LOOOL"));
                        for (int i = 0; i <= countTo.get(); i++) {
                            if (isCancelled())
                                break;
                            current.set(i);
                            updateProgress(current.get(), countTo.get());
                            Thread.sleep(100);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return current.get();
                }
            };
        }
    }

wo darin würde ich jetzt ein Label neu beschriften?

In der Zeile :
Java:
Platform.runLater(() -> lbl2.setText("LOOOL"));
Wird mir von Eclipse ein Fehler angezeigt:


Multiple markers at this line
- Cannot make a static reference to the non-static field lbl2
- Line breakpoint:MainViewController$MyFancyService [line:
85] - call()

Kannst du/ könnt ihr mir bitte nochmal helfen ?
 
Zuletzt bearbeitet:

dzim

Top Contributor
Der Fehler sagt es doch (im Prinzip ;)) schon: lbl2 müsste final sein. Das Problem ist, das Lambdas ja im wesentlichen nur eine hübsche Variante der anonymen Klassen sind. Wenn lbl2 nicht als globale Variable definiert ist, oder eben zuvor als final deklariert werden.
Aber: MyFancyService ist eine statische Klasse, hat daher Implementierungsbedingt keinen Zugriff auf die die umgebende Klasse. Also entweder den Konstruktor des Service aufwerten und alle upzudatenden Text/Label-Nodes rein (oder alternativ auch viele Setter und alles so übergeben), oder das static wegnehmen.

Würde aber an deiner Stelle eher die Setter-Variante fahren, denn mittelfrististig solltest du aus dem Service eine eigene Klasse (eigenes Java-File) machen. Ich habe es nur für das Beispiel als innere statische Klasse gemacht.
 

dzim

Top Contributor
Haha. Ja, Ok. Invokedynamic ist das Stichwort. Ja, das war mir schon klar, aber es lädt sich mit anonymen Klassen am besten beschreiben!
Das es eben keine anonymen Klassen sind, merkt man an manchen Stellen, wo man dann eben auf nicht-Finale Variablen zugreifen kann.
Aber hat recht, man sollte vielleicht nicht zu oft auf dieses zu einfach Schaubild zurückgreifen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Juelin Probleme bei Stage.close() AWT, Swing, JavaFX & SWT 23
XWing Swing Image anzeigen und probleme mit klassen AWT, Swing, JavaFX & SWT 3
E repaint Probleme AWT, Swing, JavaFX & SWT 13
mananana Mögliche probleme die in einer GUI passieren Können AWT, Swing, JavaFX & SWT 6
S GridBagLayout - Probleme mit Bilderanzeige AWT, Swing, JavaFX & SWT 3
I Probleme beim Drucken auf einen PDF-Drucker AWT, Swing, JavaFX & SWT 8
J Probleme mit idividueller Tablecell AWT, Swing, JavaFX & SWT 0
D JavaFX Probleme beim nachtäglichen hinzufügen der jfx dependency AWT, Swing, JavaFX & SWT 7
J Probleme mit InputDialog AWT, Swing, JavaFX & SWT 4
D JavaFX TextArea Probleme bei langen Zeilen AWT, Swing, JavaFX & SWT 1
G JavaFX SplitPane Anwendung - Controller Probleme AWT, Swing, JavaFX & SWT 5
K Probleme bei der Erstellung und Ausführung einer Jar Datei AWT, Swing, JavaFX & SWT 2
B Probleme Action Listener Taschenrechner AWT, Swing, JavaFX & SWT 27
pph080560 JavaFX Probleme mit FX AWT, Swing, JavaFX & SWT 3
M Probleme mit OpenJDK AWT, Swing, JavaFX & SWT 6
B 2D-Grafik paintcomponent Probleme beim zeichnen AWT, Swing, JavaFX & SWT 10
B Swing Probleme mit dem Layout AWT, Swing, JavaFX & SWT 1
L JavaFX Probleme beim Installieren JavaFX11 / JavaFX12 -- Eclipse 2019-03 AWT, Swing, JavaFX & SWT 3
Fiedlerdan Image-Pfad Probleme nach Export aus Eclipse AWT, Swing, JavaFX & SWT 31
H JFreeChart - DemoDataSetFactory Probleme AWT, Swing, JavaFX & SWT 1
H LayoutManager Probleme mit Positionierung/Abständen der Komponenten AWT, Swing, JavaFX & SWT 14
A Probleme mit gridheight (GridBagLayout) AWT, Swing, JavaFX & SWT 6
U Opaque Probleme AWT, Swing, JavaFX & SWT 3
H JavaFX Probleme Beim Wechseln der scene als .fxml AWT, Swing, JavaFX & SWT 7
F JavaFX Probleme beim automatischen Konvertieren AWT, Swing, JavaFX & SWT 4
S Probleme mit JComboboxen(?) AWT, Swing, JavaFX & SWT 18
S Swing Probleme mit MigLayout AWT, Swing, JavaFX & SWT 2
C Probleme mit createImage AWT, Swing, JavaFX & SWT 1
J Probleme mit contex Menu (javafx) AWT, Swing, JavaFX & SWT 1
J Probleme bei GameofLife AWT, Swing, JavaFX & SWT 24
S JavaFx - Button ActionEvent Probleme AWT, Swing, JavaFX & SWT 3
T Swing Probleme mit repaint() bzw. JScrollPane AWT, Swing, JavaFX & SWT 7
ImperatorMing JavaFX Probleme mit WindowEvent AWT, Swing, JavaFX & SWT 0
ImperatorMing JavaFX Probleme mit WindowEvent AWT, Swing, JavaFX & SWT 5
J LayoutManager GridBagLayout, probleme mit Anordnung von Objekten AWT, Swing, JavaFX & SWT 6
T Java FX Probleme beim befüllen eines Tableviews AWT, Swing, JavaFX & SWT 5
S AWT Probleme beim Zeichnen AWT, Swing, JavaFX & SWT 3
A Swing Probleme mit dem adden von JButtons zur JScrollPane AWT, Swing, JavaFX & SWT 2
D Swing Probleme mit dem Resizing AWT, Swing, JavaFX & SWT 7
G Probleme mit TextArea AWT, Swing, JavaFX & SWT 5
G JFrame Probleme AWT, Swing, JavaFX & SWT 2
K Probleme beim JPasswordField AWT, Swing, JavaFX & SWT 11
G Cardlayout Refresh Probleme AWT, Swing, JavaFX & SWT 2
J Swing Probleme mit ListSelectionListener(), Inhalte der JList werden gelöscht? AWT, Swing, JavaFX & SWT 6
K Probleme beim zeichnen mit paintComponent() AWT, Swing, JavaFX & SWT 1
M JButton Probleme AWT, Swing, JavaFX & SWT 14
L Probleme mit Programm AWT, Swing, JavaFX & SWT 13
blazingblade komischerweise probleme mit jtextfield.gettext() AWT, Swing, JavaFX & SWT 9
Xanny 2D-Grafik Beginner! Probleme mit Swing, Gprahics class und paint AWT, Swing, JavaFX & SWT 13
Sin137 LayoutManager GridBagLayout Probleme AWT, Swing, JavaFX & SWT 6
H Netbeans Designer: Probleme mit JPanel und JFrame AWT, Swing, JavaFX & SWT 2
M Swing Probleme mit Frame.pack() AWT, Swing, JavaFX & SWT 1
C Java FX Probleme beim Schließen einer Stage AWT, Swing, JavaFX & SWT 11
M Swing JProgressbar und Outoputstream probleme AWT, Swing, JavaFX & SWT 2
S Swing Probleme mit transparenz der Hintergrundfarbe und JRadioButtons AWT, Swing, JavaFX & SWT 2
Z Probleme mit JPanel's AWT, Swing, JavaFX & SWT 6
T Probleme mit Anzeige von Elementen im JPanel AWT, Swing, JavaFX & SWT 1
Shams Probleme bei dem Hinzufügen von Komponenten zu einem JFrame AWT, Swing, JavaFX & SWT 3
A Swing Probleme mit JScrollPane AWT, Swing, JavaFX & SWT 6
M Layout-Probleme unter Swing AWT, Swing, JavaFX & SWT 5
H Swing Probleme beim erstellen eines neuen Objektes durch einen Button AWT, Swing, JavaFX & SWT 10
J JavaFX JavaFX Probleme bei der Anzeige von Text AWT, Swing, JavaFX & SWT 18
A Probleme mit TilledBorder("***") AWT, Swing, JavaFX & SWT 4
F Bildschirmschoner Probleme mit Preview AWT, Swing, JavaFX & SWT 8
X Panel Probleme (Tetris) AWT, Swing, JavaFX & SWT 8
N JTable probleme AWT, Swing, JavaFX & SWT 5
B Probleme bei ImageIO.read (?!) AWT, Swing, JavaFX & SWT 9
P JFrame Location-/Size-Probleme AWT, Swing, JavaFX & SWT 5
U LayoutManager Probleme mit Layouts AWT, Swing, JavaFX & SWT 5
C 3 kleine Probleme... AWT, Swing, JavaFX & SWT 13
L NullpointerException und Probleme mit repaint() AWT, Swing, JavaFX & SWT 11
A Probleme mit 2 JFrames in einem Programm AWT, Swing, JavaFX & SWT 7
K LayoutManager Probleme mit 2 Komponenten AWT, Swing, JavaFX & SWT 9
C Probleme mit Buttons und einem ActionListener AWT, Swing, JavaFX & SWT 2
M Probleme mit Verkleinern eines GUI AWT, Swing, JavaFX & SWT 7
B Swing label.setText() macht probleme AWT, Swing, JavaFX & SWT 5
B ImageIcon - Probleme mit dem Dateipfad AWT, Swing, JavaFX & SWT 5
H JTree Probleme AWT, Swing, JavaFX & SWT 9
F Probleme mit (Graphics g) II AWT, Swing, JavaFX & SWT 4
F Probleme mit (Graphics g) AWT, Swing, JavaFX & SWT 3
K 2D-Grafik .GIF macht mir Probleme AWT, Swing, JavaFX & SWT 14
B Probleme bei Sortierung einer Tabelle mit DefaultTableModel AWT, Swing, JavaFX & SWT 6
T JTable Graphik probleme AWT, Swing, JavaFX & SWT 3
H GridBagLayout macht Probleme... AWT, Swing, JavaFX & SWT 4
vandread Swing Probleme mit jTextField im zusammenspiel mit einem Einblendeffekt (inkl. KSKB) AWT, Swing, JavaFX & SWT 6
S Swing Lauftext Performance Probleme, in größerer Anwendung AWT, Swing, JavaFX & SWT 6
B Infolabel Probleme mit Paint() ? AWT, Swing, JavaFX & SWT 8
P Probleme mit setIconImage AWT, Swing, JavaFX & SWT 8
U Swing Probleme mit Asynchronen Prozessen und Swing: AWT, Swing, JavaFX & SWT 3
das-mo Probleme mit GridBagLayout AWT, Swing, JavaFX & SWT 6
N 2D-Grafik 2 Probleme beim zeichnen AWT, Swing, JavaFX & SWT 18
L Probleme mit JPanel AWT, Swing, JavaFX & SWT 8
D Probleme bei Übertrag von ArrayList in Jtable AWT, Swing, JavaFX & SWT 2
G kleinere Probleme mit GUI AWT, Swing, JavaFX & SWT 2
G Mehrere Probleme mit Java's GUI AWT, Swing, JavaFX & SWT 6
M Swing Erste Schritte mit der GUI, viele Probleme AWT, Swing, JavaFX & SWT 36
J GUI-Aktualisierungs-Probleme AWT, Swing, JavaFX & SWT 4
B Performance-Probleme AWT, Swing, JavaFX & SWT 17
I Probleme if-Anweisung AWT, Swing, JavaFX & SWT 26
D Swing Probleme bei transparenten Hintergrund im JTextField AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben