diff --git a/out/artifacts/ErhaCam_jar/ErhaCam.jar b/out/artifacts/ErhaCam_jar/ErhaCam.jar index 3b0e2bf..29403d9 100644 Binary files a/out/artifacts/ErhaCam_jar/ErhaCam.jar and b/out/artifacts/ErhaCam_jar/ErhaCam.jar differ diff --git a/src/main/java/Config/SomeCodes.java b/src/main/java/Config/SomeCodes.java index 5d12c16..1b8edc3 100644 --- a/src/main/java/Config/SomeCodes.java +++ b/src/main/java/Config/SomeCodes.java @@ -12,6 +12,7 @@ import javafx.scene.control.TextField; import javafx.scene.image.Image; import javafx.scene.image.PixelFormat; import javafx.scene.image.WritableImage; +import javafx.stage.Stage; import lombok.NonNull; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; @@ -42,6 +43,7 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; import static org.bytedeco.opencv.global.opencv_core.CV_64F; @@ -879,4 +881,30 @@ public class SomeCodes { mat.data().get(data); return image; } + + + /** + * Close Stage if not null + * and wait until closed + * @param obj Stage object to close + */ + public static void closeStage(Stage obj) throws InterruptedException { + if (obj != null) { + if (Platform.isFxApplicationThread()) { + // Already on FX thread, just close directly + obj.close(); + } else { + CountDownLatch latch = new CountDownLatch(1); + Platform.runLater(() -> { + try { + obj.close(); + } finally { + latch.countDown(); + } + }); + // Wait for runLater task to finish + latch.await(); + } + } + } } diff --git a/src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java b/src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java index a9635cf..acba91a 100644 --- a/src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java +++ b/src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java @@ -24,7 +24,6 @@ import org.tinylog.Logger; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.function.Consumer; import static Config.SomeCodes.*; @@ -84,8 +83,16 @@ public class AutoCloseAlert { * Close the current alert if it is shown */ public static void close(){ - Optional.ofNullable(currentAlertStage).ifPresent(Stage::close); - currentAlertStage = null; + if (currentAlertStage!=null){ + try { + closeStage(currentAlertStage); + } catch (InterruptedException e) { + Logger.error("Error closing alert stage: " + e.getMessage()); + } + currentAlertStage = null; + } + + clear(); } @@ -188,7 +195,12 @@ public class AutoCloseAlert { timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(0), event -> alertStage.show())); timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(seconds* (pictures.length)), event -> { - alertStage.close(); + try { + closeStage(alertStage); + } catch (InterruptedException e) { + Logger.error("Error closing alert stage: " + e.getMessage()); + } + //alertStage.close(); if (currentAlertStage == alertStage) { currentAlertStage = null; } @@ -329,7 +341,12 @@ public class AutoCloseAlert { if (seconds>0){ PauseTransition delay = new PauseTransition(Duration.seconds(seconds)); delay.setOnFinished(e -> { - alertStage.close(); + try { + closeStage(alertStage); + } catch (InterruptedException err) { + Logger.error("Error closing alert stage: " + err.getMessage()); + } + //alertStage.close(); if (currentAlertStage == alertStage) { currentAlertStage = null; } diff --git a/src/main/java/id/co/gtc/erhacam/MainApplication.java b/src/main/java/id/co/gtc/erhacam/MainApplication.java index 77ea03e..17b9f19 100644 --- a/src/main/java/id/co/gtc/erhacam/MainApplication.java +++ b/src/main/java/id/co/gtc/erhacam/MainApplication.java @@ -24,7 +24,7 @@ import static Config.SomeCodes.config; public class MainApplication extends Application { - final String version = "10072025-PRODUCTION-1.0.2"; + final String version = "10072025-PRODUCTION-1.0.3"; PhotoCleaner photoCleaner; public static Map detectorsList = new HashMap<>();