Conversation
CiiLu
commented
Mar 28, 2026
- 修复模组管理点击全选会工具栏会闪烁的问题
- 在全选时禁用全选按钮
There was a problem hiding this comment.
Pull request overview
该 PR 针对版本管理页(模组/数据包列表)工具栏的“全选”交互进行优化:避免“全选”触发选择状态短暂清空导致的工具栏闪烁,并在已全选状态下禁用“全选”按钮以减少无效操作。
Changes:
- 将“全选”从
selectAll()改为selectRange(0, items.size()),减少选择状态抖动引起的工具栏闪烁 - 监听选中项变化,在已全选时禁用“全选”按钮
-(ModListPageSkin)将org.jackhuang.hmcl.util.*通配导入改为显式导入
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java | 调整模组列表“全选”实现并新增“全选按钮在全选时禁用”的逻辑 |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DataPackListPageSkin.java | 调整数据包列表“全选”实现并新增“全选按钮在全选时禁用”的逻辑 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| listView.getSelectionModel().getSelectedItems().addListener( | ||
| (ListChangeListener<Object>) change -> { | ||
| selectAll.setDisable(!listView.getItems().isEmpty() | ||
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size()); | ||
| } | ||
| ); |
There was a problem hiding this comment.
The select-all button disable state is only recomputed on selectedItems changes and isn’t initialized. If the item list size changes (e.g., refresh/search/filter adds/removes items) without a selection change, the button can stay disabled/enabled incorrectly. Prefer binding disableProperty to an expression that observes both items size and selectedItems size (and evaluate once initially) rather than a one-off listener.
| listView.getSelectionModel().getSelectedItems().addListener( | |
| (ListChangeListener<Object>) change -> { | |
| selectAll.setDisable(!listView.getItems().isEmpty() | |
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size()); | |
| } | |
| ); | |
| selectAll.disableProperty().bind(Bindings.createBooleanBinding( | |
| () -> !listView.getItems().isEmpty() | |
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size(), | |
| listView.getItems(), | |
| listView.getSelectionModel().getSelectedItems() | |
| )); |
| listView.getSelectionModel().getSelectedItems().addListener( | ||
| (ListChangeListener<Object>) change -> { | ||
| selectAll.setDisable(!listView.getItems().isEmpty() | ||
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size()); | ||
| } | ||
| ); |
There was a problem hiding this comment.
(ListChangeListener<Object>) is an unchecked/overly-broad cast here. It would be better to disambiguate the overloaded addListener call using the correct generic type (e.g., ListChangeListener or a named listener variable) so warnings aren’t suppressed and the intent stays type-safe.
| listView.getSelectionModel().getSelectedItems().addListener( | |
| (ListChangeListener<Object>) change -> { | |
| selectAll.setDisable(!listView.getItems().isEmpty() | |
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size()); | |
| } | |
| ); | |
| ListChangeListener<ModInfoObject> selectionListener = change -> { | |
| selectAll.setDisable(!listView.getItems().isEmpty() | |
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size()); | |
| }; | |
| listView.getSelectionModel().getSelectedItems().addListener(selectionListener); |
| // reason for not using selectAll() is that selectAll() first clears all selected then selects all, causing the toolbar to flicker | ||
| var selectAllButton = createToolbarButton2(i18n("button.select_all"), SVG.SELECT_ALL, () -> listView.getSelectionModel().selectRange(0, listView.getItems().size())); | ||
|
|
||
| listView.getSelectionModel().getSelectedItems().addListener( | ||
| (ListChangeListener<Object>) change -> { | ||
| selectAllButton.setDisable(!listView.getItems().isEmpty() | ||
| && listView.getSelectionModel().getSelectedItems().size() == listView.getItems().size()); | ||
| } | ||
| ); |
There was a problem hiding this comment.
The select-all button disable state is updated only when selectedItems changes and isn’t initialized. If listView.getItems() size changes (e.g., filtering/search updates) without a selection change, the button can remain disabled/enabled incorrectly. Consider binding disableProperty to a condition that observes both items size and selectedItems size, and ensure it’s evaluated once initially.
| var selectAllButton = createToolbarButton2(i18n("button.select_all"), SVG.SELECT_ALL, () -> listView.getSelectionModel().selectRange(0, listView.getItems().size())); | ||
|
|
||
| listView.getSelectionModel().getSelectedItems().addListener( | ||
| (ListChangeListener<Object>) change -> { |
There was a problem hiding this comment.
(ListChangeListener<Object>) is an unchecked/overly-broad cast and loses type safety. Use the correct generic type for the selectedItems list (e.g., ListChangeListener) or a named listener variable to disambiguate the overload without casting to Object.
| (ListChangeListener<Object>) change -> { | |
| (ListChangeListener<DataPack>) change -> { |