feat: check style & format
This commit is contained in:
@@ -17,19 +17,19 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.auth.authlibinjector;
|
||||
|
||||
import static org.jackhuang.hmcl.util.io.NetworkUtils.decodeURL;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.TransferMode;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.jackhuang.hmcl.util.io.NetworkUtils.decodeURL;
|
||||
|
||||
/**
|
||||
* @author yushijinhun
|
||||
* @see https://github.com/yushijinhun/authlib-injector/wiki/%E5%90%AF%E5%8A%A8%E5%99%A8%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83#dnd-%E6%96%B9%E5%BC%8F%E6%B7%BB%E5%8A%A0-yggdrasil-%E6%9C%8D%E5%8A%A1%E7%AB%AF
|
||||
* @see <a href="https://github.com/yushijinhun/authlib-injector/wiki/%E5%90%AF%E5%8A%A8%E5%99%A8%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83#dnd-%E6%96%B9%E5%BC%8F%E6%B7%BB%E5%8A%A0-yggdrasil-%E6%9C%8D%E5%8A%A1%E7%AB%AF">Launcher Technical Specification for Authlib-Injector</a>
|
||||
*/
|
||||
public final class AuthlibInjectorDnD {
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OfflineAccountFactory extends AccountFactory<OfflineAccount> {
|
||||
public final class OfflineAccountFactory extends AccountFactory<OfflineAccount> {
|
||||
public static final OfflineAccountFactory INSTANCE = new OfflineAccountFactory();
|
||||
|
||||
private OfflineAccountFactory() {
|
||||
|
||||
@@ -17,20 +17,13 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.auth.yggdrasil;
|
||||
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import com.google.gson.*;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
public class PropertyMapSerializer implements JsonSerializer<Map<String, String>>, JsonDeserializer<Map<String, String>> {
|
||||
|
||||
@@ -57,4 +50,4 @@ public class PropertyMapSerializer implements JsonSerializer<Map<String, String>
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -38,7 +38,7 @@ public abstract class GameBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* The new game version name, for .minecraft/<version name>.
|
||||
* The new game version name, for .minecraft/<version name>.
|
||||
*
|
||||
* @param name the name of new game version.
|
||||
*/
|
||||
|
||||
@@ -130,7 +130,7 @@ public class ForgeNewInstallTask extends Task<Version> {
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
Path temp = Files.createTempDirectory("forge_installer");
|
||||
Path temp = Files.createTempDirectory("forge_installer");
|
||||
int finished = 0;
|
||||
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
|
||||
List<ForgeNewInstallProfile.Processor> processors = profile.getProcessors();
|
||||
|
||||
@@ -105,7 +105,6 @@ public final class GameAssetIndexDownloadTask extends Task<Void> {
|
||||
dependencies.add(task);
|
||||
}
|
||||
|
||||
|
||||
public static class GameAssetIndexMalformedException extends IOException {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,8 @@ package org.jackhuang.hmcl.download.game;
|
||||
|
||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.CacheRepository;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
@@ -33,11 +29,9 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Remove class digital verification file in game jar
|
||||
|
||||
@@ -17,6 +17,8 @@ import java.util.logging.Level;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
|
||||
public final class JavaRepository {
|
||||
private JavaRepository() {
|
||||
}
|
||||
|
||||
public static Task<?> downloadJava(GameJavaVersion javaVersion, DownloadProvider downloadProvider) {
|
||||
return new JavaDownloadTask(javaVersion, getJavaStoragePath(), downloadProvider)
|
||||
|
||||
@@ -199,10 +199,10 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
* Install OptiFine library from existing local file.
|
||||
*
|
||||
* @param dependencyManager game repository
|
||||
* @param version version.json
|
||||
* @param installer the OptiFine installer
|
||||
* @param version version.json
|
||||
* @param installer the OptiFine installer
|
||||
* @return the task to install library
|
||||
* @throws IOException if unable to read compressed content of installer file, or installer file is corrupted, or the installer is not the one we want.
|
||||
* @throws IOException if unable to read compressed content of installer file, or installer file is corrupted, or the installer is not the one we want.
|
||||
* @throws VersionMismatchException if required game version of installer does not match the actual one.
|
||||
*/
|
||||
public static Task<Version> install(DefaultDependencyManager dependencyManager, Version version, Path installer) throws IOException, VersionMismatchException {
|
||||
@@ -227,7 +227,7 @@ public final class OptiFineInstallTask extends Task<Version> {
|
||||
throw new VersionMismatchException(mcVersion, gameVersion.get());
|
||||
|
||||
return new OptiFineInstallTask(dependencyManager, version,
|
||||
new OptiFineRemoteVersion(mcVersion, ofEdition + "_" + ofRelease, Collections.singletonList(""), false), installer);
|
||||
new OptiFineRemoteVersion(mcVersion, ofEdition + "_" + ofRelease, Collections.singletonList(""), false), installer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
||||
|
||||
/**
|
||||
* This event gets fired when a JavaProcess exited abnormally and the exit code is not zero.
|
||||
* <br></br>
|
||||
*
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.event.EventBus#EVENT_BUS}
|
||||
*
|
||||
* @author huangyuhui
|
||||
@@ -34,7 +34,7 @@ public final class ProcessExitedAbnormallyEvent extends Event {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param source {@link org.jackhuang.hmcl.launch.ExitWaiter}
|
||||
* @param source {@link org.jackhuang.hmcl.launch.ExitWaiter}
|
||||
* @param process The process that exited abnormally.
|
||||
*/
|
||||
public ProcessExitedAbnormallyEvent(Object source, ManagedProcess process) {
|
||||
|
||||
@@ -29,7 +29,7 @@ public final class RefreshedVersionsEvent extends Event {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param source {@link org.jackhuang.hmcl.game.GameRepository]
|
||||
* @param source {@link org.jackhuang.hmcl.game.GameRepository}
|
||||
*/
|
||||
public RefreshedVersionsEvent(Object source) {
|
||||
super(source);
|
||||
|
||||
@@ -35,4 +35,4 @@ public enum GameDirectoryType {
|
||||
* user customized directory.
|
||||
*/
|
||||
CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public interface GameRepository extends VersionProvider {
|
||||
/**
|
||||
* Gets the root folder of specific version.
|
||||
* The root folders the versions must be unique.
|
||||
* For example, .minecraft/versions/<version name>/.
|
||||
* For example, .minecraft/versions/<version name>/.
|
||||
*/
|
||||
File getVersionRoot(String id);
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class GameVersion {
|
||||
private GameVersion() {
|
||||
}
|
||||
|
||||
private static Optional<String> getVersionFromJson(Path versionJson) {
|
||||
try {
|
||||
Map<?, ?> version = JsonUtils.fromNonNullJson(FileUtils.readText(versionJson), Map.class);
|
||||
|
||||
@@ -68,7 +68,7 @@ public final class FabricModMetadata {
|
||||
FabricModMetadata metadata = JsonUtils.fromNonNullJson(FileUtils.readText(mcmod), FabricModMetadata.class);
|
||||
String authors = metadata.authors == null ? "" : metadata.authors.stream().map(author -> author.name).collect(Collectors.joining(", "));
|
||||
return new ModInfo(modManager, modFile, metadata.name, new ModInfo.Description(metadata.description),
|
||||
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "");
|
||||
authors, metadata.version, "", metadata.contact != null ? metadata.contact.getOrDefault("homepage", "") : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ public final class ModInfo implements Comparable<ModInfo> {
|
||||
|
||||
try {
|
||||
if (get())
|
||||
ModInfo.this.file = modManager.enableMod(path);
|
||||
ModInfo.this.file = modManager.enableMod(path);
|
||||
else
|
||||
ModInfo.this.file = modManager.disableMod(path);
|
||||
ModInfo.this.file = modManager.disableMod(path);
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.SEVERE, "Unable to invert state of mod file " + path, e);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public final class ModpackConfiguration<T> implements Validation {
|
||||
private final List<FileInformation> overrides;
|
||||
|
||||
public ModpackConfiguration() {
|
||||
this(null, null, "", null, Collections.emptyList());
|
||||
this(null, null, "", null, Collections.emptyList());
|
||||
}
|
||||
|
||||
public ModpackConfiguration(T manifest, String type, String name, String version, List<FileInformation> overrides) {
|
||||
@@ -110,6 +110,7 @@ public final class ModpackConfiguration<T> implements Validation {
|
||||
|
||||
/**
|
||||
* The relative path to Minecraft run directory
|
||||
*
|
||||
* @return the relative path to Minecraft run directory.
|
||||
*/
|
||||
public String getPath() {
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jackhuang.hmcl.util.Immutable;
|
||||
/**
|
||||
* CurseMetaMod is JSON structure for
|
||||
* https://cursemeta.dries007.net/<projectID>/<fileID>.json
|
||||
* https://addons-ecs.forgesvc.net/api/v2/addon/<projectID>/file/<fileID>
|
||||
* https://addons-ecs.forgesvc.net/api/v2/addon/<projectID>/file/<fileID>
|
||||
*/
|
||||
@Immutable
|
||||
public final class CurseMetaMod {
|
||||
|
||||
@@ -79,8 +79,6 @@ public final class MultiMCManifest {
|
||||
@SerializedName("suggests")
|
||||
private final String suggests;
|
||||
|
||||
|
||||
|
||||
public MultiMCManifestCachedRequires(String equalsVersion, String uid, String suggests) {
|
||||
this.equalsVersion = equalsVersion;
|
||||
this.uid = uid;
|
||||
|
||||
@@ -56,7 +56,7 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
|
||||
private final DefaultGameRepository repository;
|
||||
private final List<Task<?>> dependencies = new LinkedList<>();
|
||||
private final List<Task<?>> dependents = new LinkedList<>();
|
||||
|
||||
|
||||
public MultiMCModpackInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, MultiMCInstanceConfiguration manifest, String name) {
|
||||
this.zipFile = zipFile;
|
||||
this.modpack = modpack;
|
||||
@@ -96,7 +96,7 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
|
||||
repository.removeVersionFromDisk(name);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Task<?>> getDependencies() {
|
||||
return dependencies;
|
||||
@@ -138,7 +138,7 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
|
||||
public List<Task<?>> getDependents() {
|
||||
return dependents;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
Version version = repository.readVersionJson(name);
|
||||
@@ -169,11 +169,11 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
|
||||
|
||||
Path libraries = root.resolve("libraries");
|
||||
if (Files.exists(libraries))
|
||||
FileUtils.copyDirectory(libraries, repository.getVersionRoot(name).toPath().resolve("libraries"));
|
||||
FileUtils.copyDirectory(libraries, repository.getVersionRoot(name).toPath().resolve("libraries"));
|
||||
|
||||
Path jarmods = root.resolve("jarmods");
|
||||
if (Files.exists(jarmods))
|
||||
FileUtils.copyDirectory(jarmods, repository.getVersionRoot(name).toPath().resolve("jarmods"));
|
||||
FileUtils.copyDirectory(jarmods, repository.getVersionRoot(name).toPath().resolve("jarmods"));
|
||||
}
|
||||
|
||||
dependencies.add(repository.saveAsync(version));
|
||||
|
||||
@@ -280,7 +280,6 @@ public abstract class Task<T> {
|
||||
*/
|
||||
public void postExecute() throws Exception {}
|
||||
|
||||
|
||||
/**
|
||||
* The collection of sub-tasks that should execute **before** this task running.
|
||||
*/
|
||||
|
||||
@@ -54,6 +54,7 @@ public enum Log4jLevel {
|
||||
public boolean lessOrEqual(Log4jLevel level) {
|
||||
return this.level <= level.level;
|
||||
}
|
||||
|
||||
public static final Pattern MINECRAFT_LOGGER = Pattern.compile("\\[(?<timestamp>[0-9:]+)] \\[[^/]+/(?<level>[^]]+)]");
|
||||
public static final Pattern MINECRAFT_LOGGER_CATEGORY = Pattern.compile("\\[(?<timestamp>[0-9:]+)] \\[[^/]+/(?<level>[^]]+)] \\[(?<category>[^]]+)]");
|
||||
public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.logging.*;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Logging {
|
||||
private Logging() {
|
||||
}
|
||||
|
||||
public static final Logger LOG = Logger.getLogger("HMCL");
|
||||
private static ByteArrayOutputStream storedLogs = new ByteArrayOutputStream();
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Pair<K, V> implements Map.Entry<K, V> {
|
||||
public final class Pair<K, V> implements Map.Entry<K, V> {
|
||||
|
||||
public static <K, V> Pair<K, V> pair(K key, V value) {
|
||||
return new Pair<>(key, value);
|
||||
|
||||
@@ -27,13 +27,16 @@ import java.util.function.Predicate;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class ReflectionHelper {
|
||||
private ReflectionHelper() {
|
||||
}
|
||||
|
||||
private static Method accessible0;
|
||||
|
||||
static {
|
||||
try {
|
||||
accessible0 = AccessibleObject.class.getDeclaredMethod("setAccessible0", boolean.class);
|
||||
accessible0.setAccessible(true);
|
||||
} catch (Throwable ex) {
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +46,7 @@ public final class ReflectionHelper {
|
||||
|
||||
/**
|
||||
* Get caller, this method is caller sensitive.
|
||||
*
|
||||
* @param packageFilter returns false if we consider the given package is internal calls, not the caller
|
||||
* @return the caller, method name, source file, line number
|
||||
*/
|
||||
|
||||
@@ -26,4 +26,4 @@ public interface ExceptionalBiFunction<T, U, R, E extends Exception> {
|
||||
requireNonNull(after);
|
||||
return (t, u) -> after.apply(apply(t, u));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ public class JsonTypeAdapterFactory implements TypeAdapterFactory {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private <T> TypeAdapter<T> createForJsonSubtype(Gson gson, TypeToken<T> type) {
|
||||
Class<? super T> rawType = type.getRawType();
|
||||
if (rawType.getSuperclass() == null) return null;
|
||||
|
||||
@@ -29,7 +29,7 @@ public interface Validation {
|
||||
/**
|
||||
* 1. Check some non-null fields and;
|
||||
* 2. Check strings and;
|
||||
* 3. Check generic type of lists <T> and maps <K, V> are correct.
|
||||
* 3. Check generic type of lists <T> and maps <K, V> are correct.
|
||||
*
|
||||
* Will be called immediately after initialization.
|
||||
* Throw an exception when values are malformed.
|
||||
|
||||
@@ -21,9 +21,9 @@ import java.io.IOException;
|
||||
|
||||
public class ChecksumMismatchException extends IOException {
|
||||
|
||||
private String algorithm;
|
||||
private String expectedChecksum;
|
||||
private String actualChecksum;
|
||||
private final String algorithm;
|
||||
private final String expectedChecksum;
|
||||
private final String actualChecksum;
|
||||
|
||||
public ChecksumMismatchException(String algorithm, String expectedChecksum, String actualChecksum) {
|
||||
super("Incorrect checksum (" + algorithm + "), expected: " + expectedChecksum + ", actual: " + actualChecksum);
|
||||
|
||||
@@ -124,10 +124,11 @@ public final class FileUtils {
|
||||
|
||||
/**
|
||||
* Write plain text to file. Characters are encoded into bytes using UTF-8.
|
||||
*
|
||||
* <p>
|
||||
* We don't care about platform difference of line separator. Because readText accept all possibilities of line separator.
|
||||
* It will create the file if it does not exist, or truncate the existing file to empty for rewriting.
|
||||
* All characters in text will be written into the file in binary format. Existing data will be erased.
|
||||
*
|
||||
* @param file the path to the file
|
||||
* @param text the text being written to file
|
||||
* @throws IOException if an I/O error occurs
|
||||
@@ -138,12 +139,13 @@ public final class FileUtils {
|
||||
|
||||
/**
|
||||
* Write plain text to file.
|
||||
*
|
||||
* <p>
|
||||
* We don't care about platform difference of line separator. Because readText accept all possibilities of line separator.
|
||||
* It will create the file if it does not exist, or truncate the existing file to empty for rewriting.
|
||||
* All characters in text will be written into the file in binary format. Existing data will be erased.
|
||||
* @param file the path to the file
|
||||
* @param text the text being written to file
|
||||
*
|
||||
* @param file the path to the file
|
||||
* @param text the text being written to file
|
||||
* @param charset the charset to use for encoding
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@@ -155,7 +157,8 @@ public final class FileUtils {
|
||||
* Write byte array to file.
|
||||
* It will create the file if it does not exist, or truncate the existing file to empty for rewriting.
|
||||
* All bytes in byte array will be written into the file in binary format. Existing data will be erased.
|
||||
* @param file the path to the file
|
||||
*
|
||||
* @param file the path to the file
|
||||
* @param array the data being written to file
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@@ -192,7 +195,7 @@ public final class FileUtils {
|
||||
* Copy directory.
|
||||
* Paths of all files relative to source directory will be the same as the ones relative to destination directory.
|
||||
*
|
||||
* @param src the source directory.
|
||||
* @param src the source directory.
|
||||
* @param dest the destination directory, which will be created if not existing.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
@@ -201,7 +204,7 @@ public final class FileUtils {
|
||||
}
|
||||
|
||||
public static void copyDirectory(Path src, Path dest, Predicate<String> filePredicate) throws IOException {
|
||||
Files.walkFileTree(src, new SimpleFileVisitor<Path>(){
|
||||
Files.walkFileTree(src, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
if (!filePredicate.test(src.relativize(file).toString())) {
|
||||
@@ -228,7 +231,7 @@ public final class FileUtils {
|
||||
|
||||
/**
|
||||
* Move file to trash.
|
||||
*
|
||||
* <p>
|
||||
* This method is only implemented in Java 9. Please check we are using Java 9 by invoking isMovingToTrashSupported.
|
||||
* Example:
|
||||
* <pre>{@code
|
||||
@@ -236,9 +239,10 @@ public final class FileUtils {
|
||||
* FileUtils.moveToTrash(file);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param file the file being moved to trash.
|
||||
* @see FileUtils#isMovingToTrashSupported()
|
||||
* @return false if moveToTrash does not exist, or platform does not support Desktop.Action.MOVE_TO_TRASH
|
||||
* @see FileUtils#isMovingToTrashSupported()
|
||||
*/
|
||||
public static boolean moveToTrash(File file) {
|
||||
try {
|
||||
@@ -253,6 +257,7 @@ public final class FileUtils {
|
||||
|
||||
/**
|
||||
* Check if {@code java.awt.Desktop.moveToTrash} exists.
|
||||
*
|
||||
* @return true if the method exists.
|
||||
*/
|
||||
public static boolean isMovingToTrashSupported() {
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public final class JarUtils {
|
||||
private JarUtils() {
|
||||
}
|
||||
|
||||
public static Optional<Path> thisJar() {
|
||||
CodeSource codeSource = JarUtils.class.getProtectionDomain().getCodeSource();
|
||||
|
||||
@@ -86,6 +86,7 @@ public final class NetworkUtils {
|
||||
break;
|
||||
case '?':
|
||||
left = false;
|
||||
// fallthrough
|
||||
default:
|
||||
if (ch >= 0x80)
|
||||
sb.append(encodeURL(Character.toString(ch)));
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.io;
|
||||
|
||||
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalPredicate;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
@@ -17,20 +17,19 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.javafx;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jackhuang.hmcl.util.Lang.handleUncaughtException;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.ObjectBinding;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.ObjectBinding;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jackhuang.hmcl.util.Lang.handleUncaughtException;
|
||||
|
||||
/**
|
||||
* @author yushijinhun
|
||||
|
||||
@@ -17,72 +17,72 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.javafx;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.ObjectBinding;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author yushijinhun
|
||||
*/
|
||||
public class MappedProperty<T, U> extends SimpleObjectProperty<U> {
|
||||
|
||||
private final Property<T> predecessor;
|
||||
private final Function<U, T> reservedMapper;
|
||||
private final Property<T> predecessor;
|
||||
private final Function<U, T> reservedMapper;
|
||||
|
||||
private final ObjectBinding<U> binding;
|
||||
private final ObjectBinding<U> binding;
|
||||
|
||||
public MappedProperty(Property<T> predecessor, Function<T, U> mapper, Function<U, T> reservedMapper) {
|
||||
this(null, "", predecessor, mapper, reservedMapper);
|
||||
}
|
||||
public MappedProperty(Property<T> predecessor, Function<T, U> mapper, Function<U, T> reservedMapper) {
|
||||
this(null, "", predecessor, mapper, reservedMapper);
|
||||
}
|
||||
|
||||
public MappedProperty(Object bean, String name, Property<T> predecessor, Function<T, U> mapper, Function<U, T> reservedMapper) {
|
||||
super(bean, name);
|
||||
this.predecessor = predecessor;
|
||||
this.reservedMapper = reservedMapper;
|
||||
public MappedProperty(Object bean, String name, Property<T> predecessor, Function<T, U> mapper, Function<U, T> reservedMapper) {
|
||||
super(bean, name);
|
||||
this.predecessor = predecessor;
|
||||
this.reservedMapper = reservedMapper;
|
||||
|
||||
binding = new ObjectBinding<U>() {
|
||||
{
|
||||
bind(predecessor);
|
||||
}
|
||||
{
|
||||
bind(predecessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected U computeValue() {
|
||||
return mapper.apply(predecessor.getValue());
|
||||
}
|
||||
@Override
|
||||
protected U computeValue() {
|
||||
return mapper.apply(predecessor.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInvalidating() {
|
||||
MappedProperty.this.fireValueChangedEvent();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
protected void onInvalidating() {
|
||||
MappedProperty.this.fireValueChangedEvent();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public U get() {
|
||||
return binding.get();
|
||||
}
|
||||
@Override
|
||||
public U get() {
|
||||
return binding.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(U value) {
|
||||
predecessor.setValue(reservedMapper.apply(value));
|
||||
}
|
||||
@Override
|
||||
public void set(U value) {
|
||||
predecessor.setValue(reservedMapper.apply(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(ObservableValue<? extends U> observable) {
|
||||
predecessor.bind(Bindings.createObjectBinding(() -> reservedMapper.apply(observable.getValue()), observable));
|
||||
}
|
||||
@Override
|
||||
public void bind(ObservableValue<? extends U> observable) {
|
||||
predecessor.bind(Bindings.createObjectBinding(() -> reservedMapper.apply(observable.getValue()), observable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbind() {
|
||||
predecessor.unbind();
|
||||
}
|
||||
@Override
|
||||
public void unbind() {
|
||||
predecessor.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBound() {
|
||||
return predecessor.isBound();
|
||||
}
|
||||
@Override
|
||||
public boolean isBound() {
|
||||
return predecessor.isBound();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,5 +351,5 @@ public class VersionNumber implements Comparable<VersionNumber> {
|
||||
return canonical.hashCode();
|
||||
}
|
||||
|
||||
public static Comparator<String> VERSION_COMPARATOR = Comparator.comparing(VersionNumber::asVersion);
|
||||
public static final Comparator<String> VERSION_COMPARATOR = Comparator.comparing(VersionNumber::asVersion);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user