From cca818fddbe090f26686948d4d3046183cbb6df8 Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Fri, 17 Jul 2026 14:34:50 +0800 Subject: [PATCH 1/6] Feat: Add empty state placeholders for versions --- .../jackhuang/hmcl/ui/versions/DataPackListPageSkin.java | 8 ++++++++ .../org/jackhuang/hmcl/ui/versions/ModListPageSkin.java | 7 +++++++ .../jackhuang/hmcl/ui/versions/ResourcePackListPage.java | 7 +++++++ .../org/jackhuang/hmcl/ui/versions/SchematicsPage.java | 6 ++++++ .../org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java | 7 +++++++ .../org/jackhuang/hmcl/ui/versions/WorldListPage.java | 7 +++++++ HMCL/src/main/resources/assets/lang/I18N.properties | 6 ++++++ HMCL/src/main/resources/assets/lang/I18N_zh.properties | 6 ++++++ HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties | 6 ++++++ 9 files changed, 60 insertions(+) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java index 40fc80daf59..05f65e1e04b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java @@ -33,6 +33,7 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; +import javafx.scene.control.Label; import javafx.scene.control.SelectionMode; import javafx.scene.control.SkinBase; import javafx.scene.image.Image; @@ -193,6 +194,13 @@ final class DataPackListPageSkin extends SkinBase { listView.setCellFactory(x -> new DataPackInfoListCell(listView, getSkinnable().readOnly)); listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + + StackPane placeholderContainer = new StackPane(); + placeholderContainer.getStyleClass().add("notice-pane"); + Label placeholderLabel = new Label(i18n("datapack.empty")); + placeholderContainer.getChildren().add(placeholderLabel); + listView.setPlaceholder(placeholderContainer); + this.listView.setItems(filteredList); listView.getItems().addListener(listener); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java index b9507b84c97..9820d1aa147 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java @@ -219,6 +219,13 @@ final class ModListPageSkin extends SkinBase { listView.setCellFactory(x -> new ModInfoListCell(listView)); listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + + StackPane placeholderContainer = new StackPane(); + placeholderContainer.getStyleClass().add("notice-pane"); + Label placeholderLabel = new Label(i18n("mods.empty")); + placeholderContainer.getChildren().add(placeholderLabel); + listView.setPlaceholder(placeholderContainer); + Bindings.bindContent(listView.getItems(), skinnable.getItems()); skinnable.getItems().addListener((ListChangeListener) c -> { if (isSearching) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java index 893f508073b..6b325dd207f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java @@ -371,6 +371,13 @@ private ResourcePackListPageSkin(ResourcePackListPage control) { listView.setCellFactory(x -> new ResourcePackListCell(listView, control)); listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + + StackPane placeholderContainer = new StackPane(); + placeholderContainer.getStyleClass().add("notice-pane"); + Label placeholderLabel = new Label(i18n("resourcepack.empty")); + placeholderContainer.getChildren().add(placeholderLabel); + listView.setPlaceholder(placeholderContainer); + Bindings.bindContent(listView.getItems(), control.getItems()); listView.setOnContextMenuRequested(event -> { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java index 241c47a4351..d67ad761d16 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java @@ -636,6 +636,12 @@ protected void updateItem(Item item, boolean empty) { private final class SchematicsPageSkin extends ToolbarListPageSkin { SchematicsPageSkin() { super(SchematicsPage.this); + + StackPane placeholderContainer = new StackPane(); + placeholderContainer.getStyleClass().add("notice-pane"); + Label placeholderLabel = new Label(i18n("schematics.empty")); + placeholderContainer.getChildren().add(placeholderLabel); + listView.setPlaceholder(placeholderContainer); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java index 76a41ce665f..db03b7671c0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java @@ -24,6 +24,7 @@ import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Control; +import javafx.scene.control.Label; import javafx.scene.control.Skin; import javafx.scene.control.SkinBase; import javafx.scene.layout.BorderPane; @@ -162,6 +163,12 @@ private final class WorldBackupsPageSkin extends ToolbarListPageSkin Date: Sat, 18 Jul 2026 01:33:09 +0800 Subject: [PATCH 2/6] Refactor: Binds for searching --- .../ui/versions/DataPackListPageSkin.java | 24 ++++++++++--- .../hmcl/ui/versions/ModListPageSkin.java | 36 +++++++++++++------ .../ui/versions/ResourcePackListPage.java | 30 +++++++++++----- .../resources/assets/lang/I18N.properties | 1 + .../resources/assets/lang/I18N_zh.properties | 1 + .../assets/lang/I18N_zh_CN.properties | 2 ++ 6 files changed, 71 insertions(+), 23 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java index 05f65e1e04b..6699e6fdc36 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java @@ -25,6 +25,7 @@ import javafx.animation.PauseTransition; import javafx.application.Platform; import javafx.beans.InvalidationListener; +import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -52,6 +53,7 @@ import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionPane; import org.jackhuang.hmcl.ui.construct.*; +import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jetbrains.annotations.Nullable; @@ -83,6 +85,7 @@ final class DataPackListPageSkin extends SkinBase { private final BooleanProperty isSearching = new SimpleBooleanProperty(false); private final BooleanProperty isSelecting = new SimpleBooleanProperty(false); private final JFXTextField searchField; + private final PauseTransition searchPause = new PauseTransition(Duration.millis(100)); private static final AtomicInteger lastShiftClickIndex = new AtomicInteger(-1); final Consumer toggleSelect; @@ -149,14 +152,17 @@ final class DataPackListPageSkin extends SkinBase { searchField = new JFXTextField(); searchField.setPromptText(i18n("search")); HBox.setHgrow(searchField, Priority.ALWAYS); - PauseTransition pause = new PauseTransition(Duration.millis(100)); - pause.setOnFinished(e -> filteredList.setPredicate(skinnable.updateSearchPredicate(searchField.getText()))); + searchPause.setOnFinished(e -> filteredList.setPredicate(skinnable.updateSearchPredicate(searchField.getText()))); searchField.textProperty().addListener((observable, oldValue, newValue) -> { - pause.setRate(1); - pause.playFromStart(); + if (isSearching.get() || !StringUtils.isBlank(newValue)) { + searchPause.setRate(1); + searchPause.playFromStart(); + } }); JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE, () -> { + searchPause.stop(); + isSearching.set(false); searchField.clear(); }); @@ -198,6 +204,16 @@ final class DataPackListPageSkin extends SkinBase { StackPane placeholderContainer = new StackPane(); placeholderContainer.getStyleClass().add("notice-pane"); Label placeholderLabel = new Label(i18n("datapack.empty")); + placeholderLabel.textProperty().bind( + Bindings.createStringBinding(() -> { + if (isSearching.get()) { + return i18n("search.no_results_found"); + } else { + return i18n("datapack.empty"); + } + }, + isSearching) + ); placeholderContainer.getChildren().add(placeholderLabel); listView.setPlaceholder(placeholderContainer); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java index 9820d1aa147..8c5db905a1a 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java @@ -23,6 +23,7 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.collections.ListChangeListener; import javafx.css.PseudoClass; import javafx.geometry.Insets; @@ -88,10 +89,10 @@ final class ModListPageSkin extends SkinBase { private final HBox toolbarSelecting; private final JFXListView listView; - private final JFXTextField searchField; - @FXThread - private boolean isSearching = false; + private final BooleanProperty isSearching = new SimpleBooleanProperty(false); + private final JFXTextField searchField; + private final PauseTransition searchPause = new PauseTransition(Duration.millis(100)); ModListPageSkin(ModListPage skinnable) { super(skinnable); @@ -118,18 +119,21 @@ final class ModListPageSkin extends SkinBase { searchField = new JFXTextField(); searchField.setPromptText(i18n("search")); HBox.setHgrow(searchField, Priority.ALWAYS); - PauseTransition pause = new PauseTransition(Duration.millis(100)); - pause.setOnFinished(e -> search()); + searchPause.setOnFinished(e -> search()); searchField.textProperty().addListener((observable, oldValue, newValue) -> { - pause.setRate(1); - pause.playFromStart(); + if (isSearching.get() || !StringUtils.isBlank(newValue)) { + searchPause.setRate(1); + searchPause.playFromStart(); + } }); JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE, () -> { changeToolbar(toolbarNormal); - isSearching = false; + searchPause.stop(); + + isSearching.set(false); searchField.clear(); Bindings.bindContent(listView.getItems(), getSkinnable().getItems()); }); @@ -192,7 +196,7 @@ final class ModListPageSkin extends SkinBase { FXUtils.onChangeAndOperate(listView.getSelectionModel().selectedItemProperty(), selectedItem -> { if (selectedItem == null) - changeToolbar(isSearching ? searchBar : toolbarNormal); + changeToolbar(isSearching.get() ? searchBar : toolbarNormal); else changeToolbar(toolbarSelecting); }); @@ -223,12 +227,22 @@ final class ModListPageSkin extends SkinBase { StackPane placeholderContainer = new StackPane(); placeholderContainer.getStyleClass().add("notice-pane"); Label placeholderLabel = new Label(i18n("mods.empty")); + placeholderLabel.textProperty().bind( + Bindings.createStringBinding(() -> { + if (isSearching.get()) { + return i18n("search.no_results_found"); + } else { + return i18n("mods.empty"); + } + }, + isSearching) + ); placeholderContainer.getChildren().add(placeholderLabel); listView.setPlaceholder(placeholderContainer); Bindings.bindContent(listView.getItems(), skinnable.getItems()); skinnable.getItems().addListener((ListChangeListener) c -> { - if (isSearching) { + if (isSearching.get()) { search(); } }); @@ -271,7 +285,7 @@ private void changeToolbar(HBox newToolbar) { } private void search() { - isSearching = true; + isSearching.set(true); Bindings.unbindContent(listView.getItems(), getSkinnable().getItems()); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java index 6b325dd207f..970a37b3332 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java @@ -266,7 +266,8 @@ private static final class ResourcePackListPageSkin extends SkinBase search()); + searchPause.setOnFinished(e -> search()); FXUtils.onChange(searchField.textProperty(), newValue -> { - pause.setRate(1); - pause.playFromStart(); + if (isSearching.get() || !StringUtils.isBlank(newValue)) { + searchPause.setRate(1); + searchPause.playFromStart(); + } }); JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE, () -> { changeToolbar(toolbarNormal); - isSearching = false; + searchPause.stop(); + + isSearching.set(false); searchField.clear(); Bindings.bindContent(listView.getItems(), getSkinnable().getItems()); }); @@ -346,7 +350,7 @@ private ResourcePackListPageSkin(ResourcePackListPage control) { FXUtils.onChangeAndOperate(listView.getSelectionModel().selectedItemProperty(), selectedItem -> { if (selectedItem == null) - changeToolbar(isSearching ? searchBar : toolbarNormal); + changeToolbar(isSearching.get() ? searchBar : toolbarNormal); else changeToolbar(toolbarSelecting); }); @@ -375,6 +379,16 @@ private ResourcePackListPageSkin(ResourcePackListPage control) { StackPane placeholderContainer = new StackPane(); placeholderContainer.getStyleClass().add("notice-pane"); Label placeholderLabel = new Label(i18n("resourcepack.empty")); + placeholderLabel.textProperty().bind( + Bindings.createStringBinding(() -> { + if (isSearching.get()) { + return i18n("search.no_results_found"); + } else { + return i18n("resourcepack.empty"); + } + }, + isSearching) + ); placeholderContainer.getChildren().add(placeholderLabel); listView.setPlaceholder(placeholderContainer); @@ -410,7 +424,7 @@ private void changeToolbar(HBox newToolbar) { } private void search() { - isSearching = true; + isSearching.set(true); Bindings.unbindContent(listView.getItems(), getSkinnable().getItems()); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 452fe1c74d9..1894f115fba 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -1344,6 +1344,7 @@ search.sort=Sort By search.first_page=First search.previous_page=Previous search.next_page=Next +search.no_results_found=No results found search.last_page=Last search.page_n=%1$d / %2$s diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 699d0d41afc..301424f5caa 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -1137,6 +1137,7 @@ search.sort=排序 search.first_page=第一頁 search.previous_page=上一頁 search.next_page=下一頁 +search.no_results_found=搜尋無結果 search.last_page=最後一頁 search.page_n=%d / %s diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 17e9b21ea66..8b52588e720 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -962,6 +962,7 @@ mods.mcmod=MC 百科 mods.mcmod.page=MC 百科页面 mods.mcmod.search=MC 百科搜索 mods.name=名称 +mods.no_results_found=搜索无结果 mods.not_modded=你需要先在“自动安装”页面安装 Forge、NeoForge、Fabric、Legacy Fabric、Quilt 或 LiteLoader 才能管理模组。 mods.restore=回退 mods.url=官方页面 @@ -1142,6 +1143,7 @@ search.sort=排序 search.first_page=第一页 search.previous_page=上一页 search.next_page=下一页 +search.no_results_found=搜索无结果 search.last_page=最后一页 search.page_n=%d / %s From 932ef1ba60fcc742cfff34a1511716c06a337851 Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Sat, 18 Jul 2026 01:37:25 +0800 Subject: [PATCH 3/6] Chore: I18n --- HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 8b52588e720..cc14a8c64a3 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -962,7 +962,6 @@ mods.mcmod=MC 百科 mods.mcmod.page=MC 百科页面 mods.mcmod.search=MC 百科搜索 mods.name=名称 -mods.no_results_found=搜索无结果 mods.not_modded=你需要先在“自动安装”页面安装 Forge、NeoForge、Fabric、Legacy Fabric、Quilt 或 LiteLoader 才能管理模组。 mods.restore=回退 mods.url=官方页面 From 968d0144d821d502387b12218c92f2d66bf5f596 Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Sat, 18 Jul 2026 01:46:36 +0800 Subject: [PATCH 4/6] Fix: Search field clearance and predicate reset order on close --- .../org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java | 2 +- .../java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java | 2 +- .../org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java index 6699e6fdc36..c72154a0986 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java @@ -161,10 +161,10 @@ final class DataPackListPageSkin extends SkinBase { }); JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE, () -> { + searchField.clear(); searchPause.stop(); isSearching.set(false); - searchField.clear(); }); FXUtils.onEscPressed(searchField, closeSearchBar::fire); searchBar.getChildren().addAll(searchField, closeSearchBar); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java index 8c5db905a1a..a3491fc31a8 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java @@ -131,10 +131,10 @@ final class ModListPageSkin extends SkinBase { () -> { changeToolbar(toolbarNormal); + searchField.clear(); searchPause.stop(); isSearching.set(false); - searchField.clear(); Bindings.bindContent(listView.getItems(), getSkinnable().getItems()); }); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java index 970a37b3332..86c1768c6bb 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java @@ -322,10 +322,10 @@ private ResourcePackListPageSkin(ResourcePackListPage control) { () -> { changeToolbar(toolbarNormal); + searchField.clear(); searchPause.stop(); isSearching.set(false); - searchField.clear(); Bindings.bindContent(listView.getItems(), getSkinnable().getItems()); }); From 277e8eb903f9a28932040966109729dc87b44c4f Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Sat, 18 Jul 2026 02:09:36 +0800 Subject: [PATCH 5/6] Fix: Explicitly reset filtered list predicate on closing data-pack search --- .../org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java index c72154a0986..663c42ce898 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java @@ -164,6 +164,8 @@ final class DataPackListPageSkin extends SkinBase { searchField.clear(); searchPause.stop(); + filteredList.setPredicate(null); + isSearching.set(false); }); FXUtils.onEscPressed(searchField, closeSearchBar::fire); From 9f6e7b731cd7f110984023934addcaa27b3b3132 Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Sun, 19 Jul 2026 01:01:00 +0800 Subject: [PATCH 6/6] Docs: Add Markdown field documentation for search states per AGENTS.md --- .../org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java | 4 ++++ .../java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java | 4 ++++ .../org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java | 3 +++ 3 files changed, 11 insertions(+) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java index 663c42ce898..5c4194a3c6c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java @@ -82,9 +82,13 @@ final class DataPackListPageSkin extends SkinBase { private final JFXListView listView; private final FilteredList filteredList; + /// Whether the search mechanism is currently active. private final BooleanProperty isSearching = new SimpleBooleanProperty(false); + private final BooleanProperty isSelecting = new SimpleBooleanProperty(false); private final JFXTextField searchField; + + /// Timer for debouncing search input to avoid executing search on every keystroke. private final PauseTransition searchPause = new PauseTransition(Duration.millis(100)); private static final AtomicInteger lastShiftClickIndex = new AtomicInteger(-1); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java index a3491fc31a8..dd47fb1899b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java @@ -90,8 +90,12 @@ final class ModListPageSkin extends SkinBase { private final JFXListView listView; + /// Whether the search mechanism is currently active. private final BooleanProperty isSearching = new SimpleBooleanProperty(false); + private final JFXTextField searchField; + + /// Timer for debouncing search input to avoid executing search on every keystroke. private final PauseTransition searchPause = new PauseTransition(Duration.millis(100)); ModListPageSkin(ModListPage skinnable) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java index 86c1768c6bb..637ab6d5eec 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ResourcePackListPage.java @@ -266,7 +266,10 @@ private static final class ResourcePackListPageSkin extends SkinBase