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 54da5cb6e..d7def65c1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -103,7 +103,7 @@ public final class Controllers { }); private static Lazy rootPage = new Lazy<>(RootPage::new); private static DecoratorController decorator; - private static Lazy downloadPage = new Lazy<>(DownloadPage::new); + private static DownloadPage downloadPage; private static Lazy accountListPage = new Lazy<>(() -> { AccountListPage accountListPage = new AccountListPage(); accountListPage.selectedAccountProperty().bindBidirectional(Accounts.selectedAccountProperty()); @@ -111,7 +111,7 @@ public final class Controllers { accountListPage.authServersProperty().bindContentBidirectional(config().getAuthlibInjectorServers()); return accountListPage; }); - private static Lazy settingsPage = new Lazy<>(LauncherSettingsPage::new); + private static LauncherSettingsPage settingsPage; private static Lazy terracottaPage = new Lazy<>(TerracottaPage::new); private Controllers() { @@ -142,7 +142,18 @@ public final class Controllers { // FXThread public static LauncherSettingsPage getSettingsPage() { - return settingsPage.get(); + if (settingsPage == null) { + settingsPage = new LauncherSettingsPage(); + } + return settingsPage; + } + + @FXThread + public static void prepareSettingsPage() { + if (settingsPage == null) { + LOG.info("Prepare the settings page"); + settingsPage = FXUtils.prepareNode(new LauncherSettingsPage()); + } } // FXThread @@ -152,7 +163,18 @@ public final class Controllers { // FXThread public static DownloadPage getDownloadPage() { - return downloadPage.get(); + if (downloadPage == null) { + downloadPage = new DownloadPage(); + } + return downloadPage; + } + + @FXThread + public static void prepareDownloadPage() { + if (downloadPage == null) { + LOG.info("Prepare the download page"); + downloadPage = FXUtils.prepareNode(new DownloadPage()); + } } // FXThread @@ -533,6 +555,7 @@ public final class Controllers { downloadPage = null; accountListPage = null; settingsPage = null; + terracottaPage = null; decorator = null; stage = null; scene = null; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index b2385f3f5..2b5f49982 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -30,6 +30,7 @@ import javafx.beans.value.*; import javafx.collections.ObservableMap; import javafx.event.Event; import javafx.event.EventDispatcher; +import javafx.event.EventHandler; import javafx.event.EventType; import javafx.geometry.Bounds; import javafx.geometry.Pos; @@ -54,6 +55,7 @@ import javafx.stage.*; import javafx.util.Callback; import javafx.util.Duration; import javafx.util.StringConverter; +import org.jackhuang.hmcl.setting.StyleSheets; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.task.CacheFileTask; import org.jackhuang.hmcl.task.Schedulers; @@ -1367,6 +1369,24 @@ public final class FXUtils { }); } + public static N prepareNode(N node) { + Scene dummyScene = new Scene(node); + StyleSheets.init(dummyScene); + node.applyCss(); + node.layout(); + return node; + } + + public static void prepareOnMouseEnter(Node node, Runnable action) { + node.addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<>() { + @Override + public void handle(MouseEvent e) { + node.removeEventFilter(MouseEvent.MOUSE_ENTERED, this); + action.run(); + } + }); + } + public static void onScroll(Node node, List list, ToIntFunction> finder, Consumer updater diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TabControl.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TabControl.java index b22acf3a8..c1ff983a8 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TabControl.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TabControl.java @@ -174,7 +174,7 @@ public interface TabControl { } } - class Tab { + final class Tab { private final StringProperty id = new SimpleStringProperty(this, "id"); private final StringProperty text = new SimpleStringProperty(this, "text"); private final ReadOnlyBooleanWrapper selected = new ReadOnlyBooleanWrapper(this, "selected"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java index 4fce798cd..ecc4a5e69 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java @@ -35,6 +35,7 @@ import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.account.AccountAdvancedListItem; +import org.jackhuang.hmcl.ui.animation.AnimationUtils; import org.jackhuang.hmcl.ui.construct.AdvancedListBox; import org.jackhuang.hmcl.ui.construct.AdvancedListItem; import org.jackhuang.hmcl.ui.construct.MessageDialogPane; @@ -175,6 +176,9 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage { downloadItem.setTitle(i18n("download")); downloadItem.setOnAction(e -> Controllers.navigate(Controllers.getDownloadPage())); FXUtils.installFastTooltip(downloadItem, i18n("download.hint")); + if (AnimationUtils.isAnimationEnabled()) { + FXUtils.prepareOnMouseEnter(downloadItem, Controllers::prepareDownloadPage); + } // fifth item in left sidebar AdvancedListItem launcherSettingsItem = new AdvancedListItem(); @@ -182,13 +186,15 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage { launcherSettingsItem.setActionButtonVisible(false); launcherSettingsItem.setTitle(i18n("settings")); launcherSettingsItem.setOnAction(e -> Controllers.navigate(Controllers.getSettingsPage())); + if (AnimationUtils.isAnimationEnabled()) { + FXUtils.prepareOnMouseEnter(launcherSettingsItem, Controllers::prepareSettingsPage); + } // sixth item in left sidebar AdvancedListItem terracottaItem = new AdvancedListItem(); terracottaItem.setLeftGraphic(wrap(SVG.GRAPH2)); terracottaItem.setActionButtonVisible(false); terracottaItem.setTitle(i18n("terracotta")); - terracottaItem.setOnAction(e -> { if (TerracottaMetadata.PROVIDER != null) { Controllers.navigate(Controllers.getTerracottaPage());