Skip to content

Commit acf04b5

Browse files
authored
Merge pull request #128 from CodeDead/feature/timer-ui-countdown
feat: added a visual indicator for the timer and some minor refactoring
2 parents 801020c + c1d8d65 commit acf04b5

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

src/main/java/com/codedead/opal/controller/MainWindowController.java

+45-12
Original file line numberDiff line numberDiff line change
@@ -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
/**

src/main/resources/windows/MainWindow.fxml

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
<Image url="@../images/timer.png"/>
9494
</ImageView>
9595
</graphic>
96+
<MenuItem fx:id="mniCountDown" visible="false" disable="true" />
9697
<CheckMenuItem fx:id="mniTimerEnabled" text="%Enabled" accelerator="Shortcut+T"/>
9798
</Menu>
9899
</Menu>

0 commit comments

Comments
 (0)