From 18ca5638650006d176aaf1067f72b05295a964c2 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Thu, 14 Nov 2024 11:35:23 +0100 Subject: [PATCH] custom dialog init --- .../cryptomator/ui/controls/CustomDialog.java | 61 +++++++++++-------- .../ui/fxapp/FxApplicationModule.java | 8 +++ .../ui/fxapp/FxApplicationWindows.java | 31 +++++----- .../VaultDetailMissingVaultController.java | 29 +++++---- .../VaultDetailUnknownErrorController.java | 32 +++++----- .../VaultListContextMenuController.java | 44 ++++++------- .../ui/mainwindow/VaultListController.java | 29 +++++---- .../SupporterCertificateController.java | 37 ++++++----- 8 files changed, 146 insertions(+), 125 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/controls/CustomDialog.java b/src/main/java/org/cryptomator/ui/controls/CustomDialog.java index 3bf0a62f6..2bb0d9757 100644 --- a/src/main/java/org/cryptomator/ui/controls/CustomDialog.java +++ b/src/main/java/org/cryptomator/ui/controls/CustomDialog.java @@ -5,6 +5,7 @@ import org.cryptomator.ui.common.FxmlLoaderFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.inject.Inject; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; @@ -16,46 +17,55 @@ import java.util.function.Consumer; public class CustomDialog { private static final Logger LOG = LoggerFactory.getLogger(CustomDialog.class); + private final ResourceBundle resourceBundle; - private final Stage dialogStage; + private Stage dialogStage; - CustomDialog(Builder builder){ + CustomDialog(Builder builder) { + this.resourceBundle = builder.resourceBundle; dialogStage = new Stage(); dialogStage.initOwner(builder.owner); dialogStage.initModality(Modality.WINDOW_MODAL); - dialogStage.setTitle(resolveText(builder.resourceBundle, builder.titleKey, builder.titleArgs)); + dialogStage.setTitle(resolveText(builder.titleKey, builder.titleArgs)); - try{ + try { FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController(new CustomDialogController(), Scene::new, builder.resourceBundle); FXMLLoader loader = loaderFactory.load(FxmlFile.CUSTOM_DIALOG.getRessourcePathString()); Parent root = loader.getRoot(); CustomDialogController controller = loader.getController(); - controller.setMessage(resolveText(builder.resourceBundle, builder.messageKey, null)); - controller.setDescription(resolveText(builder.resourceBundle, builder.descriptionKey, null)); + controller.setMessage(resolveText(builder.messageKey, null)); + controller.setDescription(resolveText(builder.descriptionKey, null)); controller.setIcon(builder.icon); - controller.setOkButtonText(resolveText(builder.resourceBundle, builder.okButtonKey, null)); - controller.setCancelButtonText(resolveText(builder.resourceBundle, builder.cancelButtonKey, null)); + controller.setOkButtonText(resolveText(builder.okButtonKey, null)); + controller.setCancelButtonText(resolveText(builder.cancelButtonKey, null)); controller.setOkAction(() -> builder.okAction.accept(dialogStage)); controller.setCancelAction(() -> builder.cancelAction.accept(dialogStage)); dialogStage.setScene(new Scene(root)); - dialogStage.showAndWait(); + } catch (Exception e) { LOG.error("Failed to build and show dialog stage.", e); } } - private String resolveText(ResourceBundle resourceBundle, String key, String[] args) { - String text = resourceBundle.getString(key); + public void showAndWait() { + dialogStage.showAndWait(); + } + + private String resolveText(String key, String[] args) { + String text = (key == null || key.isEmpty() || !resourceBundle.containsKey(key)) + ? String.format("N/A - Key '%s' not found", key) + : resourceBundle.getString(key); return args != null && args.length > 0 ? String.format(text, (Object[]) args) : text; } public static class Builder { + private Stage owner; - private ResourceBundle resourceBundle; + private final ResourceBundle resourceBundle; private String titleKey; private String[] titleArgs; private String messageKey; @@ -67,57 +77,58 @@ public class CustomDialog { private Consumer okAction = Stage::close; private Consumer cancelAction = Stage::close; + @Inject + public Builder(ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; + } + public Builder setOwner(Stage owner) { this.owner = owner; return this; } - public Builder resourceBundle(ResourceBundle resourceBundle) { - this.resourceBundle = resourceBundle; - return this; - } - public Builder titleKey(String titleKey, String... args) { + public Builder setTitleKey(String titleKey, String... args) { this.titleKey = titleKey; this.titleArgs = args; return this; } - public Builder messageKey(String messageKey) { + public Builder setMessageKey(String messageKey) { this.messageKey = messageKey; return this; } - public Builder descriptionKey(String descriptionKey) { + public Builder setDescriptionKey(String descriptionKey) { this.descriptionKey = descriptionKey; return this; } - public Builder icon(FontAwesome5Icon icon) { + public Builder setIcon(FontAwesome5Icon icon) { this.icon = icon; return this; } - public Builder okButtonKey(String okButtonKey) { + public Builder setOkButtonKey(String okButtonKey) { this.okButtonKey = okButtonKey; return this; } - public Builder cancelButtonKey(String cancelButtonKey) { + public Builder setCancelButtonKey(String cancelButtonKey) { this.cancelButtonKey = cancelButtonKey; return this; } - public Builder okAction(Consumer okAction) { + public Builder setOkAction(Consumer okAction) { this.okAction = okAction; return this; } - public Builder cancelAction(Consumer cancelAction) { + public Builder setCancelAction(Consumer cancelAction) { this.cancelAction = cancelAction; return this; } - public CustomDialog build(){ + public CustomDialog build() { return new CustomDialog(this); } } diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java index 0d542b8fe..92042bf50 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java @@ -7,6 +7,7 @@ package org.cryptomator.ui.fxapp; import dagger.Module; import dagger.Provides; +import org.cryptomator.ui.controls.CustomDialog; import org.cryptomator.ui.dokanysupportend.DokanySupportEndComponent; import org.cryptomator.ui.error.ErrorComponent; import org.cryptomator.ui.health.HealthCheckComponent; @@ -24,6 +25,7 @@ import org.cryptomator.ui.vaultoptions.VaultOptionsComponent; import javafx.scene.image.Image; import java.io.IOException; import java.io.InputStream; +import java.util.ResourceBundle; @Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, // MainWindowComponent.class, // @@ -70,4 +72,10 @@ abstract class FxApplicationModule { return builder.build(); } + @Provides + @FxApplicationScoped + static CustomDialog.Builder provideCustomDialog(ResourceBundle resourceBundle) { + return new CustomDialog.Builder(resourceBundle); + } + } \ No newline at end of file diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java index 032b3e49e..fc7602fc2 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java @@ -35,7 +35,6 @@ import java.awt.Desktop; import java.awt.desktop.AppReopenedListener; import java.awt.desktop.QuitResponse; import java.util.Optional; -import java.util.ResourceBundle; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutorService; @@ -59,7 +58,7 @@ public class FxApplicationWindows { private final VaultOptionsComponent.Factory vaultOptionsWindow; private final ShareVaultComponent.Factory shareVaultWindow; private final FilteredList visibleWindows; - private final ResourceBundle resourceBundle; + private final CustomDialog.Builder customDialog; @Inject public FxApplicationWindows(@PrimaryStage Stage primaryStage, // @@ -75,7 +74,7 @@ public class FxApplicationWindows { VaultOptionsComponent.Factory vaultOptionsWindow, // ShareVaultComponent.Factory shareVaultWindow, // ExecutorService executor, // - ResourceBundle resourceBundle) { + CustomDialog.Builder customDialog) { this.primaryStage = primaryStage; this.trayIntegration = trayIntegration; this.mainWindow = mainWindow; @@ -90,8 +89,7 @@ public class FxApplicationWindows { this.vaultOptionsWindow = vaultOptionsWindow; this.shareVaultWindow = shareVaultWindow; this.visibleWindows = Window.getWindows().filtered(Window::isShowing); - this.resourceBundle = resourceBundle; - + this.customDialog = customDialog; } public void initialize() { @@ -155,21 +153,20 @@ public class FxApplicationWindows { public void showDokanySupportEndWindow() { CompletableFuture.runAsync(() -> { - new CustomDialog.Builder() - .setOwner(mainWindow.get().window()) - .resourceBundle(resourceBundle) - .titleKey("dokanySupportEnd.title") - .messageKey("dokanySupportEnd.message") - .descriptionKey("dokanySupportEnd.description") - .icon(FontAwesome5Icon.QUESTION) - .okButtonKey("generic.button.close") - .cancelButtonKey("dokanySupportEnd.preferencesBtn") - .okAction(Stage::close) // - .cancelAction(v -> { + customDialog.setOwner(mainWindow.get().window()) + .setTitleKey("dokanySupportEnd.title") + .setMessageKey("dokanySupportEnd.message") + .setDescriptionKey("dokanySupportEnd.description") + .setIcon(FontAwesome5Icon.QUESTION) + .setOkButtonKey("generic.button.close") + .setCancelButtonKey("dokanySupportEnd.preferencesBtn") + .setOkAction(Stage::close) // + .setCancelAction(v -> { showPreferencesWindow(SelectedPreferencesTab.VOLUME); v.close(); }) // - .build(); + .build() + .showAndWait(); }, Platform::runLater); } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java index 14678fc18..35ab02706 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java @@ -28,17 +28,20 @@ public class VaultDetailMissingVaultController implements FxController { private final ObservableList vaults; private final ResourceBundle resourceBundle; private final Stage window; + private final CustomDialog.Builder customDialog; @Inject public VaultDetailMissingVaultController(ObjectProperty vault, // ObservableList vaults, // ResourceBundle resourceBundle, // - @MainWindow Stage window) { + @MainWindow Stage window, // + CustomDialog.Builder customDialog) { this.vault = vault; this.vaults = vaults; this.resourceBundle = resourceBundle; this.window = window; + this.customDialog = customDialog; } @FXML @@ -48,23 +51,23 @@ public class VaultDetailMissingVaultController implements FxController { @FXML void didClickRemoveVault() { - - new CustomDialog.Builder() + customDialog .setOwner(window) - .resourceBundle(resourceBundle) - .titleKey("removeVault.title", vault.get().getDisplayName()) - .messageKey("removeVault.message") - .descriptionKey("removeVault.description") - .icon(FontAwesome5Icon.QUESTION) - .okButtonKey("removeVault.confirmBtn") - .cancelButtonKey("generic.button.cancel") - .okAction(v -> { + .setTitleKey("removeVault.title", vault.get().getDisplayName()) + .setMessageKey("removeVault.message") + .setDescriptionKey("removeVault.description") + .setIcon(FontAwesome5Icon.QUESTION) + .setOkButtonKey("removeVault.confirmBtn") + .setCancelButtonKey("generic.button.cancel") + .setOkAction(v -> { LOG.debug("Removing vault {}.", vault.get().getDisplayName()); vaults.remove(vault.get()); v.close(); }) // - .cancelAction(Stage::close) // - .build(); + .setCancelAction(Stage::close) // + .build() + .showAndWait(); + ; } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java index b29beb450..272016c09 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java @@ -15,7 +15,6 @@ import javafx.beans.property.ObjectProperty; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.stage.Stage; -import java.util.ResourceBundle; @MainWindowScoped public class VaultDetailUnknownErrorController implements FxController { @@ -26,20 +25,21 @@ public class VaultDetailUnknownErrorController implements FxController { private final FxApplicationWindows appWindows; private final Stage errorWindow; private final ObservableList vaults; - private final ResourceBundle resourceBundle; private final Stage mainWindow; + private final CustomDialog.Builder customDialog; @Inject public VaultDetailUnknownErrorController(@MainWindow Stage mainWindow, ObjectProperty vault, ObservableList vaults, // - ResourceBundle resourceBundle, // - FxApplicationWindows appWindows, @Named("errorWindow") Stage errorWindow) { + FxApplicationWindows appWindows, // + @Named("errorWindow") Stage errorWindow, // + CustomDialog.Builder customDialog) { this.mainWindow = mainWindow; this.vault = vault; this.vaults = vaults; - this.resourceBundle = resourceBundle; this.appWindows = appWindows; this.errorWindow = errorWindow; + this.customDialog = customDialog; } @FXML @@ -54,22 +54,22 @@ public class VaultDetailUnknownErrorController implements FxController { @FXML void didClickRemoveVault() { - new CustomDialog.Builder() + customDialog .setOwner(mainWindow) - .resourceBundle(resourceBundle) - .titleKey("removeVault.title", vault.get().getDisplayName()) - .messageKey("removeVault.message") - .descriptionKey("removeVault.description") - .icon(FontAwesome5Icon.QUESTION) - .okButtonKey("removeVault.confirmBtn") - .cancelButtonKey("generic.button.cancel") - .okAction(v -> { + .setTitleKey("removeVault.title", vault.get().getDisplayName()) + .setMessageKey("removeVault.message") + .setDescriptionKey("removeVault.description") + .setIcon(FontAwesome5Icon.QUESTION) + .setOkButtonKey("removeVault.confirmBtn") + .setCancelButtonKey("generic.button.cancel") + .setOkAction(v -> { LOG.debug("Removing vault {}.", vault.get().getDisplayName()); vaults.remove(vault.get()); v.close(); }) // - .cancelAction(Stage::close) // - .build(); + .setCancelAction(Stage::close) // + .build() + .showAndWait(); } } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java index 8ee588964..c148ed8a5 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java @@ -22,7 +22,6 @@ import javafx.fxml.FXML; import javafx.stage.Stage; import java.util.EnumSet; import java.util.Objects; -import java.util.ResourceBundle; import static org.cryptomator.common.vaults.VaultState.Value.ERROR; import static org.cryptomator.common.vaults.VaultState.Value.LOCKED; @@ -48,22 +47,26 @@ public class VaultListContextMenuController implements FxController { private final ObservableValue selectedVaultUnlockable; private final ObservableValue selectedVaultLockable; private final ObservableList vaults; - private final ResourceBundle resourceBundle; + private final CustomDialog.Builder customDialog; @Inject VaultListContextMenuController(ObjectProperty selectedVault, ObservableList vaults, // - ResourceBundle resourceBundle, // - @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, VaultOptionsComponent.Factory vaultOptionsWindow) { + @MainWindow Stage mainWindow, // + FxApplicationWindows appWindows, // + VaultService vaultService, // + KeychainManager keychain, // + VaultOptionsComponent.Factory vaultOptionsWindow, // + CustomDialog.Builder customDialog) { this.selectedVault = selectedVault; this.vaults = vaults; - this.resourceBundle = resourceBundle; this.mainWindow = mainWindow; this.appWindows = appWindows; this.vaultService = vaultService; this.keychain = keychain; this.vaultOptionsWindow = vaultOptionsWindow; + this.customDialog = customDialog; this.selectedVaultState = selectedVault.flatMap(Vault::stateProperty).orElse(null); this.selectedVaultPassphraseStored = selectedVault.map(this::isPasswordStored).orElse(false); @@ -79,23 +82,20 @@ public class VaultListContextMenuController implements FxController { @FXML public void didClickRemoveVault() { var vault = Objects.requireNonNull(selectedVault.get()); - - new CustomDialog.Builder() - .setOwner(mainWindow) - .resourceBundle(resourceBundle) - .titleKey("removeVault.title", vault.getDisplayName()) - .messageKey("removeVault.message") - .descriptionKey("removeVault.description") - .icon(FontAwesome5Icon.QUESTION) - .okButtonKey("removeVault.confirmBtn") - .cancelButtonKey("generic.button.cancel") - .okAction(v -> { - LOG.debug("Removing vault {}.", vault.getDisplayName()); - vaults.remove(vault); - v.close(); - }) // - .cancelAction(Stage::close) // - .build(); + customDialog.setOwner(mainWindow) + .setTitleKey("removeVault.title", vault.getDisplayName()) + .setMessageKey("removeVault.message") + .setDescriptionKey("removeVault.description") + .setIcon(FontAwesome5Icon.QUESTION) + .setOkButtonKey("removeVault.confirmBtn") + .setCancelButtonKey("generic.button.cancel") + .setOkAction(v -> { + LOG.debug("Removing vault {}.", vault.getDisplayName()); + vaults.remove(vault); + v.close(); + }) // + .build() + .showAndWait(); } @FXML diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 1a1f621c8..db41c829f 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -72,6 +72,8 @@ public class VaultListController implements FxController { private final ResourceBundle resourceBundle; private final FxApplicationWindows appWindows; private final ObservableValue cellSize; + private final CustomDialog.Builder customDialog; + public ListView vaultList; public StackPane root; @FXML @@ -89,7 +91,8 @@ public class VaultListController implements FxController { VaultListManager vaultListManager, // ResourceBundle resourceBundle, // FxApplicationWindows appWindows, // - Settings settings) { + Settings settings, + CustomDialog.Builder customDialog) { this.mainWindow = mainWindow; this.vaults = vaults; this.selectedVault = selectedVault; @@ -99,6 +102,7 @@ public class VaultListController implements FxController { this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; this.appWindows = appWindows; + this.customDialog = customDialog; this.emptyVaultList = Bindings.isEmpty(vaults); @@ -206,22 +210,21 @@ public class VaultListController implements FxController { private void pressedShortcutToRemoveVault() { final var vault = selectedVault.get(); if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION).contains(vault.getState())) { - new CustomDialog.Builder() - .setOwner(mainWindow) - .resourceBundle(resourceBundle) - .titleKey("removeVault.title", vault.getDisplayName()) - .messageKey("removeVault.message") - .descriptionKey("removeVault.description") - .icon(FontAwesome5Icon.QUESTION) - .okButtonKey("removeVault.confirmBtn") - .cancelButtonKey("generic.button.cancel") - .okAction(v -> { + customDialog.setOwner(mainWindow) + .setTitleKey("removeVault.title", vault.getDisplayName()) + .setMessageKey("removeVault.message") + .setDescriptionKey("removeVault.description") + .setIcon(FontAwesome5Icon.QUESTION) + .setOkButtonKey("removeVault.confirmBtn") + .setCancelButtonKey("generic.button.cancel") + .setOkAction(v -> { LOG.debug("Removing vault {}.", vault.getDisplayName()); vaults.remove(vault); v.close(); }) // - .cancelAction(Stage::close) // - .build(); + .setCancelAction(Stage::close) // + .build() + .showAndWait(); } } diff --git a/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java b/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java index 638be351f..95c8e6d0f 100644 --- a/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java +++ b/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java @@ -15,7 +15,6 @@ import javafx.fxml.FXML; import javafx.scene.control.TextArea; import javafx.scene.control.TextFormatter; import javafx.stage.Stage; -import java.util.ResourceBundle; @PreferencesScoped public class SupporterCertificateController implements FxController { @@ -28,18 +27,18 @@ public class SupporterCertificateController implements FxController { private final Stage window; private final LicenseHolder licenseHolder; private final Settings settings; - private final ResourceBundle resourceBundle; + private final CustomDialog.Builder customDialog; @FXML private TextArea supporterCertificateField; @Inject - SupporterCertificateController(Application application, @PreferencesWindow Stage window, LicenseHolder licenseHolder, Settings settings, ResourceBundle resourceBundle) { + SupporterCertificateController(Application application, @PreferencesWindow Stage window, LicenseHolder licenseHolder, Settings settings, CustomDialog.Builder customDialog) { this.application = application; this.window = window; this.licenseHolder = licenseHolder; this.settings = settings; - this.resourceBundle = resourceBundle; + this.customDialog = customDialog; } @FXML @@ -86,21 +85,21 @@ public class SupporterCertificateController implements FxController { @FXML void didClickRemoveCert() { - new CustomDialog.Builder() - .setOwner(window) - .resourceBundle(resourceBundle) - .titleKey("removeCert.title") - .messageKey("removeCert.message") - .descriptionKey("removeCert.description") - .icon(FontAwesome5Icon.QUESTION) - .okButtonKey("removeCert.confirmBtn") - .cancelButtonKey("generic.button.cancel") - .okAction(v -> { - settings.licenseKey.set(null); - v.close(); - }) // - .cancelAction(Stage::close) // - .build(); + customDialog.setOwner(window) + .setTitleKey("removeCert.title") + .setMessageKey("removeCert.message") + .setDescriptionKey("removeCert.description") + .setIcon(FontAwesome5Icon.QUESTION) + .setOkButtonKey("removeCert.confirmBtn") + .setCancelButtonKey("generic.button.cancel") + .setOkAction(v -> { + settings.licenseKey.set(null); + v.close(); + }) // + .setCancelAction(Stage::close) // + .build() + .showAndWait(); + } public LicenseHolder getLicenseHolder() {