Merge pull request #454 from yushijinhun/javafx

重构
This commit is contained in:
huanghongxun 2018-09-16 13:46:31 +08:00 committed by GitHub
commit 9752dea0e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 158 additions and 133 deletions

View File

@ -32,7 +32,6 @@ import org.jackhuang.hmcl.mod.CurseCompletionTask;
import org.jackhuang.hmcl.mod.ModpackConfiguration;
import org.jackhuang.hmcl.setting.LauncherVisibility;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.Settings;
import org.jackhuang.hmcl.setting.VersionSetting;
import org.jackhuang.hmcl.task.*;
import org.jackhuang.hmcl.ui.Controllers;
@ -50,6 +49,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Pair.pair;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@ -443,7 +443,7 @@ public final class LauncherHelper {
System.out.print(log);
logs.add(pair(log, level));
if (logs.size() > Settings.instance().getLogLines())
if (logs.size() > config().getLogLines())
logs.removeFirst();
if (setting.isShowLogs()) {

View File

@ -59,7 +59,7 @@ public final class Accounts {
public static final OfflineAccountFactory FACTORY_OFFLINE = OfflineAccountFactory.INSTANCE;
public static final YggdrasilAccountFactory FACTORY_YGGDRASIL = new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE);
public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory(
new AuthlibInjectorDownloader(Launcher.HMCL_DIRECTORY.toPath(), () -> Settings.instance().getDownloadProvider())::getArtifactInfo,
new AuthlibInjectorDownloader(Launcher.HMCL_DIRECTORY.toPath(), DownloadProviders::getDownloadProvider)::getArtifactInfo,
Accounts::getOrCreateAuthlibInjectorServer);
private static final String TYPE_OFFLINE = "offline";

View File

@ -115,8 +115,8 @@ public final class Config implements Cloneable, Observable {
@SerializedName("localization")
private ObjectProperty<SupportedLocale> localization = new SimpleObjectProperty<>(Locales.DEFAULT);
@SerializedName("downloadtype")
private IntegerProperty downloadType = new SimpleIntegerProperty(1);
@SerializedName("downloadType")
private StringProperty downloadType = new SimpleStringProperty("bmclapi");
@SerializedName("configurations")
private ObservableMap<String, Profile> configurations = FXCollections.observableMap(new TreeMap<>());
@ -359,15 +359,15 @@ public final class Config implements Cloneable, Observable {
return localization;
}
public int getDownloadType() {
public String getDownloadType() {
return downloadType.get();
}
public void setDownloadType(int downloadType) {
public void setDownloadType(String downloadType) {
this.downloadType.set(downloadType);
}
public IntegerProperty downloadTypeProperty() {
public StringProperty downloadTypeProperty() {
return downloadType;
}

View File

@ -86,5 +86,17 @@ final class ConfigUpgrader {
deserialized.setHasProxy(StringUtils.isNotBlank(deserialized.getProxyHost()));
if (!rawJson.containsKey("hasProxyAuth"))
deserialized.setHasProxyAuth(StringUtils.isNotBlank(deserialized.getProxyUser()));
if (!rawJson.containsKey("downloadType")) {
tryCast(rawJson.get("downloadtype"), Number.class)
.map(Number::intValue)
.ifPresent(id -> {
if (id == 0) {
deserialized.setDownloadType("mojang");
} else if (id == 1) {
deserialized.setDownloadType("bmclapi");
}
});
}
}
}

View File

@ -17,20 +17,44 @@
*/
package org.jackhuang.hmcl.setting;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Pair.pair;
import java.util.Map;
import java.util.Optional;
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
import org.jackhuang.hmcl.download.CurseCDNDownloadProvider;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.MojangDownloadProvider;
import org.jackhuang.hmcl.util.Lang;
import java.util.List;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.value.ObservableObjectValue;
public final class DownloadProviders {
private DownloadProviders() {}
public static final List<DownloadProvider> DOWNLOAD_PROVIDERS = Lang.immutableListOf(new MojangDownloadProvider(), BMCLAPIDownloadProvider.INSTANCE, CurseCDNDownloadProvider.INSTANCE);
public static final Map<String, DownloadProvider> providersById = mapOf(
pair("mojang", new MojangDownloadProvider()),
pair("bmclapi", new BMCLAPIDownloadProvider()));
public static DownloadProvider getDownloadProvider(int index) {
return Lang.get(DOWNLOAD_PROVIDERS, index).orElse(DOWNLOAD_PROVIDERS.get(0));
public static final String DEFAULT_PROVIDER_ID = "bmclapi";
private static ObjectBinding<DownloadProvider> downloadProviderProperty;
static void init() {
downloadProviderProperty = Bindings.createObjectBinding(
() -> Optional.ofNullable(providersById.get(config().getDownloadType()))
.orElse(providersById.get(DEFAULT_PROVIDER_ID)),
config().downloadTypeProperty());
}
public static DownloadProvider getDownloadProvider() {
return downloadProviderProperty.get();
}
public static ObservableObjectValue<DownloadProvider> downloadProviderProperty() {
return downloadProviderProperty;
}
}

View File

@ -29,7 +29,7 @@ import org.jackhuang.hmcl.game.HMCLCacheRepository;
import org.jackhuang.hmcl.game.HMCLGameRepository;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.mod.ModManager;
import org.jackhuang.hmcl.ui.WeakListenerHelper;
import org.jackhuang.hmcl.ui.WeakListenerHolder;
import org.jackhuang.hmcl.util.*;
import java.io.File;
@ -43,7 +43,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.onInvalidating;
* @author huangyuhui
*/
public final class Profile implements Observable {
private final WeakListenerHelper helper = new WeakListenerHelper();
private final WeakListenerHolder listenerHolder = new WeakListenerHolder();
private final HMCLGameRepository repository;
private final ModManager modManager;
@ -136,7 +136,7 @@ public final class Profile implements Observable {
gameDir.addListener((a, b, newValue) -> repository.changeDirectory(newValue));
this.selectedVersion.addListener(o -> checkSelectedVersion());
helper.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> checkSelectedVersion()));
listenerHolder.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> checkSelectedVersion()));
addPropertyChangedListener(onInvalidating(this::invalidate));
}
@ -162,7 +162,7 @@ public final class Profile implements Observable {
}
public DefaultDependencyManager getDependency() {
return new DefaultDependencyManager(repository, Settings.instance().getDownloadProvider(), HMCLCacheRepository.REPOSITORY);
return new DefaultDependencyManager(repository, DownloadProviders.getDownloadProvider(), HMCLCacheRepository.REPOSITORY);
}
public VersionSetting getVersionSetting(String id) {

View File

@ -35,20 +35,7 @@ public final class ProxyManager {
private ProxyManager() {
}
private static ObjectBinding<Proxy> proxyProperty = Bindings.createObjectBinding(
() -> {
String host = config().getProxyHost();
Integer port = Lang.toIntOrNull(config().getProxyPort());
if (!config().hasProxy() || StringUtils.isBlank(host) || port == null || config().getProxyType() == Proxy.Type.DIRECT) {
return Proxy.NO_PROXY;
} else {
return new Proxy(config().getProxyType(), new InetSocketAddress(host, port));
}
},
config().proxyTypeProperty(),
config().proxyHostProperty(),
config().proxyPortProperty(),
config().hasProxyProperty());
private static ObjectBinding<Proxy> proxyProperty;
public static Proxy getProxy() {
return proxyProperty.get();
@ -59,12 +46,25 @@ public final class ProxyManager {
}
static void init() {
proxyProperty.addListener(observable -> updateSystemProxy());
proxyProperty = Bindings.createObjectBinding(
() -> {
String host = config().getProxyHost();
Integer port = Lang.toIntOrNull(config().getProxyPort());
if (!config().hasProxy() || StringUtils.isBlank(host) || port == null || config().getProxyType() == Proxy.Type.DIRECT) {
return Proxy.NO_PROXY;
} else {
return new Proxy(config().getProxyType(), new InetSocketAddress(host, port));
}
},
config().proxyTypeProperty(),
config().proxyHostProperty(),
config().proxyPortProperty(),
config().hasProxyProperty());
proxyProperty.addListener(any -> updateSystemProxy());
updateSystemProxy();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
if (config().hasProxyAuth()) {

View File

@ -19,7 +19,6 @@ package org.jackhuang.hmcl.setting;
import javafx.scene.text.Font;
import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.game.HMCLCacheRepository;
import org.jackhuang.hmcl.util.CacheRepository;
@ -44,6 +43,7 @@ public class Settings {
}
private Settings() {
DownloadProviders.init();
ProxyManager.init();
Accounts.init();
Profiles.init();
@ -61,14 +61,6 @@ public class Settings {
config().setFontSize(font.getSize());
}
public int getLogLines() {
return Math.max(config().getLogLines(), 100);
}
public void setLogLines(int logLines) {
config().setLogLines(logLines);
}
public static String getDefaultCommonDirectory() {
return Launcher.MINECRAFT_DIRECTORY.getAbsolutePath();
}
@ -83,19 +75,4 @@ public class Settings {
return null;
}
}
/****************************************
* DOWNLOAD PROVIDERS *
****************************************/
public DownloadProvider getDownloadProvider() {
return DownloadProviders.getDownloadProvider(config().getDownloadType());
}
public void setDownloadProvider(DownloadProvider downloadProvider) {
int index = DownloadProviders.DOWNLOAD_PROVIDERS.indexOf(downloadProvider);
if (index == -1)
throw new IllegalArgumentException("Unknown download provider: " + downloadProvider);
config().setDownloadType(index);
}
}

View File

@ -328,8 +328,10 @@ public final class FXUtils {
* @param comboBox the combo box being bound with {@code property}.
* @param property the property being bound with {@code combo box}.
* @see #unbindEnum(JFXComboBox)
* @deprecated Use {@link SelectionModelSelectedItemProperty#selectedItemPropertyFor(ComboBox)}
*/
@SuppressWarnings("unchecked")
@Deprecated
public static void bindEnum(JFXComboBox<?> comboBox, Property<? extends Enum> property) {
unbindEnum(comboBox);
ChangeListener<Number> listener = (a, b, newValue) ->
@ -346,6 +348,7 @@ public final class FXUtils {
* @see #bindEnum(JFXComboBox, Property)
*/
@SuppressWarnings("unchecked")
@Deprecated
public static void unbindEnum(JFXComboBox<?> comboBox) {
ChangeListener listener = tryCast(comboBox.getProperties().get("FXUtils.bindEnum.listener"), ChangeListener.class).orElse(null);
if (listener == null) return;

View File

@ -181,7 +181,7 @@ public final class LogWindow extends Stage {
if (newValue == Worker.State.SUCCEEDED) {
document = engine.getDocument();
body = document.getElementsByTagName("body").item(0);
engine.executeScript("limitedLogs=" + Settings.instance().getLogLines());
engine.executeScript("limitedLogs=" + config().getLogLines());
latch.countDown();
onDone.fireEvent(new Event(LogWindow.this));
}
@ -189,14 +189,14 @@ public final class LogWindow extends Stage {
boolean flag = false;
for (String i : cboLines.getItems())
if (Integer.toString(Settings.instance().getLogLines()).equals(i)) {
if (Integer.toString(config().getLogLines()).equals(i)) {
cboLines.getSelectionModel().select(i);
flag = true;
}
cboLines.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
Settings.instance().setLogLines(newValue == null ? 100 : Integer.parseInt(newValue));
engine.executeScript("limitedLogs=" + Settings.instance().getLogLines());
config().setLogLines(newValue == null ? 100 : Integer.parseInt(newValue));
engine.executeScript("limitedLogs=" + config().getLogLines());
});
if (!flag)

View File

@ -25,9 +25,6 @@ import javafx.beans.WeakInvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.When;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleGroup;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
@ -48,6 +45,7 @@ import java.util.Objects;
import java.util.Optional;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.SelectionModelSelectedItemProperty.selectedItemPropertyFor;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class SettingsPage extends SettingsView implements DecoratorPage {
@ -60,10 +58,12 @@ public final class SettingsPage extends SettingsView implements DecoratorPage {
public SettingsPage() {
FXUtils.smoothScrolling(scroll);
chkEnableGameList.selectedProperty().bindBidirectional(config().enableMainPageGameListProperty());
// ==== Download sources ====
cboDownloadSource.getItems().setAll(DownloadProviders.providersById.keySet());
selectedItemPropertyFor(cboDownloadSource).bindBidirectional(config().downloadTypeProperty());
// ====
cboDownloadSource.getSelectionModel().select(DownloadProviders.DOWNLOAD_PROVIDERS.indexOf(Settings.instance().getDownloadProvider()));
cboDownloadSource.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) -> Settings.instance().setDownloadProvider(DownloadProviders.getDownloadProvider(newValue.intValue())));
chkEnableGameList.selectedProperty().bindBidirectional(config().enableMainPageGameListProperty());
cboFont.initValue(Settings.instance().getFont());
cboFont.valueProperty().addListener((a, b, newValue) -> {
@ -84,13 +84,10 @@ public final class SettingsPage extends SettingsView implements DecoratorPage {
lblDisplay.setStyle("-fx-font: " + Settings.instance().getFont().getSize() + " \"" + Settings.instance().getFont().getFamily() + "\";");
ObservableList<Label> list = FXCollections.observableArrayList();
for (Locales.SupportedLocale locale : Locales.LOCALES)
list.add(new Label(locale.getName(config().getLocalization().getResourceBundle())));
cboLanguage.setItems(list);
cboLanguage.getSelectionModel().select(Locales.LOCALES.indexOf(config().getLocalization()));
cboLanguage.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) -> config().setLocalization(Locales.getLocale(newValue.intValue())));
// ==== Languages ====
cboLanguage.getItems().setAll(Locales.LOCALES);
selectedItemPropertyFor(cboLanguage).bindBidirectional(config().localizationProperty());
// ====
// ==== Proxy ====
txtProxyHost.textProperty().bindBidirectional(config().proxyHostProperty());

View File

@ -26,11 +26,16 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import org.jackhuang.hmcl.setting.EnumBackgroundImage;
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
import org.jackhuang.hmcl.setting.Theme;
import org.jackhuang.hmcl.ui.construct.*;
import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
public abstract class SettingsView extends StackPane {
protected final JFXTextField txtProxyHost;
@ -38,8 +43,8 @@ public abstract class SettingsView extends StackPane {
protected final JFXTextField txtProxyUsername;
protected final JFXPasswordField txtProxyPassword;
protected final JFXTextField txtFontSize;
protected final JFXComboBox<Label> cboLanguage;
protected final JFXComboBox<Label> cboDownloadSource;
protected final JFXComboBox<SupportedLocale> cboLanguage;
protected final JFXComboBox<String> cboDownloadSource;
protected final FontComboBox cboFont;
protected final MultiFileItem<EnumCommonDirectory> fileCommonLocation;
protected final Label lblDisplay;
@ -162,11 +167,7 @@ public abstract class SettingsView extends StackPane {
{
cboDownloadSource = new JFXComboBox<>();
FXUtils.setLimitWidth(cboDownloadSource, 400);
cboDownloadSource.getItems().setAll(
new Label(I18n.i18n("download.mojang")),
new Label(I18n.i18n("download.BMCL"))
);
cboDownloadSource.setConverter(stringConverter(key -> I18n.i18n("download.provider." + key)));
downloadSourcePane.setRight(cboDownloadSource);
}
settingsPane.getContent().add(downloadSourcePane);
@ -180,6 +181,7 @@ public abstract class SettingsView extends StackPane {
languagePane.setLeft(left);
cboLanguage = new JFXComboBox<>();
cboLanguage.setConverter(stringConverter(locale -> locale.getName(config().getLocalization().getResourceBundle())));
FXUtils.setLimitWidth(cboLanguage, 400);
languagePane.setRight(cboLanguage);

View File

@ -27,10 +27,10 @@ import javafx.collections.WeakListChangeListener;
import java.util.LinkedList;
import java.util.List;
public class WeakListenerHelper {
List<Object> refs = new LinkedList<>();
public class WeakListenerHolder {
private List<Object> refs = new LinkedList<>();
public WeakListenerHelper() {
public WeakListenerHolder() {
}
public WeakInvalidationListener weak(InvalidationListener listener) {

View File

@ -24,7 +24,7 @@ import org.jackhuang.hmcl.event.EventBus;
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.Profiles;
import org.jackhuang.hmcl.ui.WeakListenerHelper;
import org.jackhuang.hmcl.ui.WeakListenerHolder;
import org.jackhuang.hmcl.ui.construct.AdvancedListItem;
import java.io.File;
@ -32,16 +32,16 @@ import java.io.File;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class GameAdvancedListItem extends AdvancedListItem {
private final WeakListenerHelper helper = new WeakListenerHelper();
private final WeakListenerHolder listenerHolder = new WeakListenerHolder();
private Profile profile;
private InvalidationListener listener = o -> loadVersion();
public GameAdvancedListItem() {
Profiles.selectedProfileProperty().addListener(helper.weak((a, b, newValue) -> {
Profiles.selectedProfileProperty().addListener(listenerHolder.weak((a, b, newValue) -> {
JFXUtilities.runInFX(() -> loadProfile(newValue));
}));
helper.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> {
listenerHolder.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> {
JFXUtilities.runInFX(() -> {
if (profile != null && profile.getRepository() == event.getSource())
loadVersion();

View File

@ -31,7 +31,7 @@ import org.jackhuang.hmcl.game.HMCLGameRepository;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.Profiles;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.WeakListenerHelper;
import org.jackhuang.hmcl.ui.WeakListenerHolder;
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider;
import org.jackhuang.hmcl.util.VersionNumber;
@ -70,8 +70,8 @@ public class GameList extends Control implements DecoratorPage {
private void loadVersions(HMCLGameRepository repository) {
toggleGroup = new ToggleGroup();
WeakListenerHelper helper = new WeakListenerHelper();
toggleGroup.getProperties().put("ReferenceHolder", helper);
WeakListenerHolder listenerHolder = new WeakListenerHolder();
toggleGroup.getProperties().put("ReferenceHolder", listenerHolder);
List<GameListItem> children = repository.getVersions().parallelStream()
.filter(version -> !version.isHidden())
.sorted((a, b) -> VersionNumber.COMPARATOR.compare(VersionNumber.asVersion(a.getId()), VersionNumber.asVersion(b.getId())))
@ -83,7 +83,7 @@ public class GameList extends Control implements DecoratorPage {
items.setAll(children);
children.forEach(GameListItem::checkSelection);
profile.selectedVersionProperty().addListener(helper.weak((a, b, newValue) -> {
profile.selectedVersionProperty().addListener(listenerHolder.weak((a, b, newValue) -> {
Platform.runLater(() -> {
children.forEach(it -> it.selectedProperty().set(false));
children.stream()

View File

@ -84,11 +84,11 @@ crash.NoClassDefFound=Please check "HMCL" software is complete.
crash.user_fault=Your OS or Java environment may not be properly installed resulting in crashing of this software, please check your Java Environment or your computer!
download=Download
download.BMCL=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/)
download.failed=Failed to download
download.failed.empty=No candidates. Click here to return.
download.failed.refresh=Unable to load version list. Click here to retry.
download.mojang=Mojang
download.provider.bmclapi=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/)
download.provider.mojang=Mojang
extension.bat=Windows Bat file
extension.mod=Mod file

View File

@ -84,11 +84,11 @@ crash.NoClassDefFound=請確認 HMCL 本體是否完整,或更新您的 Java
crash.user_fault=您的系統或 Java 環境可能安裝不當導致本軟體崩潰,請檢查您的 Java 環境或您的電腦!可以嘗試重新安裝 Java。
download=下載
download.BMCL=BMCLAPIbangbang93https://bmclapi2.bangbang93.com/
download.failed=下載失敗
download.failed.empty=沒有可供安裝的版本,點擊此處返回。
download.failed.refresh=載入版本列表失敗,點擊此處重試。
download.mojang=官方伺服器Mojang
download.provider.bmclapi=BMCLAPIbangbang93https://bmclapi2.bangbang93.com/
download.provider.mojang=官方伺服器Mojang
extension.bat=Windows 腳本
extension.mod=模組檔案

View File

@ -84,11 +84,11 @@ crash.NoClassDefFound=请确认 HMCL 本体是否完整,或更新您的 Java
crash.user_fault=您的系统或 Java 环境可能安装不当导致本软件崩溃,请检查您的 Java 环境或您的电脑!可以尝试重新安装 Java。
download=下载
download.BMCL=BMCLAPIbangbang93https://bmclapi2.bangbang93.com/
download.failed=下载失败
download.failed.empty=没有可供安装的版本,点击此处返回。
download.failed.refresh=加载版本列表失败,点击此处重试。
download.mojang=官方Mojang
download.provider.bmclapi=BMCLAPIbangbang93https://bmclapi2.bangbang93.com/
download.provider.mojang=官方Mojang
extension.bat=Windows 脚本
extension.mod=模组文件

View File

@ -28,11 +28,6 @@ import org.jackhuang.hmcl.download.optifine.OptiFineBMCLVersionList;
*/
public class BMCLAPIDownloadProvider implements DownloadProvider {
public static final BMCLAPIDownloadProvider INSTANCE = new BMCLAPIDownloadProvider();
private BMCLAPIDownloadProvider() {
}
@Override
public String getVersionListURL() {
return "https://bmclapi2.bangbang93.com/mc/game/version_manifest.json";

View File

@ -1,27 +0,0 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.download;
public class CurseCDNDownloadProvider extends MojangDownloadProvider {
public static final CurseCDNDownloadProvider INSTANCE = new CurseCDNDownloadProvider();
@Override
public String injectURL(String baseURL) {
return baseURL == null ? null : baseURL.replaceFirst("https?://files\\.minecraftforge\\.net/maven", "https://ftb.cursecdn.com/FTB2/maven");
}
}

View File

@ -23,7 +23,7 @@ import org.jackhuang.hmcl.download.liteloader.LiteLoaderVersionList;
import org.jackhuang.hmcl.download.optifine.OptiFineBMCLVersionList;
/**
* @see <a href="http://wiki.vg">http://wiki,vg</a>
* @see <a href="http://wiki.vg">http://wiki.vg</a>
* @author huangyuhui
*/
public class MojangDownloadProvider implements DownloadProvider {
@ -56,6 +56,6 @@ public class MojangDownloadProvider implements DownloadProvider {
@Override
public String injectURL(String baseURL) {
return baseURL;
return baseURL;
}
}

View File

@ -0,0 +1,42 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.util;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SelectionModel;
public class SelectionModelSelectedItemProperty<T> extends SimpleObjectProperty<T> {
public static <T> SelectionModelSelectedItemProperty<T> selectedItemPropertyFor(ComboBox<T> comboBox) {
return new SelectionModelSelectedItemProperty<>(comboBox.getSelectionModel());
}
private SelectionModel<T> model;
public SelectionModelSelectedItemProperty(SelectionModel<T> model) {
this.model = model;
model.selectedItemProperty().addListener((observable, oldValue, newValue) -> set(newValue));
set(model.getSelectedItem());
}
@Override
protected void invalidated() {
model.select(get());
}
}