From 1e4c8c3837b733ea684b67d8aedb1e9c37d527fd Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 10 Oct 2022 16:37:35 +0200 Subject: [PATCH] separate application from main --- .../sparrowwallet/sparrow/AppServices.java | 11 +- .../com/sparrowwallet/sparrow/MainApp.java | 126 ++---------------- .../com/sparrowwallet/sparrow/Sparrow.java | 122 +++++++++++++++++ .../sparrow/terminal/SparrowTerminal.java | 36 ++--- 4 files changed, 158 insertions(+), 137 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/sparrow/Sparrow.java diff --git a/src/main/java/com/sparrowwallet/sparrow/AppServices.java b/src/main/java/com/sparrowwallet/sparrow/AppServices.java index f5c7da89..68d6104d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppServices.java @@ -28,6 +28,7 @@ import com.sparrowwallet.sparrow.net.*; import com.sparrowwallet.sparrow.paynym.PayNymService; import com.sparrowwallet.sparrow.soroban.SorobanServices; import com.sparrowwallet.sparrow.whirlpool.WhirlpoolServices; +import javafx.application.Application; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -101,7 +102,7 @@ public class AppServices { private static PayNymService payNymService; - private final MainApp application; + private final Application application; private final Map> walletWindows = new LinkedHashMap<>(); @@ -175,7 +176,7 @@ public class AppServices { openFiles(event.getFiles(), null); }; - private AppServices(MainApp application, InteractionServices interactionServices) { + private AppServices(Application application, InteractionServices interactionServices) { this.application = application; this.interactionServices = interactionServices; EventManager.get().register(this); @@ -502,11 +503,11 @@ public class AppServices { return proxy; } - static void initialize(MainApp application) { + public static void initialize(Application application) { INSTANCE = new AppServices(application, new DefaultInteractionServices()); } - static void initialize(MainApp application, InteractionServices interactionServices) { + public static void initialize(Application application, InteractionServices interactionServices) { INSTANCE = new AppServices(application, interactionServices); } @@ -582,7 +583,7 @@ public class AppServices { return (node.getScene() != null && node.getScene().getWindow().getHeight() < 768); } - public MainApp getApplication() { + public Application getApplication() { return application; } diff --git a/src/main/java/com/sparrowwallet/sparrow/MainApp.java b/src/main/java/com/sparrowwallet/sparrow/MainApp.java index d7f2f0f8..0329755a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/MainApp.java +++ b/src/main/java/com/sparrowwallet/sparrow/MainApp.java @@ -3,33 +3,21 @@ package com.sparrowwallet.sparrow; import com.beust.jcommander.JCommander; import com.sparrowwallet.drongo.Drongo; import com.sparrowwallet.drongo.Network; -import com.sparrowwallet.drongo.wallet.Wallet; -import com.sparrowwallet.sparrow.glyphfont.FontAwesome5; -import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands; -import com.sparrowwallet.sparrow.io.Config; import com.sparrowwallet.sparrow.io.Storage; -import com.sparrowwallet.sparrow.net.PublicElectrumServer; -import com.sparrowwallet.sparrow.net.ServerType; -import com.sparrowwallet.sparrow.preferences.PreferenceGroup; -import com.sparrowwallet.sparrow.preferences.PreferencesDialog; import com.sparrowwallet.sparrow.instance.InstanceException; import com.sparrowwallet.sparrow.instance.InstanceList; import com.sparrowwallet.sparrow.terminal.SparrowTerminal; import com.sparrowwallet.sparrow.terminal.TerminalInteractionServices; +import com.sun.javafx.application.PlatformImpl; import javafx.application.Application; -import javafx.scene.text.Font; -import javafx.stage.Stage; -import org.controlsfx.glyphfont.GlyphFontRegistry; -import org.controlsfx.tools.Platform; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.bridge.SLF4JBridgeHandler; import java.io.File; import java.util.*; -import java.util.stream.Collectors; -public class MainApp extends Application { +public class MainApp { public static final String APP_ID = "com.sparrowwallet.sparrow"; public static final String APP_NAME = "Sparrow"; public static final String APP_VERSION = "1.6.6"; @@ -37,105 +25,8 @@ public class MainApp extends Application { public static final String APP_HOME_PROPERTY = "sparrow.home"; public static final String NETWORK_ENV_PROPERTY = "SPARROW_NETWORK"; - private Stage mainStage; - private static SparrowInstance sparrowInstance; - @Override - public void init() throws Exception { - Thread.setDefaultUncaughtExceptionHandler((t, e) -> { - if(e instanceof IndexOutOfBoundsException && Arrays.stream(e.getStackTrace()).anyMatch(element -> element.getClassName().equals("javafx.scene.chart.BarChart"))) { - LoggerFactory.getLogger(MainApp.class).debug("Exception in thread \"" + t.getName() + "\"", e);; - } else { - LoggerFactory.getLogger(MainApp.class).error("Exception in thread \"" + t.getName() + "\"", e); - } - }); - super.init(); - } - - @Override - public void start(Stage stage) throws Exception { - this.mainStage = stage; - - GlyphFontRegistry.register(new FontAwesome5()); - GlyphFontRegistry.register(new FontAwesome5Brands()); - Font.loadFont(AppServices.class.getResourceAsStream("/font/RobotoMono-Regular.ttf"), 13); - - AppServices.initialize(this); - - boolean createNewWallet = false; - Mode mode = Config.get().getMode(); - if(mode == null) { - WelcomeDialog welcomeDialog = new WelcomeDialog(); - Optional optionalMode = welcomeDialog.showAndWait(); - if(optionalMode.isPresent()) { - mode = optionalMode.get(); - Config.get().setMode(mode); - - if(mode.equals(Mode.ONLINE)) { - PreferencesDialog preferencesDialog = new PreferencesDialog(PreferenceGroup.SERVER, true); - Optional optNewWallet = preferencesDialog.showAndWait(); - createNewWallet = optNewWallet.isPresent() && optNewWallet.get(); - } else if(Network.get() == Network.MAINNET) { - Config.get().setServerType(ServerType.PUBLIC_ELECTRUM_SERVER); - List servers = PublicElectrumServer.getServers(); - Config.get().setPublicElectrumServer(servers.get(new Random().nextInt(servers.size())).getServer()); - } - } - } - - if(Config.get().getServerType() == null && Config.get().getCoreServer() == null && Config.get().getElectrumServer() != null) { - Config.get().setServerType(ServerType.ELECTRUM_SERVER); - } - - if(Config.get().getHdCapture() == null && Platform.getCurrent() == Platform.OSX) { - Config.get().setHdCapture(Boolean.TRUE); - } - - System.setProperty(Wallet.ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY, Boolean.toString(!Config.get().isValidateDerivationPaths())); - - if(Config.get().getAppHeight() != null && Config.get().getAppWidth() != null) { - mainStage.setWidth(Config.get().getAppWidth()); - mainStage.setHeight(Config.get().getAppHeight()); - } - - AppController appController = AppServices.newAppWindow(stage); - - if(createNewWallet) { - appController.newWallet(null); - } - - List recentWalletFiles = Config.get().getRecentWalletFiles(); - if(recentWalletFiles != null) { - //Preserve wallet order as far as possible. Unencrypted wallets will still be opened first. - List encryptedWalletFiles = recentWalletFiles.stream().filter(Storage::isEncrypted).collect(Collectors.toList()); - List sortedWalletFiles = new ArrayList<>(recentWalletFiles); - sortedWalletFiles.removeAll(encryptedWalletFiles); - sortedWalletFiles.addAll(encryptedWalletFiles); - - for(File walletFile : sortedWalletFiles) { - if(walletFile.exists()) { - appController.openWalletFile(walletFile, false); - } - } - } - - AppServices.openFileUriArguments(stage); - - AppServices.get().start(); - } - - @Override - public void stop() throws Exception { - AppServices.get().stop(); - Config.get().setAppWidth(mainStage.getWidth()); - Config.get().setAppHeight(mainStage.getHeight()); - mainStage.close(); - if(sparrowInstance != null) { - sparrowInstance.freeLock(); - } - } - public static void main(String[] argv) { Args args = new Args(); JCommander jCommander = JCommander.newBuilder().addObject(args).programName(APP_NAME.toLowerCase(Locale.ROOT)).acceptUnknownOptions(true).build(); @@ -182,9 +73,8 @@ public class MainApp extends Application { } if(args.terminal) { - MainApp mainApp = new MainApp(); - AppServices.initialize(mainApp, new TerminalInteractionServices()); - SparrowTerminal.startTerminal(); + PlatformImpl.setTaskbarApplication(false); + Application.launch(SparrowTerminal.class, argv); return; } @@ -203,14 +93,18 @@ public class MainApp extends Application { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); - com.sun.javafx.application.LauncherImpl.launchApplication(MainApp.class, MainAppPreloader.class, argv); + com.sun.javafx.application.LauncherImpl.launchApplication(Sparrow.class, MainAppPreloader.class, argv); + } + + public static SparrowInstance getSparrowInstance() { + return sparrowInstance; } private static Logger getLogger() { return LoggerFactory.getLogger(MainApp.class); } - private static class SparrowInstance extends InstanceList { + public static class SparrowInstance extends InstanceList { private final List fileUriArguments; public SparrowInstance(List fileUriArguments) { diff --git a/src/main/java/com/sparrowwallet/sparrow/Sparrow.java b/src/main/java/com/sparrowwallet/sparrow/Sparrow.java new file mode 100644 index 00000000..df51a5d9 --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/Sparrow.java @@ -0,0 +1,122 @@ +package com.sparrowwallet.sparrow; + +import com.sparrowwallet.drongo.Network; +import com.sparrowwallet.drongo.wallet.Wallet; +import com.sparrowwallet.sparrow.glyphfont.FontAwesome5; +import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands; +import com.sparrowwallet.sparrow.io.Config; +import com.sparrowwallet.sparrow.io.Storage; +import com.sparrowwallet.sparrow.net.PublicElectrumServer; +import com.sparrowwallet.sparrow.net.ServerType; +import com.sparrowwallet.sparrow.preferences.PreferenceGroup; +import com.sparrowwallet.sparrow.preferences.PreferencesDialog; +import javafx.application.Application; +import javafx.scene.text.Font; +import javafx.stage.Stage; +import org.controlsfx.glyphfont.GlyphFontRegistry; +import org.controlsfx.tools.Platform; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +public class Sparrow extends Application { + private Stage mainStage; + + @Override + public void init() throws Exception { + Thread.setDefaultUncaughtExceptionHandler((t, e) -> { + if(e instanceof IndexOutOfBoundsException && Arrays.stream(e.getStackTrace()).anyMatch(element -> element.getClassName().equals("javafx.scene.chart.BarChart"))) { + LoggerFactory.getLogger(MainApp.class).debug("Exception in thread \"" + t.getName() + "\"", e);; + } else { + LoggerFactory.getLogger(MainApp.class).error("Exception in thread \"" + t.getName() + "\"", e); + } + }); + super.init(); + } + + @Override + public void start(Stage stage) throws Exception { + this.mainStage = stage; + + GlyphFontRegistry.register(new FontAwesome5()); + GlyphFontRegistry.register(new FontAwesome5Brands()); + Font.loadFont(AppServices.class.getResourceAsStream("/font/RobotoMono-Regular.ttf"), 13); + + AppServices.initialize(this); + + boolean createNewWallet = false; + Mode mode = Config.get().getMode(); + if(mode == null) { + WelcomeDialog welcomeDialog = new WelcomeDialog(); + Optional optionalMode = welcomeDialog.showAndWait(); + if(optionalMode.isPresent()) { + mode = optionalMode.get(); + Config.get().setMode(mode); + + if(mode.equals(Mode.ONLINE)) { + PreferencesDialog preferencesDialog = new PreferencesDialog(PreferenceGroup.SERVER, true); + Optional optNewWallet = preferencesDialog.showAndWait(); + createNewWallet = optNewWallet.isPresent() && optNewWallet.get(); + } else if(Network.get() == Network.MAINNET) { + Config.get().setServerType(ServerType.PUBLIC_ELECTRUM_SERVER); + List servers = PublicElectrumServer.getServers(); + Config.get().setPublicElectrumServer(servers.get(new Random().nextInt(servers.size())).getServer()); + } + } + } + + if(Config.get().getServerType() == null && Config.get().getCoreServer() == null && Config.get().getElectrumServer() != null) { + Config.get().setServerType(ServerType.ELECTRUM_SERVER); + } + + if(Config.get().getHdCapture() == null && Platform.getCurrent() == Platform.OSX) { + Config.get().setHdCapture(Boolean.TRUE); + } + + System.setProperty(Wallet.ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY, Boolean.toString(!Config.get().isValidateDerivationPaths())); + + if(Config.get().getAppHeight() != null && Config.get().getAppWidth() != null) { + mainStage.setWidth(Config.get().getAppWidth()); + mainStage.setHeight(Config.get().getAppHeight()); + } + + AppController appController = AppServices.newAppWindow(stage); + + if(createNewWallet) { + appController.newWallet(null); + } + + List recentWalletFiles = Config.get().getRecentWalletFiles(); + if(recentWalletFiles != null) { + //Preserve wallet order as far as possible. Unencrypted wallets will still be opened first. + List encryptedWalletFiles = recentWalletFiles.stream().filter(Storage::isEncrypted).collect(Collectors.toList()); + List sortedWalletFiles = new ArrayList<>(recentWalletFiles); + sortedWalletFiles.removeAll(encryptedWalletFiles); + sortedWalletFiles.addAll(encryptedWalletFiles); + + for(File walletFile : sortedWalletFiles) { + if(walletFile.exists()) { + appController.openWalletFile(walletFile, false); + } + } + } + + AppServices.openFileUriArguments(stage); + + AppServices.get().start(); + } + + @Override + public void stop() throws Exception { + AppServices.get().stop(); + Config.get().setAppWidth(mainStage.getWidth()); + Config.get().setAppHeight(mainStage.getHeight()); + mainStage.close(); + MainApp.SparrowInstance sparrowInstance = MainApp.getSparrowInstance(); + if(sparrowInstance != null) { + sparrowInstance.freeLock(); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/terminal/SparrowTerminal.java b/src/main/java/com/sparrowwallet/sparrow/terminal/SparrowTerminal.java index d9fd0eba..6f06997e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/SparrowTerminal.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/SparrowTerminal.java @@ -11,7 +11,9 @@ import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.terminal.wallet.WalletData; +import javafx.application.Application; import javafx.application.Platform; +import javafx.stage.Stage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,22 +21,35 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -public class SparrowTerminal { +public class SparrowTerminal extends Application { private static final Logger log = LoggerFactory.getLogger(SparrowTerminal.class); private static SparrowTerminal sparrowTerminal; - private final Terminal terminal; - private final Screen screen; - private final SparrowTextGui gui; + private Terminal terminal; + private Screen screen; + private SparrowTextGui gui; private final Map walletData = new HashMap<>(); - private SparrowTerminal() throws IOException { + @Override + public void init() throws Exception { + AppServices.initialize(this, new TerminalInteractionServices()); + this.terminal = new DefaultTerminalFactory().createTerminal(); this.screen = new TerminalScreen(terminal); this.gui = new SparrowTextGui(this, screen, new DefaultWindowManager(), new EmptySpace(TextColor.ANSI.BLUE)); EventManager.get().register(gui); + + sparrowTerminal = this; + + getScreen().startScreen(); + getGui().getMainWindow().waitUntilClosed(); + } + + @Override + public void start(Stage primaryStage) throws Exception { + } public Screen getScreen() { @@ -62,17 +77,6 @@ public class SparrowTerminal { } } - public static void startTerminal() { - try { - sparrowTerminal = new SparrowTerminal(); - sparrowTerminal.getScreen().startScreen(); - sparrowTerminal.getGui().getMainWindow().waitUntilClosed(); - } catch(Exception e) { - log.error("Could not start terminal", e); - System.err.println("Could not start terminal: " + e.getMessage()); - } - } - public static SparrowTerminal get() { return sparrowTerminal; }