重构 JavaManagementPage 以使用 ListCell 展示元素 (#5223)
This commit is contained in:
@@ -18,17 +18,19 @@
|
|||||||
package org.jackhuang.hmcl.ui.main;
|
package org.jackhuang.hmcl.ui.main;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXListView;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.ListCell;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.scene.control.SkinBase;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.java.JavaInfo;
|
import org.jackhuang.hmcl.java.JavaInfo;
|
||||||
import org.jackhuang.hmcl.java.JavaManager;
|
import org.jackhuang.hmcl.java.JavaManager;
|
||||||
@@ -42,6 +44,7 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
|||||||
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
|
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
|
||||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||||
import org.jackhuang.hmcl.ui.wizard.SinglePageWizardProvider;
|
import org.jackhuang.hmcl.ui.wizard.SinglePageWizardProvider;
|
||||||
|
import org.jackhuang.hmcl.util.FXThread;
|
||||||
import org.jackhuang.hmcl.util.Pair;
|
import org.jackhuang.hmcl.util.Pair;
|
||||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
@@ -62,7 +65,7 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
|||||||
/**
|
/**
|
||||||
* @author Glavo
|
* @author Glavo
|
||||||
*/
|
*/
|
||||||
public final class JavaManagementPage extends ListPageBase<JavaManagementPage.JavaItem> {
|
public final class JavaManagementPage extends ListPageBase<JavaRuntime> {
|
||||||
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
private final ChangeListener<Collection<JavaRuntime>> listener;
|
private final ChangeListener<Collection<JavaRuntime>> listener;
|
||||||
@@ -172,130 +175,17 @@ public final class JavaManagementPage extends ListPageBase<JavaManagementPage.Ja
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FXThread
|
@FXThread
|
||||||
private void loadJava(Collection<JavaRuntime> javaRuntimes) {
|
private void loadJava(Collection<JavaRuntime> javaRuntimes) {
|
||||||
if (javaRuntimes != null) {
|
if (javaRuntimes != null) {
|
||||||
List<JavaItem> items = new ArrayList<>();
|
this.setItems(FXCollections.observableArrayList(javaRuntimes));
|
||||||
for (JavaRuntime java : javaRuntimes) {
|
|
||||||
items.add(new JavaItem(java));
|
|
||||||
}
|
|
||||||
this.setItems(FXCollections.observableList(items));
|
|
||||||
this.setLoading(false);
|
this.setLoading(false);
|
||||||
} else
|
} else {
|
||||||
this.setLoading(true);
|
this.setLoading(true);
|
||||||
}
|
|
||||||
|
|
||||||
static final class JavaItem extends Control {
|
|
||||||
private final JavaRuntime java;
|
|
||||||
|
|
||||||
public JavaItem(JavaRuntime java) {
|
|
||||||
this.java = java;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JavaRuntime getJava() {
|
|
||||||
return java;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onReveal() {
|
|
||||||
Path target;
|
|
||||||
Path parent = java.getBinary().getParent();
|
|
||||||
if (parent != null
|
|
||||||
&& parent.getParent() != null
|
|
||||||
&& parent.getFileName() != null
|
|
||||||
&& parent.getFileName().toString().equals("bin")
|
|
||||||
&& Files.exists(parent.getParent().resolve("release"))) {
|
|
||||||
target = parent.getParent();
|
|
||||||
} else {
|
|
||||||
target = java.getBinary();
|
|
||||||
}
|
|
||||||
|
|
||||||
FXUtils.showFileInExplorer(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onRemove() {
|
|
||||||
if (java.isManaged()) {
|
|
||||||
Controllers.taskDialog(JavaManager.getUninstallJavaTask(java), i18n("java.uninstall"), TaskCancellationAction.NORMAL);
|
|
||||||
} else {
|
|
||||||
String path = java.getBinary().toString();
|
|
||||||
ConfigHolder.globalConfig().getUserJava().remove(path);
|
|
||||||
ConfigHolder.globalConfig().getDisabledJava().add(path);
|
|
||||||
try {
|
|
||||||
JavaManager.removeJava(java);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Skin<?> createDefaultSkin() {
|
|
||||||
return new JavaRuntimeItemSkin(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class JavaRuntimeItemSkin extends SkinBase<JavaItem> {
|
|
||||||
|
|
||||||
JavaRuntimeItemSkin(JavaItem control) {
|
|
||||||
super(control);
|
|
||||||
JavaRuntime java = control.getJava();
|
|
||||||
String vendor = JavaInfo.normalizeVendor(java.getVendor());
|
|
||||||
|
|
||||||
BorderPane root = new BorderPane();
|
|
||||||
|
|
||||||
HBox center = new HBox();
|
|
||||||
center.setMouseTransparent(true);
|
|
||||||
center.setSpacing(8);
|
|
||||||
center.setAlignment(Pos.CENTER_LEFT);
|
|
||||||
|
|
||||||
TwoLineListItem item = new TwoLineListItem();
|
|
||||||
item.setTitle((java.isJDK() ? "JDK" : "JRE") + " " + java.getVersion());
|
|
||||||
item.setSubtitle(java.getBinary().toString());
|
|
||||||
item.addTag(i18n("java.info.architecture") + ": " + java.getArchitecture().getDisplayName());
|
|
||||||
if (vendor != null)
|
|
||||||
item.addTag(i18n("java.info.vendor") + ": " + vendor);
|
|
||||||
BorderPane.setAlignment(item, Pos.CENTER);
|
|
||||||
center.getChildren().setAll(item);
|
|
||||||
root.setCenter(center);
|
|
||||||
|
|
||||||
HBox right = new HBox();
|
|
||||||
right.setAlignment(Pos.CENTER_RIGHT);
|
|
||||||
{
|
|
||||||
JFXButton revealButton = new JFXButton();
|
|
||||||
revealButton.getStyleClass().add("toggle-icon4");
|
|
||||||
revealButton.setGraphic(FXUtils.limitingSize(SVG.FOLDER_OPEN.createIcon(24), 24, 24));
|
|
||||||
revealButton.setOnAction(e -> control.onReveal());
|
|
||||||
FXUtils.installFastTooltip(revealButton, i18n("reveal.in_file_manager"));
|
|
||||||
|
|
||||||
JFXButton removeButton = new JFXButton();
|
|
||||||
removeButton.getStyleClass().add("toggle-icon4");
|
|
||||||
removeButton.setOnAction(e -> Controllers.confirm(
|
|
||||||
java.isManaged() ? i18n("java.uninstall.confirm") : i18n("java.disable.confirm"),
|
|
||||||
i18n("message.warning"),
|
|
||||||
control::onRemove,
|
|
||||||
null
|
|
||||||
));
|
|
||||||
if (java.isManaged()) {
|
|
||||||
removeButton.setGraphic(FXUtils.limitingSize(SVG.DELETE_FOREVER.createIcon(24), 24, 24));
|
|
||||||
FXUtils.installFastTooltip(removeButton, i18n("java.uninstall"));
|
|
||||||
if (JavaRuntime.CURRENT_JAVA != null && java.getBinary().equals(JavaRuntime.CURRENT_JAVA.getBinary()))
|
|
||||||
removeButton.setDisable(true);
|
|
||||||
} else {
|
|
||||||
removeButton.setGraphic(FXUtils.limitingSize(SVG.DELETE.createIcon(24), 24, 24));
|
|
||||||
FXUtils.installFastTooltip(removeButton, i18n("java.disable"));
|
|
||||||
}
|
|
||||||
|
|
||||||
right.getChildren().setAll(revealButton, removeButton);
|
|
||||||
}
|
|
||||||
root.setRight(right);
|
|
||||||
|
|
||||||
root.getStyleClass().add("md-list-cell");
|
|
||||||
root.setPadding(new Insets(8));
|
|
||||||
|
|
||||||
getChildren().setAll(new RipplerContainer(root));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class JavaPageSkin extends ToolbarListPageSkin<JavaItem, JavaManagementPage> {
|
private static final class JavaPageSkin extends ToolbarListPageSkin<JavaRuntime, JavaManagementPage> {
|
||||||
|
|
||||||
JavaPageSkin(JavaManagementPage skinnable) {
|
JavaPageSkin(JavaManagementPage skinnable) {
|
||||||
super(skinnable);
|
super(skinnable);
|
||||||
@@ -317,5 +207,139 @@ public final class JavaManagementPage extends ListPageBase<JavaManagementPage.Ja
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ListCell<JavaRuntime> createListCell(JFXListView<JavaRuntime> listView) {
|
||||||
|
return new JavaItemCell();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class JavaItemCell extends ListCell<JavaRuntime> {
|
||||||
|
private final Node graphic;
|
||||||
|
private final TwoLineListItem content;
|
||||||
|
|
||||||
|
private SVG removeIcon;
|
||||||
|
private final StackPane removeIconPane;
|
||||||
|
private final Tooltip removeTooltip = new Tooltip();
|
||||||
|
|
||||||
|
JavaItemCell() {
|
||||||
|
BorderPane root = new BorderPane();
|
||||||
|
|
||||||
|
HBox center = new HBox();
|
||||||
|
center.setMouseTransparent(true);
|
||||||
|
center.setSpacing(8);
|
||||||
|
center.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
this.content = new TwoLineListItem();
|
||||||
|
|
||||||
|
BorderPane.setAlignment(content, Pos.CENTER);
|
||||||
|
center.getChildren().setAll(content);
|
||||||
|
root.setCenter(center);
|
||||||
|
|
||||||
|
HBox right = new HBox();
|
||||||
|
right.setAlignment(Pos.CENTER_RIGHT);
|
||||||
|
{
|
||||||
|
JFXButton revealButton = new JFXButton();
|
||||||
|
revealButton.setGraphic(FXUtils.limitingSize(SVG.FOLDER_OPEN.createIcon(24), 24, 24));
|
||||||
|
revealButton.getStyleClass().add("toggle-icon4");
|
||||||
|
revealButton.setOnAction(e -> {
|
||||||
|
JavaRuntime java = getItem();
|
||||||
|
if (java != null)
|
||||||
|
onReveal(java);
|
||||||
|
});
|
||||||
|
FXUtils.installFastTooltip(revealButton, i18n("reveal.in_file_manager"));
|
||||||
|
|
||||||
|
JFXButton removeButton = new JFXButton();
|
||||||
|
removeButton.getStyleClass().add("toggle-icon4");
|
||||||
|
removeButton.setOnAction(e -> {
|
||||||
|
JavaRuntime java = getItem();
|
||||||
|
if (java != null)
|
||||||
|
onRemove(java);
|
||||||
|
});
|
||||||
|
FXUtils.installFastTooltip(removeButton, removeTooltip);
|
||||||
|
|
||||||
|
this.removeIconPane = new StackPane();
|
||||||
|
removeIconPane.setAlignment(Pos.CENTER);
|
||||||
|
FXUtils.setLimitWidth(removeIconPane, 24);
|
||||||
|
FXUtils.setLimitHeight(removeIconPane, 24);
|
||||||
|
removeButton.setGraphic(removeIconPane);
|
||||||
|
|
||||||
|
right.getChildren().setAll(revealButton, removeButton);
|
||||||
|
}
|
||||||
|
root.setRight(right);
|
||||||
|
|
||||||
|
root.getStyleClass().add("md-list-cell");
|
||||||
|
root.setPadding(new Insets(8));
|
||||||
|
|
||||||
|
this.graphic = new RipplerContainer(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(JavaRuntime item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (empty || item == null) {
|
||||||
|
setGraphic(null);
|
||||||
|
} else {
|
||||||
|
content.setTitle((item.isJDK() ? "JDK" : "JRE") + " " + item.getVersion());
|
||||||
|
content.setSubtitle(item.getBinary().toString());
|
||||||
|
|
||||||
|
content.getTags().clear();
|
||||||
|
content.addTag(i18n("java.info.architecture") + ": " + item.getArchitecture().getDisplayName());
|
||||||
|
String vendor = JavaInfo.normalizeVendor(item.getVendor());
|
||||||
|
if (vendor != null)
|
||||||
|
content.addTag(i18n("java.info.vendor") + ": " + vendor);
|
||||||
|
|
||||||
|
SVG newRemoveIcon = item.isManaged() ? SVG.DELETE_FOREVER : SVG.DELETE;
|
||||||
|
if (removeIcon != newRemoveIcon) {
|
||||||
|
removeIcon = newRemoveIcon;
|
||||||
|
removeIconPane.getChildren().setAll(removeIcon.createIcon(24));
|
||||||
|
removeTooltip.setText(item.isManaged() ? i18n("java.uninstall") : i18n("java.disable"));
|
||||||
|
}
|
||||||
|
|
||||||
|
setGraphic(graphic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onReveal(JavaRuntime java) {
|
||||||
|
Path target;
|
||||||
|
Path parent = java.getBinary().getParent();
|
||||||
|
if (parent != null
|
||||||
|
&& parent.getParent() != null
|
||||||
|
&& parent.getFileName() != null
|
||||||
|
&& parent.getFileName().toString().equals("bin")
|
||||||
|
&& Files.exists(parent.getParent().resolve("release"))) {
|
||||||
|
target = parent.getParent();
|
||||||
|
} else {
|
||||||
|
target = java.getBinary();
|
||||||
|
}
|
||||||
|
|
||||||
|
FXUtils.showFileInExplorer(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRemove(JavaRuntime java) {
|
||||||
|
if (java.isManaged()) {
|
||||||
|
Controllers.confirm(
|
||||||
|
i18n("java.uninstall.confirm"),
|
||||||
|
i18n("message.warning"),
|
||||||
|
() -> Controllers.taskDialog(JavaManager.getUninstallJavaTask(java), i18n("java.uninstall"), TaskCancellationAction.NORMAL),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Controllers.confirm(
|
||||||
|
i18n("java.disable.confirm"),
|
||||||
|
i18n("message.warning"),
|
||||||
|
() -> {
|
||||||
|
String path = java.getBinary().toString();
|
||||||
|
ConfigHolder.globalConfig().getUserJava().remove(path);
|
||||||
|
ConfigHolder.globalConfig().getDisabledJava().add(path);
|
||||||
|
try {
|
||||||
|
JavaManager.removeJava(java);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user