@@ -41,16 +41,20 @@ public final class MainWindowController implements IAudioTimer, TrayIconListener
41
41
private GridPane grpControls ;
42
42
@ FXML
43
43
private CheckMenuItem mniTimerEnabled ;
44
+ @ FXML
45
+ private MenuItem mniCountDown ;
46
+
44
47
private TrayIconController trayIconController ;
45
48
private SettingsController settingsController ;
46
49
private UpdateController updateController ;
47
50
private ResourceBundle translationBundle ;
48
51
private TimerTask timerTask ;
49
- private boolean timerEnabled ;
52
+ private TimerTask countDownTask ;
50
53
private final String platformName ;
51
54
private final HelpUtils helpUtils ;
52
55
private final ObjectMapper objectMapper ;
53
56
private final Timer timer ;
57
+ private final Timer countDownTimer ;
54
58
private final IAudioTimer audioTimer ;
55
59
private final Logger logger ;
56
60
@@ -65,6 +69,7 @@ public MainWindowController() {
65
69
helpUtils = new HelpUtils ();
66
70
67
71
this .timer = new Timer ();
72
+ this .countDownTimer = new Timer ();
68
73
this .audioTimer = this ;
69
74
this .objectMapper = new ObjectMapper ();
70
75
}
@@ -182,7 +187,7 @@ private void checkForUpdates(final boolean showNoUpdates, final boolean showErro
182
187
} else {
183
188
logger .info ("No updates available" );
184
189
if (showNoUpdates ) {
185
- FxUtils .showInformationAlert (translationBundle .getString ("NoUpdateAvailable" ), null );
190
+ FxUtils .showInformationAlert (translationBundle .getString ("NoUpdateAvailable" ), getClass (). getResourceAsStream ( SharedVariables . ICON_URL ) );
186
191
}
187
192
}
188
193
} catch (final InterruptedException | IOException | InvalidHttpResponseCodeException | URISyntaxException ex ) {
@@ -256,7 +261,7 @@ public void run() {
256
261
*/
257
262
@ FXML
258
263
private void initialize () {
259
- mniTimerEnabled .setOnAction (e -> {
264
+ mniTimerEnabled .setOnAction (_ -> {
260
265
if (mniTimerEnabled .isSelected ()) {
261
266
final Properties properties = settingsController .getProperties ();
262
267
final long timerDelay = Long .parseLong (properties .getProperty ("timerDelay" , "3600000" ));
@@ -420,7 +425,7 @@ private void settingsAction() {
420
425
primaryStage .getIcons ().add (new Image (Objects .requireNonNull (getClass ().getResourceAsStream (SharedVariables .ICON_URL ))));
421
426
primaryStage .setScene (new Scene (root ));
422
427
423
- primaryStage .setOnHiding (event -> ThemeController .setTheme (settingsController .getProperties ().getProperty ("theme" , "Light" ).toLowerCase ()));
428
+ primaryStage .setOnHiding (_ -> ThemeController .setTheme (settingsController .getProperties ().getProperty ("theme" , "Light" ).toLowerCase ()));
424
429
425
430
logger .info ("Showing the SettingsWindow" );
426
431
primaryStage .show ();
@@ -530,8 +535,8 @@ private void updateAction() {
530
535
*/
531
536
@ Override
532
537
public void fired () {
538
+ cancelTimer ();
533
539
getAllSoundPanes (grpControls ).forEach (SoundPane ::pause );
534
- mniTimerEnabled .setSelected (false );
535
540
536
541
if (Boolean .parseBoolean (settingsController .getProperties ().getProperty ("timerComputerShutdown" , "false" ))) {
537
542
final String command = switch (platformName .toLowerCase ()) {
@@ -620,13 +625,18 @@ private void onDragDropped(final DragEvent dragEvent) {
620
625
public void cancelTimer () {
621
626
logger .info ("Cancelling the Timer to stop all MediaPlayer objects" );
622
627
623
- timerEnabled = false ;
624
-
625
628
if (timerTask != null ) {
626
629
timerTask .cancel ();
627
630
timer .purge ();
628
631
}
629
632
633
+ if (countDownTask != null ) {
634
+ countDownTask .cancel ();
635
+ countDownTimer .purge ();
636
+ }
637
+
638
+ Platform .runLater (() -> mniCountDown .setVisible (false ));
639
+
630
640
if (audioTimer != null ) {
631
641
audioTimer .cancelled ();
632
642
}
@@ -643,25 +653,48 @@ public void scheduleTimer(final long delay) {
643
653
644
654
logger .info ("Scheduling the Timer to stop all MediaPlayer objects after {} millisecond(s)" , delay );
645
655
646
- timerEnabled = true ;
647
-
648
656
if (timerTask != null ) {
649
657
timerTask .cancel ();
650
658
timer .purge ();
651
659
}
652
660
661
+ if (countDownTask != null ) {
662
+ countDownTask .cancel ();
663
+ countDownTimer .purge ();
664
+ }
665
+
653
666
timerTask = new TimerTask () {
654
667
@ Override
655
668
public void run () {
656
669
logger .info ("Timer has fired" );
657
- if (timerEnabled ) {
658
- audioTimer .fired ();
659
- }
660
- timerEnabled = false ;
670
+ audioTimer .fired ();
671
+ }
672
+ };
673
+
674
+ countDownTask = new TimerTask () {
675
+ final long seconds = delay / 1000 ;
676
+ int i = 0 ;
677
+
678
+ @ Override
679
+ public void run () {
680
+ i ++;
681
+ long timeLeft = (seconds - (i % seconds ));
682
+
683
+ // Calculate hours, minutes and seconds
684
+ long hours = timeLeft / 3600 ;
685
+ long minutes = (timeLeft % 3600 ) / 60 ;
686
+ long seconds = timeLeft % 60 ;
687
+
688
+ // Format the values to HH:MM:SS with leading zeros if necessary
689
+ final String timeLeftFormatted = String .format ("%02d:%02d:%02d" , hours , minutes , seconds );
690
+ Platform .runLater (() -> mniCountDown .setText (timeLeftFormatted ));
661
691
}
662
692
};
663
693
664
694
timer .schedule (timerTask , delay );
695
+ countDownTimer .schedule (countDownTask , 0 , 1000 );
696
+
697
+ mniCountDown .setVisible (true );
665
698
}
666
699
667
700
/**
0 commit comments