mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-21 12:11:28 +00:00
Each window is now a separate @Subcomponent of the FxApplicationComponent
This commit is contained in:
@@ -2,34 +2,28 @@ package org.cryptomator.ui;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.ui.mainwindow.MainWindow;
|
||||
import org.cryptomator.ui.preferences.PreferencesWindow;
|
||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.desktop.PreferencesEvent;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
@FxApplicationScoped
|
||||
public class FxApplication extends Application {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class);
|
||||
|
||||
private final Stage mainWindow;
|
||||
private final Stage preferencesWindow;
|
||||
private final FXMLLoaderFactory fxmlLoaders;
|
||||
private final MainWindowComponent.Builder mainWindow;
|
||||
private final PreferencesComponent.Builder preferencesWindow;
|
||||
|
||||
@Inject
|
||||
FxApplication(@MainWindow Stage mainWindow, @PreferencesWindow Stage preferencesWindow, FXMLLoaderFactory fxmlLoaders) {
|
||||
FxApplication(MainWindowComponent.Builder mainWindow, PreferencesComponent.Builder preferencesWindow) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.preferencesWindow = preferencesWindow;
|
||||
this.fxmlLoaders = fxmlLoaders;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
@@ -37,36 +31,25 @@ public class FxApplication extends Application {
|
||||
if (Desktop.getDesktop().isSupported(Desktop.Action.APP_PREFERENCES)) {
|
||||
Desktop.getDesktop().setPreferencesHandler(this::handlePreferences);
|
||||
}
|
||||
|
||||
start(mainWindow);
|
||||
|
||||
start(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) {
|
||||
assert stage == mainWindow;
|
||||
showMainWindow();
|
||||
assert stage == null;
|
||||
|
||||
mainWindow.build().showMainWindow();
|
||||
}
|
||||
|
||||
private void handlePreferences(PreferencesEvent preferencesEvent) {
|
||||
Platform.runLater(this::showPreferencesWindow);
|
||||
}
|
||||
|
||||
public void showMainWindow() {
|
||||
showViewInWindow("/fxml/main_window.fxml", mainWindow);
|
||||
}
|
||||
|
||||
public void showPreferencesWindow() {
|
||||
showViewInWindow("/fxml/preferences.fxml", preferencesWindow);
|
||||
}
|
||||
|
||||
private void showViewInWindow(String fxmlResourceName, Stage window) {
|
||||
try {
|
||||
Parent root = fxmlLoaders.load(fxmlResourceName).getRoot();
|
||||
window.setScene(new Scene(root));
|
||||
window.show();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to load " + fxmlResourceName, e);
|
||||
}
|
||||
preferencesWindow.build().showPreferencesWindow();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,13 +7,30 @@ package org.cryptomator.ui;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import javafx.application.Application;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.VaultList;
|
||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
||||
|
||||
@Module(includes = {UiModule.class})
|
||||
@Module(includes = {UiModule.class}, subcomponents = {MainWindowComponent.class, PreferencesComponent.class})
|
||||
abstract class FxApplicationModule {
|
||||
|
||||
@Binds
|
||||
@FxApplicationScoped
|
||||
abstract Application provideApplication(FxApplication application);
|
||||
|
||||
@Binds
|
||||
abstract ObservableList<Vault> bindVaultList(VaultList vaultList);
|
||||
|
||||
@Provides
|
||||
@FxApplicationScoped
|
||||
static ObjectProperty<Vault> provideSelectedVault() {
|
||||
return new SimpleObjectProperty<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,13 +11,12 @@ package org.cryptomator.ui;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.frontend.webdav.WebDavServer;
|
||||
import org.cryptomator.keychain.KeychainModule;
|
||||
import org.cryptomator.ui.mainwindow.MainWindowModule;
|
||||
import org.cryptomator.ui.model.VaultComponent;
|
||||
import org.cryptomator.ui.preferences.PreferencesModule;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import javax.inject.Named;
|
||||
@@ -28,7 +27,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Module(includes = {KeychainModule.class, MainWindowModule.class, PreferencesModule.class}, subcomponents = {VaultComponent.class})
|
||||
@Module(includes = {KeychainModule.class}, subcomponents = {VaultComponent.class})
|
||||
public class UiModule {
|
||||
|
||||
private static final int NUM_SCHEDULER_THREADS = 4;
|
||||
@@ -64,10 +63,10 @@ public class UiModule {
|
||||
@Provides
|
||||
@FxApplicationScoped
|
||||
Binding<InetSocketAddress> provideServerSocketAddressBinding(Settings settings) {
|
||||
return EasyBind.map(settings.port(), (Number port) -> {
|
||||
return Bindings.createObjectBinding(() -> {
|
||||
String host = SystemUtils.IS_OS_WINDOWS ? "127.0.0.1" : "localhost";
|
||||
return InetSocketAddress.createUnresolved(host, port.intValue());
|
||||
});
|
||||
return InetSocketAddress.createUnresolved(host, settings.port().intValue());
|
||||
}, settings.port());
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.cryptomator.ui;
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import org.cryptomator.ui.FxApplicationScoped;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
@@ -9,14 +10,12 @@ import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@FxApplicationScoped
|
||||
public class FXMLLoaderFactory {
|
||||
|
||||
private final Map<Class<? extends FxController>, Provider<FxController>> factories;
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
@Inject
|
||||
FXMLLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories) {
|
||||
public FXMLLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories) {
|
||||
this.factories = factories;
|
||||
this.resourceBundle = ResourceBundle.getBundle("i18n.strings");
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui;
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
public interface FxController {
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui;
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
import dagger.MapKey;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import dagger.Subcomponent;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.Window;
|
||||
import org.cryptomator.ui.common.FXMLLoaderFactory;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
@MainWindowScoped
|
||||
@Subcomponent(modules = {MainWindowModule.class})
|
||||
public interface MainWindowComponent {
|
||||
|
||||
Stage mainWindow();
|
||||
|
||||
FXMLLoaderFactory fxmlLoaders();
|
||||
|
||||
default void showMainWindow() {
|
||||
try {
|
||||
Parent root = fxmlLoaders().load("/fxml/main_window.fxml").getRoot();
|
||||
Stage stage = mainWindow();
|
||||
stage.setScene(new Scene(root));
|
||||
stage.show();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to load main_window.fxml", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Subcomponent.Builder
|
||||
interface Builder {
|
||||
MainWindowComponent build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.ui.FxApplication;
|
||||
import org.cryptomator.ui.FxApplicationScoped;
|
||||
import org.cryptomator.ui.FxController;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -14,13 +13,13 @@ import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@FxApplicationScoped
|
||||
@MainWindowScoped
|
||||
public class MainWindowController implements FxController {
|
||||
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainWindowController.class);
|
||||
|
||||
private final CountDownLatch shutdownLatch;
|
||||
private final Stage mainWindow;
|
||||
private final Stage window;
|
||||
private final FxApplication application;
|
||||
|
||||
@FXML
|
||||
@@ -30,9 +29,9 @@ public class MainWindowController implements FxController {
|
||||
private double yOffset;
|
||||
|
||||
@Inject
|
||||
public MainWindowController(@Named("shutdownLatch") CountDownLatch shutdownLatch, @MainWindow Stage mainWindow, FxApplication application) {
|
||||
public MainWindowController(@Named("shutdownLatch") CountDownLatch shutdownLatch, Stage window, FxApplication application) {
|
||||
this.shutdownLatch = shutdownLatch;
|
||||
this.mainWindow = mainWindow;
|
||||
this.window = window;
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
@@ -51,7 +50,7 @@ public class MainWindowController implements FxController {
|
||||
|
||||
@FXML
|
||||
public void close() {
|
||||
mainWindow.close();
|
||||
window.close();
|
||||
LOG.info("closed...");
|
||||
shutdownLatch.countDown();
|
||||
}
|
||||
|
||||
@@ -4,20 +4,36 @@ import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import org.cryptomator.ui.FxApplicationScoped;
|
||||
import org.cryptomator.ui.FxController;
|
||||
import org.cryptomator.ui.FxControllerKey;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.VaultList;
|
||||
import org.cryptomator.ui.common.FXMLLoaderFactory;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxControllerKey;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import java.util.Map;
|
||||
|
||||
@Module
|
||||
public abstract class MainWindowModule {
|
||||
|
||||
@Provides
|
||||
@MainWindowScoped
|
||||
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories) {
|
||||
return new FXMLLoaderFactory(factories);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@MainWindowScoped
|
||||
static Stage provideStage() {
|
||||
Stage stage = new Stage();
|
||||
stage.setMinWidth(652.0);
|
||||
stage.setMinHeight(440.0);
|
||||
stage.initStyle(StageStyle.UNDECORATED);
|
||||
return stage;
|
||||
}
|
||||
|
||||
// ------------------
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(MainWindowController.class)
|
||||
@@ -32,27 +48,5 @@ public abstract class MainWindowModule {
|
||||
@IntoMap
|
||||
@FxControllerKey(VaultDetailController.class)
|
||||
abstract FxController bindVaultDetailController(VaultDetailController controller);
|
||||
|
||||
// ------------------
|
||||
|
||||
@Provides
|
||||
@FxApplicationScoped
|
||||
@MainWindow
|
||||
static Stage providePrimaryStage() {
|
||||
Stage stage = new Stage();
|
||||
stage.setMinWidth(652.0);
|
||||
stage.setMinHeight(440.0);
|
||||
stage.initStyle(StageStyle.UNDECORATED);
|
||||
return stage;
|
||||
}
|
||||
|
||||
@Binds
|
||||
abstract ObservableList<Vault> bindVaultList(VaultList vaultList);
|
||||
|
||||
@Provides
|
||||
@FxApplicationScoped
|
||||
static ObjectProperty<Vault> provideSelectedVault() {
|
||||
return new SimpleObjectProperty<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import javax.inject.Scope;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Qualifier
|
||||
@Scope
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MainWindow {
|
||||
@interface MainWindowScoped {
|
||||
|
||||
}
|
||||
@@ -2,13 +2,12 @@ package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import org.cryptomator.ui.FxApplicationScoped;
|
||||
import org.cryptomator.ui.FxController;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@FxApplicationScoped
|
||||
@MainWindowScoped
|
||||
public class VaultDetailController implements FxController {
|
||||
|
||||
private final ReadOnlyObjectProperty<Vault> vault;
|
||||
|
||||
@@ -6,15 +6,14 @@ import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import org.cryptomator.ui.FxApplicationScoped;
|
||||
import org.cryptomator.ui.FxController;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@FxApplicationScoped
|
||||
@MainWindowScoped
|
||||
public class VaultListController implements FxController {
|
||||
|
||||
|
||||
private final ObservableList<Vault> vaults;
|
||||
private final ObjectProperty<Vault> selectedVault;
|
||||
public ListView vaultList;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.preferences;
|
||||
|
||||
import dagger.Subcomponent;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.ui.common.FXMLLoaderFactory;
|
||||
import org.cryptomator.ui.mainwindow.MainWindowModule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
@PreferencesScoped
|
||||
@Subcomponent(modules = {PreferencesModule.class})
|
||||
public interface PreferencesComponent {
|
||||
|
||||
Stage preferencesWindow();
|
||||
|
||||
FXMLLoaderFactory fxmlLoaders();
|
||||
|
||||
default void showPreferencesWindow() {
|
||||
try {
|
||||
Parent root = fxmlLoaders().load("/fxml/preferences.fxml").getRoot();
|
||||
Stage stage = preferencesWindow();
|
||||
stage.setScene(new Scene(root));
|
||||
stage.show();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to load main_window.fxml", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Subcomponent.Builder
|
||||
interface Builder {
|
||||
|
||||
PreferencesComponent build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,12 +10,12 @@ import javafx.util.StringConverter;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.cryptomator.common.settings.WebDavUrlScheme;
|
||||
import org.cryptomator.ui.FxController;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.model.Volume;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@PreferencesWindow
|
||||
@PreferencesScoped
|
||||
public class PreferencesController implements FxController {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
@@ -6,29 +6,38 @@ import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.ui.FxApplicationScoped;
|
||||
import org.cryptomator.ui.FxController;
|
||||
import org.cryptomator.ui.FxControllerKey;
|
||||
import org.cryptomator.ui.mainwindow.MainWindow;
|
||||
import org.cryptomator.ui.common.FXMLLoaderFactory;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxControllerKey;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import java.util.Map;
|
||||
|
||||
@Module
|
||||
public abstract class PreferencesModule {
|
||||
|
||||
@Provides
|
||||
@PreferencesScoped
|
||||
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories) {
|
||||
return new FXMLLoaderFactory(factories);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@PreferencesScoped
|
||||
static Stage provideStage() {
|
||||
Stage stage = new Stage();
|
||||
stage.setMinWidth(400);
|
||||
stage.setMinHeight(300);
|
||||
stage.initModality(Modality.APPLICATION_MODAL);
|
||||
return stage;
|
||||
}
|
||||
|
||||
// ------------------
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(PreferencesController.class)
|
||||
abstract FxController bindPreferencesController(PreferencesController controller);
|
||||
|
||||
@Provides
|
||||
@FxApplicationScoped
|
||||
@PreferencesWindow
|
||||
static Stage providePreferencesStage(@MainWindow Stage mainWindow) {
|
||||
Stage stage = new Stage();
|
||||
stage.setMinWidth(400);
|
||||
stage.setMinHeight(300);
|
||||
stage.initModality(Modality.APPLICATION_MODAL);
|
||||
stage.initOwner(mainWindow);
|
||||
return stage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package org.cryptomator.ui.preferences;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import javax.inject.Scope;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Qualifier
|
||||
@Scope
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PreferencesWindow {
|
||||
@interface PreferencesScoped {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user