Skip to content

Commit ccc64db

Browse files
authored
重构 JavaManagementPage 以使用 ListCell 展示元素 (#5223)
1 parent ea407be commit ccc64db

1 file changed

Lines changed: 116 additions & 92 deletions

File tree

HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java

Lines changed: 116 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@
1818
package org.jackhuang.hmcl.ui.main;
1919

2020
import com.jfoenix.controls.JFXButton;
21+
import com.jfoenix.controls.JFXListView;
2122
import javafx.beans.binding.Bindings;
2223
import javafx.beans.value.ChangeListener;
2324
import javafx.collections.FXCollections;
2425
import javafx.geometry.Insets;
2526
import javafx.geometry.Pos;
2627
import javafx.scene.Node;
27-
import javafx.scene.control.Control;
28+
import javafx.scene.control.ListCell;
2829
import javafx.scene.control.Skin;
29-
import javafx.scene.control.SkinBase;
30+
import javafx.scene.control.Tooltip;
3031
import javafx.scene.layout.BorderPane;
3132
import javafx.scene.layout.HBox;
33+
import javafx.scene.layout.StackPane;
3234
import javafx.stage.FileChooser;
3335
import org.jackhuang.hmcl.java.JavaInfo;
3436
import org.jackhuang.hmcl.java.JavaManager;
@@ -42,6 +44,7 @@
4244
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
4345
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
4446
import org.jackhuang.hmcl.ui.wizard.SinglePageWizardProvider;
47+
import org.jackhuang.hmcl.util.FXThread;
4548
import org.jackhuang.hmcl.util.Pair;
4649
import org.jackhuang.hmcl.util.TaskCancellationAction;
4750
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -62,7 +65,7 @@
6265
/**
6366
* @author Glavo
6467
*/
65-
public final class JavaManagementPage extends ListPageBase<JavaManagementPage.JavaItem> {
68+
public final class JavaManagementPage extends ListPageBase<JavaRuntime> {
6669

6770
@SuppressWarnings("FieldCanBeLocal")
6871
private final ChangeListener<Collection<JavaRuntime>> listener;
@@ -172,117 +175,94 @@ private void onInstallArchive(Path file) {
172175
}).start();
173176
}
174177

175-
// FXThread
178+
@FXThread
176179
private void loadJava(Collection<JavaRuntime> javaRuntimes) {
177180
if (javaRuntimes != null) {
178-
List<JavaItem> items = new ArrayList<>();
179-
for (JavaRuntime java : javaRuntimes) {
180-
items.add(new JavaItem(java));
181-
}
182-
this.setItems(FXCollections.observableList(items));
181+
this.setItems(FXCollections.observableArrayList(javaRuntimes));
183182
this.setLoading(false);
184-
} else
183+
} else {
185184
this.setLoading(true);
185+
}
186186
}
187187

188-
static final class JavaItem extends Control {
189-
private final JavaRuntime java;
188+
private static final class JavaPageSkin extends ToolbarListPageSkin<JavaRuntime, JavaManagementPage> {
190189

191-
public JavaItem(JavaRuntime java) {
192-
this.java = java;
190+
JavaPageSkin(JavaManagementPage skinnable) {
191+
super(skinnable);
193192
}
194193

195-
public JavaRuntime getJava() {
196-
return java;
197-
}
194+
@Override
195+
protected List<Node> initializeToolbar(JavaManagementPage skinnable) {
196+
ArrayList<Node> res = new ArrayList<>(4);
198197

199-
public void onReveal() {
200-
Path target;
201-
Path parent = java.getBinary().getParent();
202-
if (parent != null
203-
&& parent.getParent() != null
204-
&& parent.getFileName() != null
205-
&& parent.getFileName().toString().equals("bin")
206-
&& Files.exists(parent.getParent().resolve("release"))) {
207-
target = parent.getParent();
208-
} else {
209-
target = java.getBinary();
198+
res.add(createToolbarButton2(i18n("button.refresh"), SVG.REFRESH, JavaManager::refresh));
199+
if (skinnable.onInstallJava != null) {
200+
res.add(createToolbarButton2(i18n("java.download"), SVG.DOWNLOAD, skinnable.onInstallJava));
210201
}
202+
res.add(createToolbarButton2(i18n("java.add"), SVG.ADD, skinnable::onAddJava));
211203

212-
FXUtils.showFileInExplorer(target);
213-
}
204+
JFXButton disableJava = createToolbarButton2(i18n("java.disabled.management"), SVG.FORMAT_LIST_BULLETED, skinnable::onShowRestoreJavaPage);
205+
disableJava.disableProperty().bind(Bindings.isEmpty(ConfigHolder.globalConfig().getDisabledJava()));
206+
res.add(disableJava);
214207

215-
public void onRemove() {
216-
if (java.isManaged()) {
217-
Controllers.taskDialog(JavaManager.getUninstallJavaTask(java), i18n("java.uninstall"), TaskCancellationAction.NORMAL);
218-
} else {
219-
String path = java.getBinary().toString();
220-
ConfigHolder.globalConfig().getUserJava().remove(path);
221-
ConfigHolder.globalConfig().getDisabledJava().add(path);
222-
try {
223-
JavaManager.removeJava(java);
224-
} catch (InterruptedException ignored) {
225-
}
226-
}
208+
return res;
227209
}
228210

229211
@Override
230-
protected Skin<?> createDefaultSkin() {
231-
return new JavaRuntimeItemSkin(this);
212+
protected ListCell<JavaRuntime> createListCell(JFXListView<JavaRuntime> listView) {
213+
return new JavaItemCell();
232214
}
233-
234215
}
235216

236-
private static final class JavaRuntimeItemSkin extends SkinBase<JavaItem> {
217+
private static final class JavaItemCell extends ListCell<JavaRuntime> {
218+
private final Node graphic;
219+
private final TwoLineListItem content;
237220

238-
JavaRuntimeItemSkin(JavaItem control) {
239-
super(control);
240-
JavaRuntime java = control.getJava();
241-
String vendor = JavaInfo.normalizeVendor(java.getVendor());
221+
private SVG removeIcon;
222+
private final StackPane removeIconPane;
223+
private final Tooltip removeTooltip = new Tooltip();
242224

225+
JavaItemCell() {
243226
BorderPane root = new BorderPane();
244227

245228
HBox center = new HBox();
246229
center.setMouseTransparent(true);
247230
center.setSpacing(8);
248231
center.setAlignment(Pos.CENTER_LEFT);
249232

250-
TwoLineListItem item = new TwoLineListItem();
251-
item.setTitle((java.isJDK() ? "JDK" : "JRE") + " " + java.getVersion());
252-
item.setSubtitle(java.getBinary().toString());
253-
item.addTag(i18n("java.info.architecture") + ": " + java.getArchitecture().getDisplayName());
254-
if (vendor != null)
255-
item.addTag(i18n("java.info.vendor") + ": " + vendor);
256-
BorderPane.setAlignment(item, Pos.CENTER);
257-
center.getChildren().setAll(item);
233+
this.content = new TwoLineListItem();
234+
235+
BorderPane.setAlignment(content, Pos.CENTER);
236+
center.getChildren().setAll(content);
258237
root.setCenter(center);
259238

260239
HBox right = new HBox();
261240
right.setAlignment(Pos.CENTER_RIGHT);
262241
{
263242
JFXButton revealButton = new JFXButton();
264-
revealButton.getStyleClass().add("toggle-icon4");
265243
revealButton.setGraphic(FXUtils.limitingSize(SVG.FOLDER_OPEN.createIcon(24), 24, 24));
266-
revealButton.setOnAction(e -> control.onReveal());
244+
revealButton.getStyleClass().add("toggle-icon4");
245+
revealButton.setOnAction(e -> {
246+
JavaRuntime java = getItem();
247+
if (java != null)
248+
onReveal(java);
249+
});
267250
FXUtils.installFastTooltip(revealButton, i18n("reveal.in_file_manager"));
268251

269252
JFXButton removeButton = new JFXButton();
270253
removeButton.getStyleClass().add("toggle-icon4");
271-
removeButton.setOnAction(e -> Controllers.confirm(
272-
java.isManaged() ? i18n("java.uninstall.confirm") : i18n("java.disable.confirm"),
273-
i18n("message.warning"),
274-
control::onRemove,
275-
null
276-
));
277-
if (java.isManaged()) {
278-
removeButton.setGraphic(FXUtils.limitingSize(SVG.DELETE_FOREVER.createIcon(24), 24, 24));
279-
FXUtils.installFastTooltip(removeButton, i18n("java.uninstall"));
280-
if (JavaRuntime.CURRENT_JAVA != null && java.getBinary().equals(JavaRuntime.CURRENT_JAVA.getBinary()))
281-
removeButton.setDisable(true);
282-
} else {
283-
removeButton.setGraphic(FXUtils.limitingSize(SVG.DELETE.createIcon(24), 24, 24));
284-
FXUtils.installFastTooltip(removeButton, i18n("java.disable"));
285-
}
254+
removeButton.setOnAction(e -> {
255+
JavaRuntime java = getItem();
256+
if (java != null)
257+
onRemove(java);
258+
});
259+
FXUtils.installFastTooltip(removeButton, removeTooltip);
260+
261+
this.removeIconPane = new StackPane();
262+
removeIconPane.setAlignment(Pos.CENTER);
263+
FXUtils.setLimitWidth(removeIconPane, 24);
264+
FXUtils.setLimitHeight(removeIconPane, 24);
265+
removeButton.setGraphic(removeIconPane);
286266

287267
right.getChildren().setAll(revealButton, removeButton);
288268
}
@@ -291,31 +271,75 @@ private static final class JavaRuntimeItemSkin extends SkinBase<JavaItem> {
291271
root.getStyleClass().add("md-list-cell");
292272
root.setPadding(new Insets(8));
293273

294-
getChildren().setAll(new RipplerContainer(root));
274+
this.graphic = new RipplerContainer(root);
295275
}
296-
}
297276

298-
private static final class JavaPageSkin extends ToolbarListPageSkin<JavaItem, JavaManagementPage> {
277+
@Override
278+
protected void updateItem(JavaRuntime item, boolean empty) {
279+
super.updateItem(item, empty);
280+
if (empty || item == null) {
281+
setGraphic(null);
282+
} else {
283+
content.setTitle((item.isJDK() ? "JDK" : "JRE") + " " + item.getVersion());
284+
content.setSubtitle(item.getBinary().toString());
285+
286+
content.getTags().clear();
287+
content.addTag(i18n("java.info.architecture") + ": " + item.getArchitecture().getDisplayName());
288+
String vendor = JavaInfo.normalizeVendor(item.getVendor());
289+
if (vendor != null)
290+
content.addTag(i18n("java.info.vendor") + ": " + vendor);
291+
292+
SVG newRemoveIcon = item.isManaged() ? SVG.DELETE_FOREVER : SVG.DELETE;
293+
if (removeIcon != newRemoveIcon) {
294+
removeIcon = newRemoveIcon;
295+
removeIconPane.getChildren().setAll(removeIcon.createIcon(24));
296+
removeTooltip.setText(item.isManaged() ? i18n("java.uninstall") : i18n("java.disable"));
297+
}
299298

300-
JavaPageSkin(JavaManagementPage skinnable) {
301-
super(skinnable);
299+
setGraphic(graphic);
300+
}
302301
}
303302

304-
@Override
305-
protected List<Node> initializeToolbar(JavaManagementPage skinnable) {
306-
ArrayList<Node> res = new ArrayList<>(4);
307-
308-
res.add(createToolbarButton2(i18n("button.refresh"), SVG.REFRESH, JavaManager::refresh));
309-
if (skinnable.onInstallJava != null) {
310-
res.add(createToolbarButton2(i18n("java.download"), SVG.DOWNLOAD, skinnable.onInstallJava));
303+
private void onReveal(JavaRuntime java) {
304+
Path target;
305+
Path parent = java.getBinary().getParent();
306+
if (parent != null
307+
&& parent.getParent() != null
308+
&& parent.getFileName() != null
309+
&& parent.getFileName().toString().equals("bin")
310+
&& Files.exists(parent.getParent().resolve("release"))) {
311+
target = parent.getParent();
312+
} else {
313+
target = java.getBinary();
311314
}
312-
res.add(createToolbarButton2(i18n("java.add"), SVG.ADD, skinnable::onAddJava));
313315

314-
JFXButton disableJava = createToolbarButton2(i18n("java.disabled.management"), SVG.FORMAT_LIST_BULLETED, skinnable::onShowRestoreJavaPage);
315-
disableJava.disableProperty().bind(Bindings.isEmpty(ConfigHolder.globalConfig().getDisabledJava()));
316-
res.add(disableJava);
316+
FXUtils.showFileInExplorer(target);
317+
}
317318

318-
return res;
319+
private void onRemove(JavaRuntime java) {
320+
if (java.isManaged()) {
321+
Controllers.confirm(
322+
i18n("java.uninstall.confirm"),
323+
i18n("message.warning"),
324+
() -> Controllers.taskDialog(JavaManager.getUninstallJavaTask(java), i18n("java.uninstall"), TaskCancellationAction.NORMAL),
325+
null
326+
);
327+
} else {
328+
Controllers.confirm(
329+
i18n("java.disable.confirm"),
330+
i18n("message.warning"),
331+
() -> {
332+
String path = java.getBinary().toString();
333+
ConfigHolder.globalConfig().getUserJava().remove(path);
334+
ConfigHolder.globalConfig().getDisabledJava().add(path);
335+
try {
336+
JavaManager.removeJava(java);
337+
} catch (InterruptedException ignored) {
338+
}
339+
},
340+
null
341+
);
342+
}
319343
}
320344
}
321345
}

0 commit comments

Comments
 (0)