Quellcode durchsuchen

Each window is now a separate @Subcomponent of the FxApplicationComponent

Sebastian Stenzel vor 6 Jahren
Ursprung
Commit
b76e1d4167

+ 12 - 29
main/ui/src/main/java/org/cryptomator/ui/FxApplication.java

@@ -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();
 	}
 
+
 }

+ 18 - 1
main/ui/src/main/java/org/cryptomator/ui/FxApplicationModule.java

@@ -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<>();
+	}
+
 }

+ 5 - 6
main/ui/src/main/java/org/cryptomator/ui/UiModule.java

@@ -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

+ 3 - 4
main/ui/src/main/java/org/cryptomator/ui/FXMLLoaderFactory.java

@@ -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");
 	}

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/FxController.java

@@ -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 {
 }

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/FxControllerKey.java

@@ -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;
 

+ 43 - 0
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowComponent.java

@@ -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();
+	}
+
+}

+ 7 - 8
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java

@@ -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();
 	}

+ 24 - 30
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java

@@ -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<>();
-	}
 
 }

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindow.java

@@ -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 - 3
main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailController.java

@@ -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;

+ 3 - 4
main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java

@@ -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;

+ 43 - 0
main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesComponent.java

@@ -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();
+	}
+
+}

+ 2 - 2
main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java

@@ -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;

+ 21 - 12
main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java

@@ -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 {
 
-	@Binds
-	@IntoMap
-	@FxControllerKey(PreferencesController.class)
-	abstract FxController bindPreferencesController(PreferencesController controller);
+	@Provides
+	@PreferencesScoped
+	static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories) {
+		return new FXMLLoaderFactory(factories);
+	}
 
 	@Provides
-	@FxApplicationScoped
-	@PreferencesWindow
-	static Stage providePreferencesStage(@MainWindow Stage mainWindow) {
+	@PreferencesScoped
+	static Stage provideStage() {
 		Stage stage = new Stage();
 		stage.setMinWidth(400);
 		stage.setMinHeight(300);
 		stage.initModality(Modality.APPLICATION_MODAL);
-		stage.initOwner(mainWindow);
 		return stage;
 	}
 
+	// ------------------
+
+	@Binds
+	@IntoMap
+	@FxControllerKey(PreferencesController.class)
+	abstract FxController bindPreferencesController(PreferencesController controller);
+
+
 }

+ 3 - 3
main/ui/src/main/java/org/cryptomator/ui/preferences/PreferencesWindow.java

@@ -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 {
 
 }