@@ -41,16 +41,20 @@ public final class MainWindowController implements IAudioTimer, TrayIconListener
4141 private GridPane grpControls ;
4242 @ FXML
4343 private CheckMenuItem mniTimerEnabled ;
44+ @ FXML
45+ private MenuItem mniCountDown ;
46+
4447 private TrayIconController trayIconController ;
4548 private SettingsController settingsController ;
4649 private UpdateController updateController ;
4750 private ResourceBundle translationBundle ;
4851 private TimerTask timerTask ;
49- private boolean timerEnabled ;
52+ private TimerTask countDownTask ;
5053 private final String platformName ;
5154 private final HelpUtils helpUtils ;
5255 private final ObjectMapper objectMapper ;
5356 private final Timer timer ;
57+ private final Timer countDownTimer ;
5458 private final IAudioTimer audioTimer ;
5559 private final Logger logger ;
5660
@@ -65,6 +69,7 @@ public MainWindowController() {
6569 helpUtils = new HelpUtils ();
6670
6771 this .timer = new Timer ();
72+ this .countDownTimer = new Timer ();
6873 this .audioTimer = this ;
6974 this .objectMapper = new ObjectMapper ();
7075 }
@@ -256,7 +261,7 @@ public void run() {
256261 */
257262 @ FXML
258263 private void initialize () {
259- mniTimerEnabled .setOnAction (e -> {
264+ mniTimerEnabled .setOnAction (_ -> {
260265 if (mniTimerEnabled .isSelected ()) {
261266 final Properties properties = settingsController .getProperties ();
262267 final long timerDelay = Long .parseLong (properties .getProperty ("timerDelay" , "3600000" ));
@@ -420,7 +425,7 @@ private void settingsAction() {
420425 primaryStage .getIcons ().add (new Image (Objects .requireNonNull (getClass ().getResourceAsStream (SharedVariables .ICON_URL ))));
421426 primaryStage .setScene (new Scene (root ));
422427
423- primaryStage .setOnHiding (event -> ThemeController .setTheme (settingsController .getProperties ().getProperty ("theme" , "Light" ).toLowerCase ()));
428+ primaryStage .setOnHiding (_ -> ThemeController .setTheme (settingsController .getProperties ().getProperty ("theme" , "Light" ).toLowerCase ()));
424429
425430 logger .info ("Showing the SettingsWindow" );
426431 primaryStage .show ();
@@ -530,8 +535,8 @@ private void updateAction() {
530535 */
531536 @ Override
532537 public void fired () {
538+ cancelTimer ();
533539 getAllSoundPanes (grpControls ).forEach (SoundPane ::pause );
534- mniTimerEnabled .setSelected (false );
535540
536541 if (Boolean .parseBoolean (settingsController .getProperties ().getProperty ("timerComputerShutdown" , "false" ))) {
537542 final String command = switch (platformName .toLowerCase ()) {
@@ -620,13 +625,18 @@ private void onDragDropped(final DragEvent dragEvent) {
620625 public void cancelTimer () {
621626 logger .info ("Cancelling the Timer to stop all MediaPlayer objects" );
622627
623- timerEnabled = false ;
624-
625628 if (timerTask != null ) {
626629 timerTask .cancel ();
627630 timer .purge ();
628631 }
629632
633+ if (countDownTask != null ) {
634+ countDownTask .cancel ();
635+ countDownTimer .purge ();
636+ }
637+
638+ Platform .runLater (() -> mniCountDown .setVisible (false ));
639+
630640 if (audioTimer != null ) {
631641 audioTimer .cancelled ();
632642 }
@@ -643,25 +653,48 @@ public void scheduleTimer(final long delay) {
643653
644654 logger .info ("Scheduling the Timer to stop all MediaPlayer objects after {} millisecond(s)" , delay );
645655
646- timerEnabled = true ;
647-
648656 if (timerTask != null ) {
649657 timerTask .cancel ();
650658 timer .purge ();
651659 }
652660
661+ if (countDownTask != null ) {
662+ countDownTask .cancel ();
663+ countDownTimer .purge ();
664+ }
665+
653666 timerTask = new TimerTask () {
654667 @ Override
655668 public void run () {
656669 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 ));
661691 }
662692 };
663693
664694 timer .schedule (timerTask , delay );
695+ countDownTimer .schedule (countDownTask , 0 , 1000 );
696+
697+ mniCountDown .setVisible (true );
665698 }
666699
667700 /**
0 commit comments