diff --git a/fx-application/src/main/java/com/dua3/fx/application/FxApplication.java b/fx-application/src/main/java/com/dua3/fx/application/FxApplication.java index 4b043cc9..264ec2b5 100644 --- a/fx-application/src/main/java/com/dua3/fx/application/FxApplication.java +++ b/fx-application/src/main/java/com/dua3/fx/application/FxApplication.java @@ -14,6 +14,7 @@ package com.dua3.fx.application; +import com.dua3.cabe.annotations.Nullable; import com.dua3.fx.controls.Dialogs; import com.dua3.utility.fx.FxUtil; import com.dua3.utility.i18n.I18N; @@ -37,6 +38,8 @@ import java.io.UncheckedIOException; import java.net.URI; import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -132,6 +135,16 @@ public static ResourceBundle getFxAppBundle(Locale locale) { return resources; } + /** + * Convert a given URI to text. + * + * @param uri the URI to convert + * @return the text representation of the URI + */ + public static String asText(@Nullable URI uri) { + return uri == null ? "" : URLDecoder.decode(uri.toString(), StandardCharsets.UTF_8); + } + /** * Get application main resource bundle. * @@ -251,7 +264,7 @@ protected void updateApplicationTitle() { if (document != null) { String locStr = document.hasLocation() ? - FxUtil.asText(document.getLocation()) : + asText(document.getLocation()) : i18n.get("fx.application.text.untitled"); boolean dirty = document.isDirty(); diff --git a/fx-application/src/main/java/com/dua3/fx/application/FxController.java b/fx-application/src/main/java/com/dua3/fx/application/FxController.java index f8ccedd4..a286b409 100644 --- a/fx-application/src/main/java/com/dua3/fx/application/FxController.java +++ b/fx-application/src/main/java/com/dua3/fx/application/FxController.java @@ -271,7 +271,7 @@ protected boolean open(URI uri) { } catch (Exception e) { LOG.warn("error opening document", e); getApp().showErrorDialog( - i18n.format("fx.application.dialog.error.open.document.{0.name}", FxUtil.asText(uri)), + i18n.format("fx.application.dialog.error.open.document.{0.name}", FxApplication.asText(uri)), String.valueOf(e.getLocalizedMessage()) ); return false; @@ -402,7 +402,7 @@ private boolean saveDocumentAndHandleErrors(D document, URI uri) { } catch (Exception e) { LOG.warn("error saving document", e); getApp().showErrorDialog( - i18n.format("fx.application.dialog.error.save.{0.document}", FxUtil.asText(uri)), + i18n.format("fx.application.dialog.error.save.{0.document}", FxApplication.asText(uri)), e.getLocalizedMessage() ); return false; diff --git a/fx-controls/src/main/java/com/dua3/fx/controls/PinBoard.java b/fx-controls/src/main/java/com/dua3/fx/controls/PinBoard.java index b8a8a13b..16ab0a44 100644 --- a/fx-controls/src/main/java/com/dua3/fx/controls/PinBoard.java +++ b/fx-controls/src/main/java/com/dua3/fx/controls/PinBoard.java @@ -6,9 +6,9 @@ package com.dua3.fx.controls; import com.dua3.fx.util.FxRefresh; -import com.dua3.fx.util.PlatformHelper; import com.dua3.utility.data.Pair; import com.dua3.utility.fx.FxUtil; +import com.dua3.utility.fx.PlatformHelper; import com.dua3.utility.lang.LangUtil; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty; diff --git a/fx-controls/src/main/java/com/dua3/fx/controls/StatusBar.java b/fx-controls/src/main/java/com/dua3/fx/controls/StatusBar.java index 4ee48476..9648a452 100644 --- a/fx-controls/src/main/java/com/dua3/fx/controls/StatusBar.java +++ b/fx-controls/src/main/java/com/dua3/fx/controls/StatusBar.java @@ -15,7 +15,7 @@ package com.dua3.fx.controls; import com.dua3.fx.util.FxTaskTracker; -import com.dua3.fx.util.PlatformHelper; +import com.dua3.utility.fx.PlatformHelper; import javafx.concurrent.Task; import javafx.concurrent.Worker.State; import javafx.geometry.Pos; diff --git a/fx-util-db/src/main/java/com/dua3/fx/util/db/FxDbUtil.java b/fx-util-db/src/main/java/com/dua3/fx/util/db/FxDbUtil.java index 75e73f1a..08ebba8b 100644 --- a/fx-util-db/src/main/java/com/dua3/fx/util/db/FxDbUtil.java +++ b/fx-util-db/src/main/java/com/dua3/fx/util/db/FxDbUtil.java @@ -14,8 +14,8 @@ package com.dua3.fx.util.db; -import com.dua3.fx.util.PlatformHelper; import com.dua3.utility.db.DbUtil; +import com.dua3.utility.fx.PlatformHelper; import javafx.application.Platform; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.value.ObservableValue; diff --git a/fx-util-db/src/main/java/module-info.java b/fx-util-db/src/main/java/module-info.java index c63915e4..76978c3a 100644 --- a/fx-util-db/src/main/java/module-info.java +++ b/fx-util-db/src/main/java/module-info.java @@ -38,4 +38,5 @@ requires javafx.controls; requires javafx.graphics; requires static com.dua3.cabe.annotations; + requires com.dua3.utility.fx; } diff --git a/fx-util/src/main/java/com/dua3/fx/util/PlatformHelper.java b/fx-util/src/main/java/com/dua3/fx/util/PlatformHelper.java deleted file mode 100644 index 8bb7879e..00000000 --- a/fx-util/src/main/java/com/dua3/fx/util/PlatformHelper.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.dua3.fx.util; - -import com.dua3.utility.lang.LangUtil; -import javafx.application.Platform; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.lang.ref.Cleaner; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; - -/** - * The PlatformHelper class provides utility methods for performing tasks on the JavaFX application thread. - * It provides methods for running tasks synchronously or asynchronously on the JavaFX application thread, - * as well as checking if the current thread is the FX Application Thread. - */ -public final class PlatformHelper { - - /** - * Logger instance - */ - private static final Logger LOG = LogManager.getLogger(PlatformHelper.class); - - /** - * CLEANER is a private static final variable of type Cleaner. - */ - private static final Cleaner CLEANER = Cleaner.create(); - - /** - * Utility class private constructor. - */ - private PlatformHelper() { - // utility class - } - - /** - * Run a task on the JavaFX application thread and wait for completion. - * Consider using {@link #runLater(Runnable)} to avoid executing tasks out of order. - * - * @param action the task to run - * @throws NullPointerException if {@code action} is {@code null} - */ - public static void runAndWait(Runnable action) { - runAndWait(() -> { - action.run(); - return null; - }); - } - - /** - * Run a task on the JavaFX application thread and return result. - * - * @param the result type - * @param action the task to run - * @return the result returned by action - * @throws NullPointerException if {@code action} is {@code null} - */ - public static T runAndWait(Supplier action) { - // run synchronously on JavaFX thread - if (Platform.isFxApplicationThread()) { - return action.get(); - } - - // queue on JavaFX thread and wait for completion - AtomicReference result = new AtomicReference<>(); - final CountDownLatch doneLatch = new CountDownLatch(1); - Platform.runLater(() -> { - try { - result.set(action.get()); - } finally { - doneLatch.countDown(); - } - }); - - while (doneLatch.getCount() > 0) { - try { - doneLatch.await(); - } catch (InterruptedException e) { - LOG.debug("interrupted", e); - Thread.currentThread().interrupt(); - } - } - - return result.get(); - } - - /** - * Run a task on the JavaFX application thread. - * - * @param action the task to run - * @throws NullPointerException if {@code action} is {@code null} - */ - public static void runLater(Runnable action) { - Platform.runLater(action); - } - - /** - * Checks if the current thread is the FX Application Thread. - * Throws an exception if it is not. - */ - public static void checkApplicationThread() { - LangUtil.check(Platform.isFxApplicationThread(), "not on FX Application Thread"); - } - - /** - * Registers an object and a cleanup action to be executed when the object becomes phantom reachable. - * - * @param obj the object to register for cleanup - * @param action the cleanup action to be executed when the object becomes phantom reachable - * @throws NullPointerException if {@code obj} or {@code action} is {@code null} - */ - public static void registerForCleanup(Object obj, Runnable action) { - CLEANER.register(obj, action); - } - - /** - * Get default Cleaner. - * - * @return the {@link Cleaner} instance - */ - public static Cleaner getCleaner() { - return CLEANER; - } - -} diff --git a/fx-util/src/main/resources/META-INF/services/com.dua3.utility.data.ImageUtil b/fx-util/src/main/resources/META-INF/services/com.dua3.utility.data.ImageUtil deleted file mode 100644 index c4854ac3..00000000 --- a/fx-util/src/main/resources/META-INF/services/com.dua3.utility.data.ImageUtil +++ /dev/null @@ -1 +0,0 @@ -com.dua3.fx.util.FxImageUtil diff --git a/fx-util/src/main/resources/META-INF/services/com.dua3.utility.text.FontUtil b/fx-util/src/main/resources/META-INF/services/com.dua3.utility.text.FontUtil deleted file mode 100644 index 25b79052..00000000 --- a/fx-util/src/main/resources/META-INF/services/com.dua3.utility.text.FontUtil +++ /dev/null @@ -1 +0,0 @@ -com.dua3.fx.util.FxFontUtil