diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java index 9a95c7b01..2f2264831 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java @@ -17,6 +17,8 @@ */ package org.jackhuang.hmcl; +import static org.jackhuang.hmcl.util.Logging.LOG; + import com.jfoenix.concurrency.JFXUtilities; import javafx.application.Application; import javafx.application.Platform; @@ -34,6 +36,7 @@ import java.io.File; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Paths; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -79,11 +82,13 @@ public final class Launcher extends Application { Constants.UI_THREAD_SCHEDULER = Constants.JAVAFX_UI_THREAD_SCHEDULER; UPGRADER.parseArguments(VersionNumber.asVersion(VERSION), Arrays.asList(args)); - Logging.LOG.info("*** " + TITLE + " ***"); - Logging.LOG.info("Operating System: " + System.getProperty("os.name") + ' ' + OperatingSystem.SYSTEM_VERSION); - Logging.LOG.info("Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor")); - Logging.LOG.info("Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor")); - Logging.LOG.info("Java Home: " + System.getProperty("java.home")); + LOG.info("*** " + TITLE + " ***"); + LOG.info("Operating System: " + System.getProperty("os.name") + ' ' + OperatingSystem.SYSTEM_VERSION); + LOG.info("Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor")); + LOG.info("Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor")); + LOG.info("Java Home: " + System.getProperty("java.home")); + LOG.info("Current Directory: " + Paths.get("").toAbsolutePath()); + LOG.info("HMCL Directory: " + HMCL_DIRECTORY); launch(args); } catch (Throwable e) { // Fucking JavaFX will suppress the exception and will break our crash reporter. @@ -92,7 +97,7 @@ public final class Launcher extends Application { } public static void stopApplication() { - Logging.LOG.info("Stopping application.\n" + StringUtils.getStackTrace(Thread.currentThread().getStackTrace())); + LOG.info("Stopping application.\n" + StringUtils.getStackTrace(Thread.currentThread().getStackTrace())); JFXUtilities.runInFX(() -> { if (Controllers.getStage() == null) @@ -106,7 +111,7 @@ public final class Launcher extends Application { } public static void stopWithoutPlatform() { - Logging.LOG.info("Stopping application without JavaFX Toolkit.\n" + StringUtils.getStackTrace(Thread.currentThread().getStackTrace())); + LOG.info("Stopping application without JavaFX Toolkit.\n" + StringUtils.getStackTrace(Thread.currentThread().getStackTrace())); JFXUtilities.runInFX(() -> { if (Controllers.getStage() == null) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Main.java b/HMCL/src/main/java/org/jackhuang/hmcl/Main.java index 273545b80..daa04aaf7 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Main.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Main.java @@ -21,6 +21,8 @@ import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -32,12 +34,17 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import javax.swing.JOptionPane; +import org.jackhuang.hmcl.setting.ConfigHolder; + public final class Main { public static void main(String[] args) { checkJavaFX(); checkDirectoryPath(); checkDSTRootCAX3(); + checkConfigPermission(); + + ConfigHolder.init(); Launcher.main(args); } @@ -80,6 +87,22 @@ public final class Main { showWarningAndContinue(i18n("fatal.missing_dst_root_ca_x3")); } + private static void checkConfigPermission() { + Path config = ConfigHolder.CONFIG_PATH; + if (Files.exists(config)) { + if (Files.isReadable(config) && Files.isWritable(config)) { + // we are able to read & write the existent config + return; + } + } else { + if (Files.isWritable(config.getParent())) { + // we are able to create a new config + return; + } + } + showErrorAndExit(i18n("fatal.config_access_denied", config)); + } + /** * Indicates that a fatal error has occurred, and that the application cannot start. */ diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameDownloadTask.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameDownloadTask.java index 33935476b..e1e15a72d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameDownloadTask.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameDownloadTask.java @@ -33,7 +33,7 @@ import java.util.List; import java.util.Optional; import java.util.logging.Level; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; /** * @author huangyuhui @@ -63,7 +63,7 @@ public class HMCLGameDownloadTask extends Task { // Force using common directory will not affect the behaviour that repository acts // Since we always copy the downloaded jar to .minecraft/versions// - File cache = new File(Optional.ofNullable(Settings.INSTANCE.getCommonDirectory()) + File cache = new File(Optional.ofNullable(Settings.instance().getCommonDirectory()) .orElse(Settings.getDefaultCommonDirectory()), "jars/" + gameVersion + ".jar"); if (cache.exists()) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index c2a3717c9..0033ae6bd 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -34,7 +34,7 @@ import java.io.IOException; import java.util.*; import java.util.logging.Level; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; public class HMCLGameRepository extends DefaultGameRepository { private final Profile profile; @@ -58,10 +58,10 @@ public class HMCLGameRepository extends DefaultGameRepository { @Override public File getAssetDirectory(String version, String assetId) { - if (Settings.INSTANCE.isCommonDirectoryDisabled() || useSelf(assetId)) + if (Settings.instance().isCommonDirectoryDisabled() || useSelf(assetId)) return super.getAssetDirectory(version, assetId); else - return new File(Settings.INSTANCE.getCommonDirectory(), "assets"); + return new File(Settings.instance().getCommonDirectory(), "assets"); } @Override @@ -83,10 +83,10 @@ public class HMCLGameRepository extends DefaultGameRepository { public File getLibraryFile(Version version, Library lib) { VersionSetting vs = profile.getVersionSetting(version.getId()); File self = super.getLibraryFile(version, lib); - if (Settings.INSTANCE.isCommonDirectoryDisabled() || self.exists()) + if (Settings.instance().isCommonDirectoryDisabled() || self.exists()) return self; else - return new File(Settings.INSTANCE.getCommonDirectory(), "libraries/" + lib.getPath()); + return new File(Settings.instance().getCommonDirectory(), "libraries/" + lib.getPath()); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index e17bd7823..d36cc3d0e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -378,7 +378,7 @@ public final class LauncherHelper { System.out.print(log); logs.add(pair(log, level)); - if (logs.size() > Settings.INSTANCE.getLogLines()) + if (logs.size() > Settings.instance().getLogLines()) logs.removeFirst(); if (setting.isShowLogs()) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java index 17e6a6551..5ac018d9c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java @@ -44,7 +44,7 @@ import java.util.logging.Level; import static java.util.stream.Collectors.toList; import static javafx.collections.FXCollections.observableArrayList; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating; import static org.jackhuang.hmcl.util.Lang.mapOf; import static org.jackhuang.hmcl.util.Logging.LOG; @@ -60,7 +60,7 @@ public final class Accounts { public static final OfflineAccountFactory FACTORY_OFFLINE = OfflineAccountFactory.INSTANCE; public static final YggdrasilAccountFactory FACTORY_YGGDRASIL = new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE); public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory( - new AuthlibInjectorDownloader(Launcher.HMCL_DIRECTORY.toPath(), () -> Settings.INSTANCE.getDownloadProvider())::getArtifactInfo, + new AuthlibInjectorDownloader(Launcher.HMCL_DIRECTORY.toPath(), () -> Settings.instance().getDownloadProvider())::getArtifactInfo, Accounts::getOrCreateAuthlibInjectorServer); private static final String TYPE_OFFLINE = "offline"; @@ -125,7 +125,7 @@ public final class Accounts { // selection is valid, store it if (!initialized) return; - CONFIG.setSelectedAccount(selected == null ? "" : accountId(selected)); + config().setSelectedAccount(selected == null ? "" : accountId(selected)); } }; @@ -144,7 +144,7 @@ public final class Accounts { if (!initialized) return; // update storage - CONFIG.getAccountStorages().setAll( + config().getAccountStorages().setAll( accounts.stream() .map(account -> { Map storage = account.toStorage(); @@ -155,14 +155,14 @@ public final class Accounts { } /** - * Called when it's ready to load accounts from {@link ConfigHolder#CONFIG}. + * Called when it's ready to load accounts from {@link ConfigHolder#config()}. */ static void init() { if (initialized) throw new IllegalStateException("Already initialized"); // load accounts - CONFIG.getAccountStorages().forEach(storage -> { + config().getAccountStorages().forEach(storage -> { AccountFactory factory = type2factory.get(storage.get("type")); if (factory == null) { LOG.warning("Unrecognized account type: " + storage); @@ -180,12 +180,12 @@ public final class Accounts { initialized = true; - CONFIG.getAuthlibInjectorServers().addListener(onInvalidating(Accounts::removeDanglingAuthlibInjectorAccounts)); + config().getAuthlibInjectorServers().addListener(onInvalidating(Accounts::removeDanglingAuthlibInjectorAccounts)); // load selected account selectedAccount.set( accounts.stream() - .filter(it -> accountId(it).equals(CONFIG.getSelectedAccount())) + .filter(it -> accountId(it).equals(config().getSelectedAccount())) .findFirst() .orElse(null)); } @@ -212,7 +212,7 @@ public final class Accounts { // ==== authlib-injector ==== private static AuthlibInjectorServer getOrCreateAuthlibInjectorServer(String url) { - return CONFIG.getAuthlibInjectorServers().stream() + return config().getAuthlibInjectorServers().stream() .filter(server -> url.equals(server.getUrl())) .findFirst() .orElseGet(() -> { @@ -226,7 +226,7 @@ public final class Accounts { LOG.log(Level.WARNING, "Failed to migrate authlib injector server " + url, e); } - CONFIG.getAuthlibInjectorServers().add(server); + config().getAuthlibInjectorServers().add(server); return server; }); } @@ -239,7 +239,7 @@ public final class Accounts { accounts.stream() .filter(AuthlibInjectorAccount.class::isInstance) .map(AuthlibInjectorAccount.class::cast) - .filter(it -> !CONFIG.getAuthlibInjectorServers().contains(it.getServer())) + .filter(it -> !config().getAuthlibInjectorServers().contains(it.getServer())) .collect(toList()) .forEach(accounts::remove); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java index d7e90427a..7746dabf5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -33,6 +33,8 @@ import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.util.EnumOrdinalDeserializer; import org.jackhuang.hmcl.util.FileTypeAdapter; import org.jackhuang.hmcl.util.ObservableHelper; +import org.jackhuang.hmcl.util.i18n.Locales; +import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -67,6 +69,7 @@ public final class Config implements Cloneable, Observable { .registerTypeAdapter(ObservableMap.class, new ObservableMapCreator()) .registerTypeAdapterFactory(new JavaFxPropertyTypeAdapterFactory(true, true)) .registerTypeAdapter(Theme.class, new Theme.TypeAdapter()) + .registerTypeAdapter(SupportedLocale.class, new SupportedLocale.TypeAdapter()) .registerTypeAdapter(EnumBackgroundImage.class, new EnumOrdinalDeserializer<>(EnumBackgroundImage.class)) // backward compatibility for backgroundType .registerTypeAdapter(Proxy.Type.class, new EnumOrdinalDeserializer<>(Proxy.Type.class)) // backward compatibility for hasProxy .setPrettyPrinting() @@ -120,7 +123,7 @@ public final class Config implements Cloneable, Observable { private ObjectProperty theme = new SimpleObjectProperty<>(Theme.BLUE); @SerializedName("localization") - private StringProperty localization = new SimpleStringProperty(); + private ObjectProperty localization = new SimpleObjectProperty<>(Locales.DEFAULT); @SerializedName("downloadtype") private IntegerProperty downloadType = new SimpleIntegerProperty(1); @@ -143,9 +146,6 @@ public final class Config implements Cloneable, Observable { @SerializedName("logLines") private IntegerProperty logLines = new SimpleIntegerProperty(100); - @SerializedName("firstLaunch") - private BooleanProperty firstLaunch = new SimpleBooleanProperty(true); - @SerializedName("authlibInjectorServers") private ObservableList authlibInjectorServers = FXCollections.observableArrayList(); @@ -351,15 +351,15 @@ public final class Config implements Cloneable, Observable { return theme; } - public String getLocalization() { + public SupportedLocale getLocalization() { return localization.get(); } - public void setLocalization(String localization) { + public void setLocalization(SupportedLocale localization) { this.localization.set(localization); } - public StringProperty localizationProperty() { + public ObjectProperty localizationProperty() { return localization; } @@ -431,18 +431,6 @@ public final class Config implements Cloneable, Observable { return logLines; } - public boolean isFirstLaunch() { - return firstLaunch.get(); - } - - public void setFirstLaunch(boolean firstLaunch) { - this.firstLaunch.set(firstLaunch); - } - - public BooleanProperty firstLaunchProperty() { - return firstLaunch; - } - public ObservableList getAuthlibInjectorServers() { return authlibInjectorServers; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigHolder.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigHolder.java index c07bf7ec6..1246f5a22 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigHolder.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigHolder.java @@ -36,40 +36,72 @@ public final class ConfigHolder { public static final String CONFIG_FILENAME = "hmcl.json"; public static final Path CONFIG_PATH = Paths.get(CONFIG_FILENAME).toAbsolutePath(); - public static final Config CONFIG = initSettings(); - private static Config upgradeSettings(Config deserialized, Map rawJson) { - if (!rawJson.containsKey("commonDirType")) - deserialized.setCommonDirType(deserialized.getCommonDirectory().equals(Settings.getDefaultCommonDirectory()) ? EnumCommonDirectory.DEFAULT : EnumCommonDirectory.CUSTOM); - return deserialized; + private static Config configInstance; + private static boolean newlyCreated; + + public static Config config() { + if (configInstance == null) { + throw new IllegalStateException("Configuration hasn't been loaded"); + } + return configInstance; } - private static Config initSettings() { - Config config = new Config(); + public static boolean isNewlyCreated() { + if (configInstance == null) { + throw new IllegalStateException("Configuration hasn't been loaded"); + } + return newlyCreated; + } + + public synchronized static void init() { + if (configInstance != null) { + throw new IllegalStateException("Configuration is already loaded"); + } + + configInstance = loadConfig(); + configInstance.addListener(source -> saveConfig()); + + Settings.init(); + + if (newlyCreated) { + saveConfig(); + } + } + + private static Config loadConfig() { if (Files.exists(CONFIG_PATH)) { try { - String json = new String(Files.readAllBytes(CONFIG_PATH), UTF_8); - Map raw = new Gson().fromJson(json, Map.class); - Config deserialized = Config.fromJson(json); + String content = new String(Files.readAllBytes(CONFIG_PATH), UTF_8); + Config deserialized = Config.fromJson(content); if (deserialized == null) { - LOG.finer("Settings file is empty, use the default settings."); + LOG.info("Config is empty"); } else { - config = upgradeSettings(deserialized, raw); + Map raw = new Gson().fromJson(content, Map.class); + return upgradeConfig(deserialized, raw); } - LOG.finest("Initialized settings."); } catch (IOException | JsonParseException e) { - LOG.log(Level.WARNING, "Something happened wrongly when load settings.", e); + LOG.log(Level.WARNING, "Something went wrong when loading config.", e); } } - return config; + + LOG.info("Creating an empty config"); + newlyCreated = true; + return new Config(); } - static void saveConfig(Config config) { + static void saveConfig() { + LOG.info("Saving config"); try { - Files.write(CONFIG_PATH, config.toJson().getBytes(UTF_8)); + Files.write(CONFIG_PATH, configInstance.toJson().getBytes(UTF_8)); } catch (IOException ex) { LOG.log(Level.SEVERE, "Failed to save config", ex); } } + private static Config upgradeConfig(Config deserialized, Map rawJson) { + if (!rawJson.containsKey("commonDirType")) + deserialized.setCommonDirType(deserialized.getCommonDirectory().equals(Settings.getDefaultCommonDirectory()) ? EnumCommonDirectory.DEFAULT : EnumCommonDirectory.CUSTOM); + return deserialized; + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java index e6b134098..ffff683cd 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profile.java @@ -122,7 +122,7 @@ public final class Profile { } public HMCLDependencyManager getDependency() { - return new HMCLDependencyManager(this, Settings.INSTANCE.getDownloadProvider()); + return new HMCLDependencyManager(this, Settings.instance().getDownloadProvider()); } public VersionSetting getVersionSetting(String id) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ProxyManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ProxyManager.java index b856bd4ca..0cababf5f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ProxyManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ProxyManager.java @@ -17,7 +17,7 @@ */ package org.jackhuang.hmcl.setting; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import java.net.Authenticator; import java.net.InetSocketAddress; @@ -38,18 +38,18 @@ public final class ProxyManager { private static ObjectBinding proxyProperty = Bindings.createObjectBinding( () -> { - String host = CONFIG.getProxyHost(); - Integer port = Lang.toIntOrNull(CONFIG.getProxyPort()); - if (!CONFIG.hasProxy() || StringUtils.isBlank(host) || port == null || CONFIG.getProxyType() == Proxy.Type.DIRECT) { + String host = config().getProxyHost(); + Integer port = Lang.toIntOrNull(config().getProxyPort()); + if (!config().hasProxy() || StringUtils.isBlank(host) || port == null || config().getProxyType() == Proxy.Type.DIRECT) { return Proxy.NO_PROXY; } else { - return new Proxy(CONFIG.getProxyType(), new InetSocketAddress(host, port)); + return new Proxy(config().getProxyType(), new InetSocketAddress(host, port)); } }, - CONFIG.proxyTypeProperty(), - CONFIG.proxyHostProperty(), - CONFIG.proxyPortProperty(), - CONFIG.hasProxyProperty()); + config().proxyTypeProperty(), + config().proxyHostProperty(), + config().proxyPortProperty(), + config().hasProxyProperty()); public static Proxy getProxy() { return proxyProperty.get(); @@ -68,9 +68,9 @@ public final class ProxyManager { @Override protected PasswordAuthentication getPasswordAuthentication() { - if (CONFIG.hasProxyAuth()) { - String username = CONFIG.getProxyUser(); - String password = CONFIG.getProxyPass(); + if (config().hasProxyAuth()) { + String username = config().getProxyUser(); + String password = config().getProxyPass(); if (username != null && password != null) { return new PasswordAuthentication(username, password.toCharArray()); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index a59c95b62..483be6292 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -25,24 +25,31 @@ import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.event.*; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.util.*; -import org.jackhuang.hmcl.util.i18n.Locales; -import java.io.File; import java.util.*; import java.util.stream.Collectors; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; -import static org.jackhuang.hmcl.util.Logging.LOG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; public class Settings { - public static final Settings INSTANCE = new Settings(); + private static Settings instance; - private final boolean firstLaunch; + public static Settings instance() { + if (instance == null) { + throw new IllegalStateException("Settings hasn't been initialized"); + } + return instance; + } + + /** + * Should be called from {@link ConfigHolder#init()}. + */ + static void init() { + instance = new Settings(); + } private Settings() { - firstLaunch = CONFIG.isFirstLaunch(); - ProxyManager.init(); Accounts.init(); @@ -51,52 +58,31 @@ public class Settings { for (Map.Entry profileEntry : getProfileMap().entrySet()) { profileEntry.getValue().setName(profileEntry.getKey()); profileEntry.getValue().nameProperty().setChangedListener(this::profileNameChanged); - profileEntry.getValue().addPropertyChangedListener(e -> save()); + profileEntry.getValue().addPropertyChangedListener(e -> ConfigHolder.saveConfig()); } - CONFIG.addListener(source -> save()); - CONFIG.setFirstLaunch(false); - } - - private void save() { - LOG.info("Saving config"); - ConfigHolder.saveConfig(CONFIG); - } - - public boolean isFirstLaunch() { - return firstLaunch; - } - - private Locales.SupportedLocale locale = Locales.getLocaleByName(CONFIG.getLocalization()); - - public Locales.SupportedLocale getLocale() { - return locale; - } - - public void setLocale(Locales.SupportedLocale locale) { - this.locale = locale; - CONFIG.setLocalization(Locales.getNameByLocale(locale)); + config().addListener(source -> ConfigHolder.saveConfig()); } public Font getFont() { - return Font.font(CONFIG.getFontFamily(), CONFIG.getFontSize()); + return Font.font(config().getFontFamily(), config().getFontSize()); } public void setFont(Font font) { - CONFIG.setFontFamily(font.getFamily()); - CONFIG.setFontSize(font.getSize()); + config().setFontFamily(font.getFamily()); + config().setFontSize(font.getSize()); } public int getLogLines() { - return Math.max(CONFIG.getLogLines(), 100); + return Math.max(config().getLogLines(), 100); } public void setLogLines(int logLines) { - CONFIG.setLogLines(logLines); + config().setLogLines(logLines); } public boolean isCommonDirectoryDisabled() { - return CONFIG.getCommonDirType() == EnumCommonDirectory.DISABLED; + return config().getCommonDirType() == EnumCommonDirectory.DISABLED; } public static String getDefaultCommonDirectory() { @@ -104,13 +90,13 @@ public class Settings { } public String getCommonDirectory() { - switch (CONFIG.getCommonDirType()) { + switch (config().getCommonDirType()) { case DISABLED: return null; case DEFAULT: return getDefaultCommonDirectory(); case CUSTOM: - return CONFIG.getCommonDirectory(); + return config().getCommonDirectory(); default: return null; } @@ -121,14 +107,14 @@ public class Settings { ****************************************/ public DownloadProvider getDownloadProvider() { - return DownloadProviders.getDownloadProvider(CONFIG.getDownloadType()); + return DownloadProviders.getDownloadProvider(config().getDownloadType()); } public void setDownloadProvider(DownloadProvider downloadProvider) { int index = DownloadProviders.DOWNLOAD_PROVIDERS.indexOf(downloadProvider); if (index == -1) throw new IllegalArgumentException("Unknown download provider: " + downloadProvider); - CONFIG.setDownloadType(index); + config().setDownloadType(index); } /**************************************** @@ -138,18 +124,18 @@ public class Settings { public Profile getSelectedProfile() { checkProfileMap(); - if (!hasProfile(CONFIG.getSelectedProfile())) { + if (!hasProfile(config().getSelectedProfile())) { getProfileMap().keySet().stream().findFirst().ifPresent(selectedProfile -> { - CONFIG.setSelectedProfile(selectedProfile); + config().setSelectedProfile(selectedProfile); }); Schedulers.computation().schedule(this::onProfileChanged); } - return getProfile(CONFIG.getSelectedProfile()); + return getProfile(config().getSelectedProfile()); } public void setSelectedProfile(Profile selectedProfile) { - if (hasProfile(selectedProfile.getName()) && !Objects.equals(selectedProfile.getName(), CONFIG.getSelectedProfile())) { - CONFIG.setSelectedProfile(selectedProfile.getName()); + if (hasProfile(selectedProfile.getName()) && !Objects.equals(selectedProfile.getName(), config().getSelectedProfile())) { + config().setSelectedProfile(selectedProfile.getName()); Schedulers.computation().schedule(this::onProfileChanged); } } @@ -166,7 +152,7 @@ public class Settings { } public Map getProfileMap() { - return CONFIG.getConfigurations(); + return config().getConfigurations(); } public Collection getProfiles() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Theme.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Theme.java index d3ee6ba6d..5aea647a6 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Theme.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Theme.java @@ -27,7 +27,7 @@ import org.jackhuang.hmcl.util.Logging; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import java.io.File; import java.io.IOException; @@ -120,7 +120,7 @@ public class Theme { } public static ObjectBinding foregroundFillBinding() { - return Bindings.createObjectBinding(() -> CONFIG.getTheme().getForegroundColor(), CONFIG.themeProperty()); + return Bindings.createObjectBinding(() -> config().getTheme().getForegroundColor(), config().themeProperty()); } public static ObjectBinding blackFillBinding() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java index 761dce2bf..061639a6e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java @@ -30,7 +30,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; /** * @@ -515,10 +515,10 @@ public final class VersionSetting { .setFullscreen(isFullscreen()) .setServerIp(getServerIp()) .setWrapper(getWrapper()) - .setProxyHost(CONFIG.getProxyHost()) - .setProxyPort(CONFIG.getProxyPort()) - .setProxyUser(CONFIG.getProxyUser()) - .setProxyPass(CONFIG.getProxyPass()) + .setProxyHost(config().getProxyHost()) + .setProxyPort(config().getProxyPort()) + .setProxyUser(config().getProxyUser()) + .setProxyPass(config().getProxyPass()) .setPrecalledCommand(getPreLaunchCommand()) .setNoGeneratedJVMArgs(isNoJVMArgs()) .create(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java index c6f4775bf..ab2bbf599 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAccountPane.java @@ -54,7 +54,7 @@ import java.util.concurrent.CountDownLatch; import java.util.logging.Level; import static java.util.Objects.requireNonNull; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.ui.FXUtils.jfxListCellFactory; import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating; import static org.jackhuang.hmcl.ui.FXUtils.stringConverter; @@ -79,7 +79,7 @@ public class AddAccountPane extends StackPane { cboServers.setCellFactory(jfxListCellFactory(server -> new TwoLineListItem(server.getName(), server.getUrl()))); cboServers.setConverter(stringConverter(AuthlibInjectorServer::getName)); - Bindings.bindContent(cboServers.getItems(), CONFIG.getAuthlibInjectorServers()); + Bindings.bindContent(cboServers.getItems(), config().getAuthlibInjectorServers()); cboServers.getItems().addListener(onInvalidating(this::selectDefaultServer)); selectDefaultServer(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAuthlibInjectorServerPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAuthlibInjectorServerPane.java index 2fbf48b94..61dd9d52d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAuthlibInjectorServerPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AddAuthlibInjectorServerPane.java @@ -39,7 +39,7 @@ import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; public class AddAuthlibInjectorServerPane extends StackPane { @@ -133,8 +133,8 @@ public class AddAuthlibInjectorServerPane extends StackPane { @FXML private void onAddFinish() { - if (!CONFIG.getAuthlibInjectorServers().contains(serverBeingAdded)) { - CONFIG.getAuthlibInjectorServers().add(serverBeingAdded); + if (!config().getAuthlibInjectorServers().contains(serverBeingAdded)) { + config().getAuthlibInjectorServers().add(serverBeingAdded); } fireEvent(new DialogCloseEvent()); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java index 96efa7727..02e02ad30 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/AuthlibInjectorServersPage.java @@ -34,7 +34,7 @@ import javafx.scene.control.ScrollPane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; public class AuthlibInjectorServersPage extends StackPane implements DecoratorPage { private final StringProperty title = new SimpleStringProperty(this, "title", i18n("account.injector.manage.title")); @@ -49,13 +49,13 @@ public class AuthlibInjectorServersPage extends StackPane implements DecoratorPa loadFXML(this, "/assets/fxml/authlib-injector-servers.fxml"); smoothScrolling(scrollPane); - serverItems = MappedObservableList.create(CONFIG.getAuthlibInjectorServers(), this::createServerItem); + serverItems = MappedObservableList.create(config().getAuthlibInjectorServers(), this::createServerItem); Bindings.bindContent(listPane.getChildren(), serverItems); } private AuthlibInjectorServerItem createServerItem(AuthlibInjectorServer server) { return new AuthlibInjectorServerItem(server, - item -> CONFIG.getAuthlibInjectorServers().remove(item.getServer())); + item -> config().getAuthlibInjectorServers().remove(item.getServer())); } @FXML diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index e2abc47d5..99fb168ba 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -34,7 +34,7 @@ import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; import org.jackhuang.hmcl.util.FutureCallback; import org.jackhuang.hmcl.util.JavaVersion; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import java.util.function.Consumer; @@ -102,13 +102,13 @@ public final class Controllers { decorator.showPage(null); leftPaneController = new LeftPaneController(decorator.getLeftPane()); - Settings.INSTANCE.onProfileLoading(); + Settings.instance().onProfileLoading(); Task.of(JavaVersion::initialize).start(); decorator.setCustomMaximize(false); scene = new Scene(decorator, 804, 521); - scene.getStylesheets().setAll(CONFIG.getTheme().getStylesheets()); + scene.getStylesheets().setAll(config().getTheme().getStylesheets()); stage.setMinWidth(804); stage.setMaxWidth(804); stage.setMinHeight(521); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java index 5acc657cc..17f2523ed 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java @@ -55,8 +55,8 @@ import javafx.stage.StageStyle; import javafx.util.Duration; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDnD; +import org.jackhuang.hmcl.setting.ConfigHolder; import org.jackhuang.hmcl.setting.EnumBackgroundImage; -import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.animation.AnimationProducer; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; @@ -69,7 +69,6 @@ import org.jackhuang.hmcl.ui.wizard.*; import org.jackhuang.hmcl.util.Lang; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; @@ -81,7 +80,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; import static java.util.stream.Collectors.toList; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.util.Logging.LOG; public final class Decorator extends StackPane implements TaskExecutorDialogWizardDisplayer { @@ -200,7 +199,7 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza ); nowAnimation.play(); }); - if (!Settings.INSTANCE.isFirstLaunch() || Settings.INSTANCE.getLocale().getLocale() != Locale.CHINA) + if (!ConfigHolder.isNewlyCreated() || config().getLocalization().getLocale() != Locale.CHINA) drawerWrapper.getChildren().remove(welcomeView); if (!min) buttonsContainer.getChildren().remove(btnMin); @@ -228,8 +227,8 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza Bindings.createObjectBinding( () -> { Image image = null; - if (CONFIG.getBackgroundImageType() == EnumBackgroundImage.CUSTOM && CONFIG.getBackgroundImage() != null) { - image = tryLoadImage(Paths.get(CONFIG.getBackgroundImage())) + if (config().getBackgroundImageType() == EnumBackgroundImage.CUSTOM && config().getBackgroundImage() != null) { + image = tryLoadImage(Paths.get(config().getBackgroundImage())) .orElse(null); } if (image == null) { @@ -237,8 +236,8 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza } return new Background(new BackgroundImage(image, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, new BackgroundSize(800, 480, false, false, true, true))); }, - CONFIG.backgroundImageTypeProperty(), - CONFIG.backgroundImageProperty())); + config().backgroundImageTypeProperty(), + config().backgroundImageProperty())); } private Image defaultBackground = new Image("/assets/img/background.jpg"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java index 06d0beb70..343041dd1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java @@ -216,11 +216,11 @@ public final class LeftPaneController { private void onProfilesLoading() { LinkedList list = new LinkedList<>(); - for (Profile profile : Settings.INSTANCE.getProfiles()) { + for (Profile profile : Settings.instance().getProfiles()) { VersionListItem item = new VersionListItem(Profiles.getProfileDisplayName(profile)); RipplerContainer ripplerContainer = new RipplerContainer(item); item.setOnSettingsButtonClicked(e -> Controllers.getDecorator().showPage(new ProfilePage(profile))); - ripplerContainer.setOnMouseClicked(e -> Settings.INSTANCE.setSelectedProfile(profile)); + ripplerContainer.setOnMouseClicked(e -> Settings.instance().setSelectedProfile(profile)); ripplerContainer.getProperties().put("profile", profile.getName()); ripplerContainer.maxWidthProperty().bind(leftPane.widthProperty()); list.add(ripplerContainer); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java index 4cc24c1b2..ac835799d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java @@ -43,7 +43,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import java.util.concurrent.CountDownLatch; @@ -65,7 +65,7 @@ public final class LogWindow extends Stage { public LogWindow() { setScene(new Scene(impl, 800, 480)); - getScene().getStylesheets().addAll(CONFIG.getTheme().getStylesheets()); + getScene().getStylesheets().addAll(config().getTheme().getStylesheets()); setTitle(i18n("logwindow.title")); getIcons().add(new Image("/assets/img/icon.png")); } @@ -177,12 +177,12 @@ public final class LogWindow extends Stage { engine = webView.getEngine(); engine.loadContent(Lang.ignoringException(() -> IOUtils.readFullyAsString(getClass().getResourceAsStream("/assets/log-window-content.html"))) - .replace("${FONT}", Settings.INSTANCE.getFont().getSize() + "px \"" + Settings.INSTANCE.getFont().getFamily() + "\"")); + .replace("${FONT}", Settings.instance().getFont().getSize() + "px \"" + Settings.instance().getFont().getFamily() + "\"")); engine.getLoadWorker().stateProperty().addListener((a, b, newValue) -> { if (newValue == Worker.State.SUCCEEDED) { document = engine.getDocument(); body = document.getElementsByTagName("body").item(0); - engine.executeScript("limitedLogs=" + Settings.INSTANCE.getLogLines()); + engine.executeScript("limitedLogs=" + Settings.instance().getLogLines()); latch.countDown(); onDone.fireEvent(new Event(LogWindow.this)); } @@ -190,14 +190,14 @@ public final class LogWindow extends Stage { boolean flag = false; for (String i : cboLines.getItems()) - if (Integer.toString(Settings.INSTANCE.getLogLines()).equals(i)) { + if (Integer.toString(Settings.instance().getLogLines()).equals(i)) { cboLines.getSelectionModel().select(i); flag = true; } cboLines.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> { - Settings.INSTANCE.setLogLines(newValue == null ? 100 : Integer.parseInt(newValue)); - engine.executeScript("limitedLogs=" + Settings.INSTANCE.getLogLines()); + Settings.instance().setLogLines(newValue == null ? 100 : Integer.parseInt(newValue)); + engine.executeScript("limitedLogs=" + Settings.instance().getLogLines()); }); if (!flag) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java index 8c973a6f8..1acbd7a67 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java @@ -101,7 +101,7 @@ public final class MainPage extends StackPane implements DecoratorPage { btnAdd.setOnMouseClicked(e -> Controllers.getDecorator().startWizard(new DownloadWizardProvider(), i18n("install"))); FXUtils.installTooltip(btnAdd, i18n("install")); - btnRefresh.setOnMouseClicked(e -> Settings.INSTANCE.getSelectedProfile().getRepository().refreshVersionsAsync().start()); + btnRefresh.setOnMouseClicked(e -> Settings.instance().getSelectedProfile().getRepository().refreshVersionsAsync().start()); FXUtils.installTooltip(btnRefresh, i18n("button.refresh")); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/ProfilePage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/ProfilePage.java index deface84d..c50b96c08 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/ProfilePage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/ProfilePage.java @@ -80,7 +80,7 @@ public final class ProfilePage extends StackPane implements DecoratorPage { @FXML private void onDelete() { if (profile != null) { - Settings.INSTANCE.deleteProfile(profile); + Settings.instance().deleteProfile(profile); Controllers.navigate(null); } } @@ -99,10 +99,10 @@ public final class ProfilePage extends StackPane implements DecoratorPage { } Profile newProfile = new Profile(txtProfileName.getText(), new File(getLocation())); newProfile.setUseRelativePath(toggleUseRelativePath.isSelected()); - Settings.INSTANCE.putProfile(newProfile); + Settings.instance().putProfile(newProfile); } - Settings.INSTANCE.onProfileLoading(); + Settings.instance().onProfileLoading(); Controllers.navigate(null); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java index 8ff2a3d94..717db8f43 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java @@ -39,7 +39,6 @@ import javafx.scene.paint.Color; import javafx.scene.text.Font; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.setting.*; -import org.jackhuang.hmcl.ui.construct.FileItem; import org.jackhuang.hmcl.ui.construct.FontComboBox; import org.jackhuang.hmcl.ui.construct.MultiFileItem; import org.jackhuang.hmcl.ui.construct.Validator; @@ -47,7 +46,7 @@ import org.jackhuang.hmcl.ui.wizard.DecoratorPage; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.i18n.Locales; -import static org.jackhuang.hmcl.setting.ConfigHolder.CONFIG; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import java.net.Proxy; @@ -111,47 +110,47 @@ public final class SettingsPage extends StackPane implements DecoratorPage { FXUtils.smoothScrolling(scroll); - cboDownloadSource.getSelectionModel().select(DownloadProviders.DOWNLOAD_PROVIDERS.indexOf(Settings.INSTANCE.getDownloadProvider())); - cboDownloadSource.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) -> Settings.INSTANCE.setDownloadProvider(DownloadProviders.getDownloadProvider(newValue.intValue()))); + cboDownloadSource.getSelectionModel().select(DownloadProviders.DOWNLOAD_PROVIDERS.indexOf(Settings.instance().getDownloadProvider())); + cboDownloadSource.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) -> Settings.instance().setDownloadProvider(DownloadProviders.getDownloadProvider(newValue.intValue()))); - cboFont.getSelectionModel().select(Settings.INSTANCE.getFont().getFamily()); + cboFont.getSelectionModel().select(Settings.instance().getFont().getFamily()); cboFont.valueProperty().addListener((a, b, newValue) -> { - Font font = Font.font(newValue, Settings.INSTANCE.getFont().getSize()); - Settings.INSTANCE.setFont(font); + Font font = Font.font(newValue, Settings.instance().getFont().getSize()); + Settings.instance().setFont(font); lblDisplay.setStyle("-fx-font: " + font.getSize() + " \"" + font.getFamily() + "\";"); }); - txtFontSize.setText(Double.toString(Settings.INSTANCE.getFont().getSize())); + txtFontSize.setText(Double.toString(Settings.instance().getFont().getSize())); txtFontSize.getValidators().add(new Validator(it -> Lang.toDoubleOrNull(it) != null)); txtFontSize.textProperty().addListener((a, b, newValue) -> { if (txtFontSize.validate()) { - Font font = Font.font(Settings.INSTANCE.getFont().getFamily(), Double.parseDouble(newValue)); - Settings.INSTANCE.setFont(font); + Font font = Font.font(Settings.instance().getFont().getFamily(), Double.parseDouble(newValue)); + Settings.instance().setFont(font); lblDisplay.setStyle("-fx-font: " + font.getSize() + " \"" + font.getFamily() + "\";"); } }); - lblDisplay.setStyle("-fx-font: " + Settings.INSTANCE.getFont().getSize() + " \"" + Settings.INSTANCE.getFont().getFamily() + "\";"); + lblDisplay.setStyle("-fx-font: " + Settings.instance().getFont().getSize() + " \"" + Settings.instance().getFont().getFamily() + "\";"); ObservableList