IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: 5 minutový countdown (v JavaFX)

Aktivity
Avatar
Vojtěch Bešťák:21.5.2016 10:10

Zdravím, snažím se vytvořit 5 minutový countdown za pomoci kódu, který mi poradil Atrament
Zde je můj dosavadní zdrojový kód:

@FXML
    private void handlestartButtonAction(ActionEvent event)
    {


        casSekundy.setCycleCount(countDownSeconds2); //nastaví se počet opakování, tedy pošet sekund k odpočtu
        casSekundy.play(); //a jedeme...
        startButton.setVisible(false);

    }
private int countDownSeconds2 = 59; // bude se odpočítávat od 3 do nuly
    private final StringProperty casSekundyValue = new SimpleStringProperty(countDownSeconds2 + ""); //StringProperty countDownValue se později 'přibinduje' k countdownLabel, když se změní hodnota  countDownValue, změní se i countdownLabel
    private final StringProperty casMinutyValue = new SimpleStringProperty(4 + "");
//nyní vytvoříme timeline s duration 1 sekunda
    private final Timeline casSekundy = new Timeline(new KeyFrame(Duration.seconds(1), (e) -> {

        int i = Integer.parseInt(casSekundyValue.getValue()) - 1; //koukneme jaka je hodnota countDownValue a snížíme o jedna
        casSekundyValue.setValue(i + "");//nastavíme countDownValue novou hodnotu
        if (i == 0)
        {
            casSekundyValue.setValue("59");
            odeberMinuty();
            cas();
        }




}));
    public void cas()
        {
            casSekundy.setCycleCount(countDownSeconds2); //nastaví se počet opakování, tedy pošet sekund k odpočtu
            casSekundy.play(); //a jedeme...
        }

    public void odeberMinuty()
    {
        int j = Integer.parseInt(casMinutyValue.getValue()) - 1;
        casMinutyValue.setValue(j + "");
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        countdownLabel.textProperty().bind(countDownValue);
        casSekundyLabel.textProperty().bind(casSekundyValue);
        casMinutyLabel.textProperty().bind(casMinutyValue);
        countdownLabel.setVisible(false);


    }

Moje představa byla taková, že se nejdříve odečte 59 sekund z

casSekundyValue

a poté se díky metodě

odeberMinuty()

a

cas()

odebere 1 minuta a znovu se spustí odpočítávání 59 sekund.

Ovšem výsledek byl takový, že po spuštění aplikace tlacitkem se odečetlo prvních 59 sekund, poté se minuty změnili ze 4 na 3 a sekundy se vrátili zpět na 59. Ale odpočítávání další minuty nezačalo.
Pomůže mi prosím někdo, a řekne mi co mám špatně?

 
Odpovědět
21.5.2016 10:10
Avatar
Odpovídá na Vojtěch Bešťák
Petr Štechmüller:21.5.2016 12:25

Ahoj, co na to jít trochu jinak. Pokud chceš odpočet 5 minut, tak ten interval čas sekundy nastav na hodnotu 5*60. Pak místo kontroly, zda-li i==0 můžeš kontrolovat něco ve stylu i%60==0. Tímto zkontrolujes, jestli je hodnota i násobek 60, neboli jestli ubehla minuta. Pokud se podmínka splní, tak můžeš odečíst minutu a nemusí s restartovat žádném timer...

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
21.5.2016 12:25
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Odpovídá na Vojtěch Bešťák
Erik Šťastný:21.5.2016 13:16

Ahoj ahoj, nechci ti tu myšlenku nějakou celou rozbíjet, ale nešlo by vyjít z aktuálního systémového času a založit to na tom? :)

 
Nahoru Odpovědět
21.5.2016 13:16
Avatar
Odpovídá na Petr Štechmüller
Vojtěch Bešťák:21.5.2016 15:53

Děkuji dobrý nápad, zkusil jsem to nějak předělat:

    @FXML
    private void handlestartButtonAction(ActionEvent event)
    {
        cas();
        startButton.setVisible(false);
    }
    private int zbyvaMinut = 5;
    private int zbyvaSekund = zbyvaMinut*60;
    private int zbyvaMinutAktualne = zbyvaMinut;
    private int zbyvaSekundAktualne = zbyvaSekund;

    private final StringProperty casSekundyValue = new SimpleStringProperty(zbyvaSekund + "");
    private final StringProperty casMinutyValue = new SimpleStringProperty(zbyvaMinut + "");

    private final Timeline casSekundy = new Timeline(new KeyFrame(Duration.seconds(1), (e) -> {
        zbyvaSekundAktualne--;
        int vytisk = (zbyvaSekundAktualne - ((zbyvaMinutAktualne - 1) * 60)) -1;
        casSekundyValue.setValue(String.format("%02d", vytisk));


        if(zbyvaSekundAktualne == zbyvaSekund - 1)
        {
            odeberMinuty();
        }
        if(zbyvaSekundAktualne == 241 || zbyvaSekundAktualne == 181 || zbyvaSekundAktualne == 121 || zbyvaSekundAktualne == 61)
        {
            odeberMinuty();
            zbyvaMinutAktualne--;
        }




}));


    public void cas()
    {
        casSekundy.setCycleCount(zbyvaSekund); //nastaví se počet opakování, tedy počet sekund k odpočtu
        casSekundy.play();

    }


    public void odeberMinuty()
    {
        int j = Integer.parseInt(casMinutyValue.getValue()) - 1;
        casMinutyValue.setValue(String.format("%02d", j));
        zbyvaMinut--;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        countdownLabel.textProperty().bind(countDownValue);
        casSekundyLabel.textProperty().bind(casSekundyValue);
        casMinutyLabel.textProperty().bind(casMinutyValue);
        countdownLabel.setVisible(false);

Po tomto to již ve své podstatě odpočítává 5 minut, ale na úplném začátku před zmáčknutí tlačítka se zobrazuje: viz. obrazek - 5 minut 300 sekund (tedy počáteční hodnoty countdownu)

Po zmáčknutí tlačítka se 1 sekudnu nic neděje, a pak se najednou objeví 04:58. To znamená, že z nějakého důvodu nezobrazí 59.

Další věc, která je tak trochu rozbitá je přechod jednotlivých minut. casMinutyLabel se v GUI zmenší o 1 ve chvíly, kdy v casSekundyLabel je teprve 00.

Nezná prosím někdo řešení těchto problémů?

Editováno 21.5.2016 15:53
 
Nahoru Odpovědět
21.5.2016 15:53
Avatar
Atrament
Tvůrce
Avatar
Odpovídá na Vojtěch Bešťák
Atrament:21.5.2016 17:00

Já bych na to šel ještě trochu jinak :) Změnil bych nastavení té timeline tak aby neodpočítávala konkrétní počet cyklů, ale aby běžela do nekonečna setCycleCount(Ti­meline.INDEFI­NITE). Tím by mi vlastně odtikávala sekundy. Při každém 'tiknutí' bych zkontroloval jestli jsou minuty a sekundy už nula, a když jo tak bych tu timeline stopnul a provedl to co chceš provést po skončení odpočtu. Když ne tak bych ubral jednu sekundu, pokud by se tím dostal počet sekund na nulu tak bych koukl jestli jsou minuty víc než 0 a když jo tak bych ubral minutu a nastavil na sekundách 59.

 
Nahoru Odpovědět
21.5.2016 17:00
Avatar
Odpovídá na Atrament
Petr Štechmüller:21.5.2016 17:10

Tak to je podobné, co jsem já navrhoval s tím rozdílem, že znám předem dobu, jak dlouho to poběží...

Nahoru Odpovědět
21.5.2016 17:10
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Vojtěch Bešťák:21.5.2016 17:39

Z nějakého důvodu mi tento kód hází po zmáčnkutí tlačítka chybu:
Kód:

    @FXML
    private void handlestartButtonAction(ActionEvent event)
    {
        countdownLabel.setVisible(true);
        cas();
        startButton.setVisible(false);
    }

    private final StringProperty casSekundyValue = new SimpleStringProperty();
    private final StringProperty casMinutyValue = new SimpleStringProperty();

    private final Timeline casSekundy = new Timeline(new KeyFrame(Duration.seconds(1), (e) -> {
        int s = Integer.parseInt(casSekundyValue.getValue());
        int m = Integer.parseInt(casMinutyValue.getValue());
        if(s == 0 && m == 0)
        {
            stopTimeLine();
            System.out.println("Odpočet úspěšně dokončen");
        }
        else
            if (s != 0)
            {
                casSekundyValue.setValue(String.format("%02d", s - 1));
            }
        else
            {
                casMinutyValue.setValue(String.format("%02d", m - 1));
                casSekundyValue.setValue(String.format("%02d", 59));
            }
}));

    public void stopTimeLine()
    {
        casSekundy.stop();
    }

    public void cas()
    {
        casSekundy.setCycleCount(Timeline.INDEFINITE);
        casSekundy.play();


    }
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        countdownLabel.textProperty().bind(countDownValue);
        casSekundyLabel.textProperty().bind(casSekundyValue);
        casMinutyLabel.textProperty().bind(casMinutyValue);
        countdownLabel.setVisible(false);
    }

Chyba:

ant -f "C:\\Users\\Vojta\\Dropbox\\Java\\Programy - NetBeans\\Objektově orientované programování\\STIGA-Scoreboard" jfxsa-run
init:
Deleting: C:\Users\Vojta\Dropbox\Java\Programy - NetBeans\Objektově orientované programování\STIGA-Scoreboard\build\built-jar.properties
deps-jar:
Updating property file: C:\Users\Vojta\Dropbox\Java\Programy - NetBeans\Objektově orientované programování\STIGA-Scoreboard\build\built-jar.properties
Compiling 1 source file to C:\Users\Vojta\Dropbox\Java\Programy - NetBeans\Objektově orientované programování\STIGA-Scoreboard\build\classes
compile:
Detected JavaFX Ant API version 1.3
Launching <fx:jar> task from C:\Program Files\Java\jdk1.8.0_77\jre\..\lib\ant-javafx.jar
Warning: From JDK7u25 the Codebase manifest attribute should be used to restrict JAR repurposing.
         Please set manifest.custom.codebase property to override the current default non-secure value '*'.
Launching <fx:deploy> task from C:\Program Files\Java\jdk1.8.0_77\jre\..\lib\ant-javafx.jar
No base JDK. Package will use system JRE.
No base JDK. Package will use system JRE.
jfx-deployment-script:
jfx-deployment:
jar:
Copying 12 files to C:\Users\Vojta\Dropbox\Java\Programy - NetBeans\Objektově orientované programování\STIGA-Scoreboard\dist\run549448994
jfx-project-run:
Executing C:\Users\Vojta\Dropbox\Java\Programy - NetBeans\Objektově orientované programování\STIGA-Scoreboard\dist\run549448994\STIGA-Scoreboard.jar using platform C:\Program Files\Java\jdk1.8.0_77\jre/bin/java
Exception in thread "JavaFX Application Thread" java.lang.NumberFormatException: null
        at java.lang.Integer.parseInt(Integer.java:542)
        at java.lang.Integer.parseInt(Integer.java:615)
        at stiga.scoreboard.FXMLDocumentController.lambda$new$1(FXMLDocumentController.java:135)
        at com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:239)
        at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:180)
        at javafx.animation.Timeline.impl_playTo(Timeline.java:176)
        at javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
        at com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(InfiniteClipEnvelope.java:110)
        at javafx.animation.Animation.impl_timePulse(Animation.java:1102)
        at javafx.animation.Animation$1.lambda$timePulse$25(Animation.java:186)
        at java.security.AccessController.doPrivileged(Native Method)
        at javafx.animation.Animation$1.timePulse(Animation.java:185)
        at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
        at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
        at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:506)
        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(Thread.java:745)
Exception in thread "JavaFX Application Thread" java.lang.NumberFormatException: null
        at java.lang.Integer.parseInt(Integer.java:542)
        at java.lang.Integer.parseInt(Integer.java:615)
        at stiga.scoreboard.FXMLDocumentController.lambda$new$1(FXMLDocumentController.java:135)
        at com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:239)
        at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:180)
        at javafx.animation.Timeline.impl_playTo(Timeline.java:176)
        at javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
        at com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(InfiniteClipEnvelope.java:110)
        at javafx.animation.Animation.impl_timePulse(Animation.java:1102)
        at javafx.animation.Animation$1.lambda$timePulse$25(Animation.java:186)
        at java.security.AccessController.doPrivileged(Native Method)
        at javafx.animation.Animation$1.timePulse(Animation.java:185)
        at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
        at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
        at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:506)
        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(Thread.java:745)
Deleting directory C:\Users\Vojta\Dropbox\Java\Programy - NetBeans\Objektově orientované programování\STIGA-Scoreboard\dist\run549448994
jfxsa-run:
BUILD SUCCESSFUL (total time: 11 seconds)
 
Nahoru Odpovědět
21.5.2016 17:39
Avatar
Vojtěch Bešťák:21.5.2016 17:50

Děkuji moc :) Už jsem na to přišel, stačilo definovat tyto dvě proměnné:

private final StringProperty casSekundyValue = new SimpleStringProperty(0 + "");
private final StringProperty casMinutyValue = new SimpleStringProperty(5 + "");

Nicméně mám ještě jeden dotaz, jde nějak udělat, aby countdown před zmáčknutím tlačítka vypadal jako po zmáčknutí?
viz obrázky

 
Nahoru Odpovědět
21.5.2016 17:50
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.