Skip to content

Commit

Permalink
Change action of "Add Java" to search Java in the directory, optimize…
Browse files Browse the repository at this point in the history
…d code
  • Loading branch information
ri-fumo committed Dec 13, 2024
1 parent 69b960e commit bbcf928
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 12 deletions.
72 changes: 72 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,77 @@ 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 = 2;

Queue<File> fileQueue = new ArrayDeque<>(64);
ArrayList<JavaRuntime> binaryList = new ArrayList<>();
final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable();
File[] subDirs = directory.listFiles(File::isDirectory);
if(subDirs == null) return binaryList;
fileQueue.addAll(Arrays.asList(subDirs));
fileQueue.add(directory);
int depth = 0;
while (depth < maxDepth) {
if(isCancelled())
return Collections.emptyList();
if(fileQueue.isEmpty()) break;
final File dir = fileQueue.poll();
if (dir == directory) {
depth++;
if (!fileQueue.isEmpty() && depth < maxDepth - 1)
fileQueue.add(directory);
continue;
}
final File binary = new File(dir, relative);
if (binary.exists()) {
binaryList.add(JavaManager.getJava(binary.toPath()));
continue;
}
subDirs = dir.listFiles(File::isDirectory);
if (subDirs != null)
fileQueue.addAll(Arrays.asList(subDirs));
}
return 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,34 @@ 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;

final File file = new File(directory, 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).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 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

0 comments on commit bbcf928

Please sign in to comment.