Countdown in Label anzeigen

fabipfolix

Mitglied
Hallo,

ich scheitere leider an dem Versuch einen Timer, welcher in der Konsole problemlos funktioniert, in einer GUI anzeigen zu lassen.

Das Problem ist, dass ich innerhalb des TimerTasks nicht auf mein Label, welches die Zeit anzeigen soll, zugreifen kann.

Java:
package application;

import java.util.Timer;
import java.util.TimerTask;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

public class SampleController {
   
    static int seconds,interval;
   
    static Timer timer;
   
    @FXML
    private Button btnStart;

    @FXML
    private Label LabelTime;

    @FXML
    void btnStartPressed(ActionEvent event) {
        countdown();
    }

public void countdown() {
       
        int seconds = 60;
       
         int delay = 1000;
            int period = 1000;
            timer = new Timer();
            interval = (seconds);
            System.out.println(seconds);
           
            timer.scheduleAtFixedRate(new TimerTask() {

                public void run() {
                   

                    System.out.println(setInterval());                
//                  LabelTime.setText(""+setInterval());  Das ist das Problem

                }
            }, delay, period);
       
    }
   
    private static final int setInterval() {
        if (interval == 1)
            timer.cancel();
        return --interval;
    }
}
Falls die Antwort nicht sowieso klar ist, hier die Error-Message, wenn ich auf das Label zugreifen will:
Code:
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
    at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
    at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
    at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
    at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
    at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
    at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
    at javafx.scene.control.Labeled.setText(Labeled.java:145)
    at application.SampleController$1.run(SampleController.java:45)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)
Weiß jemand, wie ich das richtig mache?
Das selbe Problem habe ich auch, wenn etwas in einem anderen Thread abläuft.
 

fabipfolix

Mitglied
Kurze Antwort: Du greifst auf ein UI-Element außerhalb des UI-Threads zu. Lösung: die Operation in Platform.runLater ausführen.

https://stackoverflow.com/questions...alstateexception-not-on-fx-application-thread

Wie ich Platform.runLater() bei mir benutzte bekomm ich leider nicht do ganz hin.

Ich würde das ganze jetzt versuchen mit einem ScheduledService, welcher Thread.sleep(1) beinhaltet und dann 45 mal wiederholt wird. Und bei jedem onSucceded Event das Label um 1 verringern.

Wäre die andere Möglichkeit leichter/Funktioniert das oben genannte überhaupt? (kann es leider erst später testen)?
 

fabipfolix

Mitglied
Platform.runLater so:
Java:
Platform.runLater(() -> LabelTime.setText(""+setInterval()));

Und ein ScheduledService lässt sich schedulen.. ScheduledService#setPeriod, ScheduledService#setDelay und hat eine prop ReadOnlyObjectProperty<V> lastValue, die du an die Textproperty eines Textfeldes binden kannst.

Jetzt wo ich das les macht das mit runLater natürlich Sinn...
Irgendwie war ich überzeugt davon, dass es man damit einen Task o. ä ausführt.

Danke für eure Hilfe :D
 

fabipfolix

Mitglied
Den Countdown hab ich jetzt in ein anderes Programm implementiert. Im Prinzip funktioniert er auch, nur in der neuen Version entsteht beim zweiten Durchlauf des Timers ein Fehler, wenn das Label überschrieben werden soll.
Der Output in der Konsole funktioniert.

Es muss ja daran liegen, dass der Timer in einem ScheduledService aufgerufen wird, denn in der obigen Version hat es ja funktioniert.

Java:
package sample;

//Imports ausgelassen

public class Connector{
   
    ScheduledService service;
    MyTimer myTimer = new MyTimer();

    public Connector(Controller controller){

            service = new ScheduledService() {
                @Override
                protected Task createTask() {
                    return new Task() {
                        @Override
                        protected Object call() throws Exception {

                            if (getActive()) {
                   
                                 myTimer = new MyTimer();

                                 try {
                                        myTimer.countdown(15000, controller); //ERROR nach zweitem Durchlauf
                                 }catch(Exception e){
                                        System.out.println("Error at Timer");
                                        e.printStackTrace();
                                 }
                               
                                 System.out.println("[INFO] Start Timer");

                                 try {
                                      Thread.sleep(15000);
                                 } catch (InterruptedException e) {
                                       e.printStackTrace();
                                }

                                return null;

                            }


                    };
                }
            };
        }

}

Java:
package sample;

public class MyTimer {
    static int interval;
    static Timer timer=new Timer();
    Controller controller;

    public void countdown(int duration, Controller controller) {
            this.controller = controller;

            int delay = 1000;
            int period = 1000;

            interval = (duration);
            System.out.println("[TIMER] "+duration+" Seconds left!");

            Platform.runLater(() ->controller.getLabelTime().setText(""+duration));

            timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {

                    int timeLeft = setInterval();

                    System.out.println("[TIMER] "+timeLeft +" Seconds left!");
                    Platform.runLater(() -> controller.getLabelTime().setText(""+timeLeft));

                    if(timeLeft<=5){
                       Platform.runLater(() ->controller.getBackground().setStyle("-fx-background-color: #ff0000"));
                    } else if(timeLeft<=10){
                       Platform.runLater(() ->controller.getBackground().setStyle("-fx-background-color: #ff9400"));
                    }

                    if(!controller.isActive()|| timeLeft<=0)
                        stopTimer();

             }
        }, delay, period);
    }

    private static final int setInterval() { 
        return --interval;
    }

      public void stopTimer(){

            timer.cancel();
            timer.purge();
            Platform.runLater(() -> controller.getBackground().setStyle(null));
            Platform.runLater(() -> controller.getLabelTime().setText("..."));


       }
}

Tut mir leid, falls die Formatierung nicht ganz passt, aber das wurde beim kopieren gerade wild zerstreut.
 

looparda

Top Contributor
Was für ein Fehler?
Der Controller fehlt - benutzt du überhaupt Funktionalität des ScheduledService außer die Taskausführung?
Was hast du überhaupt vor? Wieso startest du mehrere Timer?
 

fabipfolix

Mitglied
Was für ein Fehler?
Tut mir leid, den hab ich grad ganz vergessen.
Hier:
java.lang.IllegalStateException: Timer already cancelled.
at java.util.Timer.sched(Timer.java:397)
at java.util.Timer.scheduleAtFixedRate(Timer.java:328)
at utils.fxutils.MyTimer.countdownForDefTimer(MyTimer.java:81)
at sample.Connector$1$1.call(Connector.java:57)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at javafx.concurrent.Service.lambda$null$493(Service.java:725)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.concurrent.Service.lambda$executeTask$494(Service.java:724)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

Das Problem scheint ja zu sein, dass der Timer gecancelt wurde, aber das wurde er doch oben ebenso, oder?

Der Controller fehlt
Der Controller tut nicht wirklich was zur Sache, wird ja nur für die Getter verwendet, welche Label etc zurückgeben. Das funktioniert problemlos.

benutzt du überhaupt Funktionalität des ScheduledService außer die Taskausführung?
Ich hab ein if statement ausgelassen, welches in noch einer neuen Klasse etwas überprüft, gibt aber auch nur true/false zurück, also eigentlich auch irrelevant und der Sinn hinter dem Scheduled Service ist, dass es sich wiederholt. Theoretisch wäre also auch ein Service mit einer while möglich.

Was hast du überhaupt vor? Wieso startest du mehrere Timer?
Ich will überprüfen an einem Screenshot überprüfen ob ein bestimmter Pixel eine passende Farbe hat. Wenn das zutrifft startet der Countdown. (das ist das oben genannte If-Statement)
Und mehrere Timer starten, da das mehrmals geschehen soll.
 

looparda

Top Contributor
Ich hab versucht es zu reproduzieren und den Kram mit dem Background und isActive rausgeschmissen, da mir der Controller fehlt. Aber ich erhalte keine Exception.

Ich habe die Sekunden von 1500 auf 5 gestellt und kann es nun reproduzieren.

Das Problem ist der
Java:
public class MyTimer {
    static Timer timer=new Timer();
in deinem MyTimer. Von diesem hast du nur eine Instanz zur Laufzeit und du cancelst ihn ein zweites mal.
 
Zuletzt bearbeitet:

fabipfolix

Mitglied
Java:
public class MyTimer {
    static Timer timer=new Timer();
in deinem MyTimer. Von diesem hast du nur eine Instanz zur Laufzeit und du cancelst ihn ein zweites mal.

Aber wieso tritt der Fehler dann auf sobald ich den Timer ein zweites Mal starte und nicht wenn ich ihn zum zweiten mal cancel.

Diese Zeile verursacht den Fehler:
Java:
timer.scheduleAtFixedRate(new TimerTask() {
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Swing Countdown mit Minuten und Sekunden AWT, Swing, JavaFX & SWT 9
S Swing Timer, Countdown AWT, Swing, JavaFX & SWT 2
N Countdown verursacht Speicher Leak AWT, Swing, JavaFX & SWT 7
H JavaFX Label.Text mit bind an DoubleProperty binden AWT, Swing, JavaFX & SWT 3
izoards Ausdruck auf Label Drucker AWT, Swing, JavaFX & SWT 1
N JavaFX Unicode zeichnen in javafx Label verwenden AWT, Swing, JavaFX & SWT 2
H RPG Programmieren, label.setLocation funktioniert nicht AWT, Swing, JavaFX & SWT 7
Jose05 Javafx Label Höhe=Breite AWT, Swing, JavaFX & SWT 1
N javafx Position der Bustaben finden label AWT, Swing, JavaFX & SWT 1
N Label Schriftart Ändern javafx AWT, Swing, JavaFX & SWT 2
D JavaFX Label flackert beim aktualisieren AWT, Swing, JavaFX & SWT 12
J JavaFX Label aktualisieren AWT, Swing, JavaFX & SWT 18
M JavaFX javaFX Label-Text wird nicht gesetzt AWT, Swing, JavaFX & SWT 3
T Anderen Java Code durch Code kompilieren und Fehler in Label ausgeben AWT, Swing, JavaFX & SWT 5
I BoxLayout zentriert Label nicht AWT, Swing, JavaFX & SWT 7
B Ausgaben einer Umrechnung vom Textfeld in ein Label AWT, Swing, JavaFX & SWT 2
R JavaFX Label oder Imageview anzeigen mit Buttonklick AWT, Swing, JavaFX & SWT 4
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
A Inhalt wechseln bei Klick auf Label AWT, Swing, JavaFX & SWT 8
ralfb1105 JavaFX Label lässt sich innerhalb service Task nicht updaten? AWT, Swing, JavaFX & SWT 22
Trèfle JavaFX Formattierung im Label AWT, Swing, JavaFX & SWT 3
ralfb1105 JavaFX Wie Text Label in neuem Window von Main Stage setzen? AWT, Swing, JavaFX & SWT 6
H JavaFX - Label aktualisieren AWT, Swing, JavaFX & SWT 1
J Dateiname im Label einblenden AWT, Swing, JavaFX & SWT 4
C SWT autosize bei gc.drawString() auf einem Label AWT, Swing, JavaFX & SWT 7
xYurisha Aus einer Gui Buttons, Label und ProgessBars entfernen AWT, Swing, JavaFX & SWT 4
T Label wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
zhermann FX Label text wird nicht richtig angezeigt AWT, Swing, JavaFX & SWT 12
zhermann NullPointerException bei Label.setText() AWT, Swing, JavaFX & SWT 5
T JavaFX Label mit mehreren Images AWT, Swing, JavaFX & SWT 11
Kanda Sorata Inhalt einer .txt Datei einlesen und in ein Label einfügen (JavaFX) AWT, Swing, JavaFX & SWT 2
L JavaFX ContextMenu bei Label mit Linksklick AWT, Swing, JavaFX & SWT 4
J JavaFX - Felder (Label) in einer ForSchleife bearbeiten AWT, Swing, JavaFX & SWT 4
N Anordnung der Label AWT, Swing, JavaFX & SWT 3
N Swing Label auf Panel legen.. AWT, Swing, JavaFX & SWT 2
D JavaFX Label lässt sich nicht mehrmals färben AWT, Swing, JavaFX & SWT 7
R Swing JLabel berührung an einem anderen Label prüfen AWT, Swing, JavaFX & SWT 3
U Java FX Zusätzliches Label per Knopfdruck während der Laufzeit auf Panel einfügen. AWT, Swing, JavaFX & SWT 2
M Text in einem Label fett setzen AWT, Swing, JavaFX & SWT 4
D Swing JFreeChart Crosshair Label - setPreferredSize oder ähnliches, aber wo ? AWT, Swing, JavaFX & SWT 1
T CSS Rechtsbüdniges Label mit Zwei Zeilen AWT, Swing, JavaFX & SWT 7
J JavaFX Translation Text/Label AWT, Swing, JavaFX & SWT 2
Tom299 JavaFX Text oder Label benutzen AWT, Swing, JavaFX & SWT 4
C Textfeld und Label werden nicht angezeigt (Ubuntu) AWT, Swing, JavaFX & SWT 2
C SWT Treeview mit Bilder im Label verändert Expanded Icon AWT, Swing, JavaFX & SWT 1
Augenblau JavaFX Wechselnde Werte in Label darstellen AWT, Swing, JavaFX & SWT 7
V Swing Brauche Hilfe mit Label AWT, Swing, JavaFX & SWT 3
S JButton-Label vergrößern AWT, Swing, JavaFX & SWT 2
D Java Swing, Label lässt sich nicht mit Checkboxen/Knopf verändern AWT, Swing, JavaFX & SWT 2
M label mit icon verschieben. AWT, Swing, JavaFX & SWT 1
B Swing JXMapKit Mausemove in Label anzeigen AWT, Swing, JavaFX & SWT 0
K Bild in Label wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
S JButton u. Label auf paint-Methode AWT, Swing, JavaFX & SWT 1
G Label wird nicht erstellt AWT, Swing, JavaFX & SWT 0
7 AWT problem: KeyListener/ test im Label umändern AWT, Swing, JavaFX & SWT 4
W JavaFX Label in Controller-Klasse in einer anderen Controller-Klasse ändern AWT, Swing, JavaFX & SWT 9
D Swing [Frage] ComboBox + Label AWT, Swing, JavaFX & SWT 3
G Label erstellen AWT, Swing, JavaFX & SWT 6
U Label zeigt nicht überall HTML Zeichen AWT, Swing, JavaFX & SWT 3
F JavaFX label.getWidth() AWT, Swing, JavaFX & SWT 2
T Swing Label aus anderer Methode bearbeiten AWT, Swing, JavaFX & SWT 2
N Input/Output Stream werte in Label anzeigen. AWT, Swing, JavaFX & SWT 6
R JavaFX Label ändern in aufgerufener AnchorPane AWT, Swing, JavaFX & SWT 3
B Swing label.setText() macht probleme AWT, Swing, JavaFX & SWT 5
G JavaFX CSS: Label in GridPane rechts ausrichten AWT, Swing, JavaFX & SWT 9
T Swing Aktuelle Größe eines Textes in einem Label darstellen AWT, Swing, JavaFX & SWT 3
KrokoDiehl Swing Buchstaben im Label anders färben AWT, Swing, JavaFX & SWT 4
K Zugriff auf Label und Ereignisbehandlung durch zwei Handlerklassen AWT, Swing, JavaFX & SWT 3
P Label rotieren mit Timer AWT, Swing, JavaFX & SWT 5
C Label wird nicht an der richtigen Position angezeigt.. AWT, Swing, JavaFX & SWT 7
H Label mit Icon positionieren AWT, Swing, JavaFX & SWT 14
E Netbeans: Buttons mit Label bzw. Rahmen unterlegen AWT, Swing, JavaFX & SWT 8
J resize - Label bleibt erst schwarz AWT, Swing, JavaFX & SWT 4
T label überschriebt seine werte-SWT AWT, Swing, JavaFX & SWT 3
O Swing JTree um Label (oder Panel) erweitern AWT, Swing, JavaFX & SWT 9
D Label über JScrollPane AWT, Swing, JavaFX & SWT 3
N Label auf Hauptfenster manipulieren AWT, Swing, JavaFX & SWT 2
S VAADIN: Problem mit Label AWT, Swing, JavaFX & SWT 18
P Ausgabe Label AWT, Swing, JavaFX & SWT 6
GUI-Programmer Informations-Panel an Label AWT, Swing, JavaFX & SWT 2
S ImageIcon von Label entfernen AWT, Swing, JavaFX & SWT 9
B Label breite ermitteln vor dem rendern? AWT, Swing, JavaFX & SWT 7
A Bekomme das Label nicht in die Mitte von Reihe AWT, Swing, JavaFX & SWT 7
H SWT Markierbares Label AWT, Swing, JavaFX & SWT 8
A Swing Box Label ausrichten AWT, Swing, JavaFX & SWT 3
R Label in den Vordergrund einblenden AWT, Swing, JavaFX & SWT 5
J Hintergrund Label-Frame AWT, Swing, JavaFX & SWT 3
O Swing Label(bzw. Grafik) verdekt von anderm Label AWT, Swing, JavaFX & SWT 2
A TextField und Label AWT, Swing, JavaFX & SWT 8
L Label dynamisch awt AWT, Swing, JavaFX & SWT 2
J Label mit transparentem hintergrund - geht das? AWT, Swing, JavaFX & SWT 21
B Die Werte von getLocation() im Label anzeigen AWT, Swing, JavaFX & SWT 4
Avalarion SWT Listener auf Label oder Text Teile AWT, Swing, JavaFX & SWT 10
C Label Hintergrundbild mit Text AWT, Swing, JavaFX & SWT 6
A SWT - Farbe von Text auf Label ändern AWT, Swing, JavaFX & SWT 2
M gridbaglayout - abstand bei label und field AWT, Swing, JavaFX & SWT 8
hdi SWT Label Text vertikal zentrieren AWT, Swing, JavaFX & SWT 6
T In einem Label scrollen AWT, Swing, JavaFX & SWT 3
Spot84 swt label zeilenumbruch will nicht funktionieren AWT, Swing, JavaFX & SWT 1
L JFreeChar Label für StackedBar AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben