Skip to content
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

将 "Add Java" 的行为更改为选择一个目录后, 在目录中递归搜索并添加所有 Java #3494

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
78 changes: 78 additions & 0 deletions HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.jetbrains.annotations.Nullable;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.*;
Expand Down Expand Up @@ -176,6 +177,83 @@ public static void refresh() {
}).start();
}

private static class SearchJavaTask extends Task<List<JavaRuntime>> {

private final File directory;

SearchJavaTask(File directory, String name) {
this.directory = directory;
setName(name);
}

@Override
public void execute() throws Exception {
setResult(searchJava());
}

private List<JavaRuntime> searchJava() throws IOException, InterruptedException {
final int maxDepth = 3;

File[] subDirs = directory.listFiles(File::isDirectory);
if(subDirs == null) return Collections.emptyList();
List<JavaRuntime> binaryList = new ArrayList<>();
Queue<File> fileQueue = new LinkedList<>(Arrays.asList(subDirs));
fileQueue.add(directory);
final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable();
int depth = 1;
while(!fileQueue.isEmpty()) {
final File dir = fileQueue.poll();
if (dir == directory) {
depth++;
if (!fileQueue.isEmpty() && depth < maxDepth)
fileQueue.add(directory);
continue;
}
Path binary = dir.toPath().resolve(relative);
if (Files.exists(binary)) {
JavaRuntime java = JavaManager.getJava(binary);
if(java.getParsedVersion() <= 8 && java.isJDK()) {
binary = dir.toPath().resolve("jre").resolve(relative);
if(Files.exists(binary))
java = JavaManager.getJava(binary);
}
binaryList.add(java);
continue;
}
if(depth < maxDepth) {
subDirs = dir.listFiles(File::isDirectory);
if (subDirs != null)
fileQueue.addAll(Arrays.asList(subDirs));
}
if(isCancelled())
return Collections.emptyList();
}
return Collections.unmodifiableList(binaryList);
}
}

public static Task<List<JavaRuntime>> getSearchAndAddJavaTask(File directory) {
return new SearchJavaTask(directory, "Search Java")
.thenApplyAsync("Add Java", Schedulers.javafx(), javaRuntimes -> {
ArrayList<JavaRuntime> failedJavaRuntimes = new ArrayList<>();
for(JavaRuntime javaRuntime: javaRuntimes) {
if(!JavaManager.isCompatible(javaRuntime.getPlatform()))
failedJavaRuntimes.add(javaRuntime);
String pathString = javaRuntime.getBinary().toString();
ConfigHolder.globalConfig().getDisabledJava().remove(pathString);
if(ConfigHolder.globalConfig().getUserJava().add(pathString))
addJava(javaRuntime);
}
if(!failedJavaRuntimes.isEmpty()) {
StringBuilder sb = new StringBuilder("Incompatible platform: ");
for(JavaRuntime javaRuntime :javaRuntimes)
sb.append('\n').append(javaRuntime.getPlatform()).append(": ").append(javaRuntime.getBinary());
throw new UnsupportedPlatformException(sb.toString());
}
return javaRuntimes;
});
}

public static Task<JavaRuntime> getAddJavaTask(Path binary) {
return Task.supplyAsync("Get Java", () -> JavaManager.getJava(binary))
.thenApplyAsync(Schedulers.javafx(), javaRuntime -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.DirectoryChooser;
import org.jackhuang.hmcl.java.JavaInfo;
import org.jackhuang.hmcl.java.JavaManager;
import org.jackhuang.hmcl.java.JavaRuntime;
Expand Down Expand Up @@ -106,25 +106,39 @@ protected Skin<?> createDefaultSkin() {
}

void onAddJava() {
FileChooser chooser = new FileChooser();
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS)
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Java", "java.exe"));
final DirectoryChooser chooser = new DirectoryChooser();
chooser.setTitle(i18n("settings.game.java_directory.choose"));
File file = chooser.showOpenDialog(Controllers.getStage());
if (file != null) {
JavaManager.getAddJavaTask(file.toPath()).whenComplete(Schedulers.javafx(), exception -> {
if (exception != null) {
LOG.warning("Failed to add java", exception);
Controllers.dialog(i18n("java.add.failed"), i18n("message.error"), MessageDialogPane.MessageType.ERROR);
}
}).start();
File directory = chooser.showDialog(Controllers.getStage());
if(directory == null) return;

File file = new File(directory, OperatingSystem.CURRENT_OS.getJavaExecutable());
file = file.exists()? file
: new File(file, "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable());
if(file.exists()) {
onAddJavaBinary(file.toPath());
return;
}

onSearchAndAddJavaBinary(directory);
}

void onShowRestoreJavaPage() {
Controllers.navigate(new JavaRestorePage(ConfigHolder.globalConfig().getDisabledJava()));
}

private void onSearchAndAddJavaBinary(File directory) {
Task<Void> task = JavaManager.getSearchAndAddJavaTask(directory).thenAcceptAsync(Schedulers.javafx(), javaRuntimes -> {
if(javaRuntimes.isEmpty())
Controllers.dialog(i18n("java.add.not_found"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING);
}).whenComplete(Schedulers.javafx(), exception -> {
if(exception instanceof UnsupportedPlatformException) {
LOG.warning("Failed to add java", exception);
Controllers.dialog(i18n("java.add.failed.some"), i18n("message.error"), MessageDialogPane.MessageType.ERROR);
} else if(exception != null) LOG.warning("Other exception when add java", exception);
});
Controllers.taskDialog(task, i18n("java.add"), TaskCancellationAction.NORMAL);
}

private void onAddJavaBinary(Path file) {
JavaManager.getAddJavaTask(file).whenComplete(Schedulers.javafx(), exception -> {
if (exception != null) {
Expand Down
2 changes: 2 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,8 @@ install.success=Successfully installed.

java.add=Add Java
java.add.failed=This Java is invalid or incompatible with the current platform.
java.add.failed.some=Some of the found Java is invalid or incompatible with the current platform.
java.add.not_found=Java not found in specified directory, or the Java directory is too deep.
java.disable=Disable Java
java.disable.confirm=Are you sure you want to disable this Java?
java.disabled.management=Disabled Java
Expand Down
2 changes: 2 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ install.success=Instalado con éxito.

java.add=Añadir Java
java.add.failed=Este Java no es válido o es incompatible con la plataforma actual.
java.add.failed.some=Parte del Java encontrado no es válido o es incompatible con la plataforma actual.
java.add.not_found=Java no se encuentra en el directorio especificado, o el directorio Java es demasiado profundo.
java.disable=Deshabilitar este Java
java.disable.confirm=¿Está seguro de que desea desactivar este Java?
java.disabled.management=Java desactivado
Expand Down
2 changes: 2 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ install.success=正常にインストールされました

java.add=Javaの追加
java.add.failed=このJavaは無効であるか、現在のプラットフォームと互換性がない。
java.add.failed.some=見つかったJavaのいくつかは無効であるか、現在のプラットフォームと互換性がありません。
java.add.not_found=指定されたディレクトリにJavaが見つからないか、Javaディレクトリが深すぎます。
java.disable=無効化
java.disable.confirm=本当にこのJavaを無効にしますか?
java.disabled.management=無効なJava
Expand Down
2 changes: 2 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_ru.properties
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ install.success=Успешно установлено.

java.add=Добавить Java
java.add.failed=Этот Java недопустим или несовместим с текущей платформой.
java.add.failed.some=Некоторые из найденных Java недопустимы или несовместимы с текущей платформой.
java.add.not_found=Java не найдена в указанном каталоге, или каталог Java находится слишком глубоко.
java.disable=Отключить Java
java.disable.confirm=Вы уверены, что хотите отключить эту Java?
java.disabled.management=Отключенная Java
Expand Down
2 changes: 2 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ install.success=安裝成功

java.add=添加 Java
java.add.failed=Java 無效或與目前平臺不相容
java.add.failed.some=找到的某些 Java 無效或與目前平臺不相容
java.add.not_found=在指定目錄中找不到 Java,或 Java 目錄太深。
java.disable=禁用此 Java
java.disable.confirm=你確定要禁用此 Java 嗎?
java.disabled.management=管理已禁用的 Java
Expand Down
2 changes: 2 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,8 @@ install.success=安装成功

java.add=添加 Java
java.add.failed=Java 无效或与当前平台不兼容。
java.add.failed.some=找到的部分 Java 无效或与当前平台不兼容。
java.add.not_found=在指定目录中找不到 Java,或 Java 目录太深。
java.disable=禁用此 Java
java.disable.confirm=你确定要禁用此 Java 吗?
java.disabled.management=管理已禁用的 Java
Expand Down