-
Notifications
You must be signed in to change notification settings - Fork 818
在陶瓦联机页面添加切换账号菜单 #5270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在陶瓦联机页面添加切换账号菜单 #5270
Conversation
Glavo
commented
Jan 20, 2026
# Conflicts: # HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
在“陶瓦联机”页面左侧菜单中加入账号入口,并支持通过右键弹出账号切换菜单,以便快速切换已登录账号。
Changes:
- 在
TerracottaPage左侧工具栏新增账号项,并支持右键弹出账号列表菜单 - 将
RootPage中账号切换弹出菜单逻辑抽取为可复用组件 - 新增
AccountListPopupMenu作为账号列表弹出菜单实现
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaPage.java | 在陶瓦联机页面侧边栏增加账号项,并提供右键弹出切换菜单入口 |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java | 替换内联账号弹出菜单实现,改为复用新组件 |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPopupMenu.java | 新增账号列表弹出菜单组件供多处复用 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public final class AccountListPopupMenu extends StackPane { | ||
| public static void show(Node owner, JFXPopup.PopupVPosition vAlign, JFXPopup.PopupHPosition hAlign, | ||
| double initOffsetX, double initOffsetY) { | ||
| var menu = new AccountListPopupMenu(); | ||
| JFXPopup popup = new JFXPopup(menu); | ||
| popup.show(owner, vAlign, hAlign, initOffsetX, initOffsetY); | ||
| } |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AccountListPopupMenu doesn’t apply the popup menu styling class used elsewhere (e.g. GameListPopupMenu adds popup-menu-content, and PopupMenu skin wraps content with the same class). Without it, this popup may render without the expected background/padding/theme. Consider adding the same style class to this root node (or reusing PopupMenu) to keep appearance consistent.
| @SuppressWarnings("FieldCanBeLocal") | ||
| private final BooleanBinding isEmpty = Bindings.isEmpty(Accounts.getAccounts()); | ||
| @SuppressWarnings("FieldCanBeLocal") | ||
| private final InvalidationListener listener; | ||
|
|
||
| public AccountListPopupMenu() { | ||
| AdvancedListBox box = new AdvancedListBox(); | ||
| box.getStyleClass().add("no-padding"); | ||
| box.setPrefWidth(220); | ||
| box.setPrefHeight(-1); | ||
| box.setMaxHeight(260); | ||
|
|
||
| listener = o -> { | ||
| box.clear(); | ||
|
|
||
| for (Account account : Accounts.getAccounts()) { | ||
| AccountAdvancedListItem item = new AccountAdvancedListItem(account); | ||
| item.setOnAction(e -> { | ||
| Accounts.setSelectedAccount(account); | ||
| if (getScene().getWindow() instanceof JFXPopup popup) | ||
| popup.hide(); | ||
| }); | ||
| box.add(item); | ||
| } | ||
| }; | ||
| listener.invalidated(null); | ||
| Accounts.getAccounts().addListener(new WeakInvalidationListener(listener)); | ||
|
|
||
| Label placeholder = new Label(i18n("account.empty")); | ||
| placeholder.setStyle("-fx-padding: 10px; -fx-text-fill: -monet-on-surface-variant; -fx-font-style: italic;"); | ||
|
|
||
| FXUtils.onChangeAndOperate(isEmpty, empty -> { | ||
| getChildren().setAll(empty ? placeholder : box); | ||
| }); |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isEmpty is a BooleanBinding created from the global Accounts.getAccounts() list, and FXUtils.onChangeAndOperate(...) attaches a strong listener to that binding. Because the binding itself listens to Accounts.getAccounts(), this can keep each popup instance reachable via listeners even after the popup is hidden (leaking menus over time). Prefer updating the placeholder/content inside the existing (weak) list listener (e.g. check Accounts.getAccounts().isEmpty() there), or otherwise ensure listeners/bindings are disposed/unregistered when the popup closes.