fix: ModListPage not loading mods.

This commit is contained in:
huanghongxun 2021-08-04 01:29:07 +08:00
parent 5ddb69077f
commit 53c63db150
11 changed files with 118 additions and 101 deletions

View File

@ -114,13 +114,14 @@ public final class FXUtils {
return onWeakChange(value, consumer);
}
public static WeakInvalidationListener observeWeak(Runnable runnable, Observable... observables) {
WeakInvalidationListener listener = new WeakInvalidationListener(observable -> runnable.run());
public static InvalidationListener observeWeak(Runnable runnable, Observable... observables) {
InvalidationListener originalListener = observable -> runnable.run();
WeakInvalidationListener listener = new WeakInvalidationListener(originalListener);
for (Observable observable : observables) {
observable.addListener(listener);
}
runnable.run();
return listener;
return originalListener;
}
public static void runLaterIf(BooleanSupplier condition, Runnable runnable) {

View File

@ -19,7 +19,7 @@ package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.controls.JFXSpinner;
import javafx.beans.DefaultProperty;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.InvalidationListener;
import javafx.beans.property.*;
import javafx.scene.Node;
import javafx.scene.control.Control;
@ -94,7 +94,7 @@ public class SpinnerPane extends Control {
private final StackPane failedPane = new StackPane();
private final Label failedReasonLabel = new Label();
@SuppressWarnings("FieldCanBeLocal") // prevent from gc.
private final WeakInvalidationListener observer;
private final InvalidationListener observer;
protected Skin(SpinnerPane control) {
super(control);

View File

@ -27,9 +27,9 @@ import javafx.scene.control.SingleSelectionModel;
import java.util.function.Supplier;
public interface TabControl {
ObservableList<Tab> getTabs();
ObservableList<Tab<?>> getTabs();
class TabControlSelectionModel extends SingleSelectionModel<Tab> {
class TabControlSelectionModel extends SingleSelectionModel<Tab<?>> {
private final TabControl tabHeader;
public TabControlSelectionModel(final TabControl t) {
@ -39,9 +39,9 @@ public interface TabControl {
this.tabHeader = t;
// watching for changes to the items list content
final ListChangeListener<Tab> itemsContentObserver = c -> {
final ListChangeListener<Tab<?>> itemsContentObserver = c -> {
while (c.next()) {
for (Tab tab : c.getRemoved()) {
for (Tab<?> tab : c.getRemoved()) {
if (tab != null && !tabHeader.getTabs().contains(tab)) {
if (tab.isSelected()) {
tab.setSelected(false);
@ -117,29 +117,29 @@ public interface TabControl {
}
}
@Override protected Tab getModelItem(int index) {
final ObservableList<Tab> items = tabHeader.getTabs();
@Override protected Tab<?> getModelItem(int index) {
final ObservableList<Tab<?>> items = tabHeader.getTabs();
if (items == null) return null;
if (index < 0 || index >= items.size()) return null;
return items.get(index);
}
@Override protected int getItemCount() {
final ObservableList<Tab> items = tabHeader.getTabs();
final ObservableList<Tab<?>> items = tabHeader.getTabs();
return items == null ? 0 : items.size();
}
private Tab findNearestAvailableTab(int tabIndex, boolean doSelect) {
private Tab<?> findNearestAvailableTab(int tabIndex, boolean doSelect) {
// we always try to select the nearest, non-disabled
// tab from the position of the closed tab.
final int tabCount = getItemCount();
int i = 1;
Tab bestTab = null;
Tab<?> bestTab = null;
while (true) {
// look leftwards
int downPos = tabIndex - i;
if (downPos >= 0) {
Tab _tab = getModelItem(downPos);
Tab<?> _tab = getModelItem(downPos);
if (_tab != null) {
bestTab = _tab;
break;
@ -153,7 +153,7 @@ public interface TabControl {
// the removed tabs position).
int upPos = tabIndex + i - 1;
if (upPos < tabCount) {
Tab _tab = getModelItem(upPos);
Tab<?> _tab = getModelItem(upPos);
if (_tab != null) {
bestTab = _tab;
break;
@ -174,12 +174,12 @@ public interface TabControl {
}
}
class Tab {
class Tab<T extends Node> {
private final StringProperty id = new SimpleStringProperty(this, "id");
private final StringProperty text = new SimpleStringProperty(this, "text");
private final ReadOnlyBooleanWrapper selected = new ReadOnlyBooleanWrapper(this, "selected");
private final ObjectProperty<Node> node = new SimpleObjectProperty<>(this, "node");
private Supplier<Node> nodeSupplier;
private final ObjectProperty<T> node = new SimpleObjectProperty<>(this, "node");
private Supplier<? extends T> nodeSupplier;
public Tab(String id) {
setId(id);
@ -190,11 +190,11 @@ public interface TabControl {
setText(text);
}
public Supplier<Node> getNodeSupplier() {
public Supplier<? extends T> getNodeSupplier() {
return nodeSupplier;
}
public void setNodeSupplier(Supplier<Node> nodeSupplier) {
public void setNodeSupplier(Supplier<? extends T> nodeSupplier) {
this.nodeSupplier = nodeSupplier;
}
@ -234,16 +234,27 @@ public interface TabControl {
this.selected.set(selected);
}
public Node getNode() {
public T getNode() {
return node.get();
}
public ObjectProperty<Node> nodeProperty() {
public ObjectProperty<T> nodeProperty() {
return node;
}
public void setNode(Node node) {
public void setNode(T node) {
this.node.set(node);
}
public boolean initializeIfNeeded() {
if (getNode() == null) {
if (getNodeSupplier() == null) {
return false;
}
setNode(getNodeSupplier().get());
return true;
}
return false;
}
}
}

View File

@ -41,32 +41,32 @@ import org.jackhuang.hmcl.util.javafx.MappedObservableList;
public class TabHeader extends Control implements TabControl {
public TabHeader(Tab... tabs) {
public TabHeader(Tab<?>... tabs) {
getStyleClass().setAll("tab-header");
if (tabs != null) {
getTabs().addAll(tabs);
}
}
private ObservableList<Tab> tabs = FXCollections.observableArrayList();
private ObservableList<Tab<?>> tabs = FXCollections.observableArrayList();
private ObjectProperty<Side> side = new SimpleObjectProperty<>(Side.TOP);
@Override
public ObservableList<Tab> getTabs() {
public ObservableList<Tab<?>> getTabs() {
return tabs;
}
private final ObjectProperty<SingleSelectionModel<Tab>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControlSelectionModel(this));
private final ObjectProperty<SingleSelectionModel<Tab<?>>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControlSelectionModel(this));
public SingleSelectionModel<Tab> getSelectionModel() {
public SingleSelectionModel<Tab<?>> getSelectionModel() {
return selectionModel.get();
}
public ObjectProperty<SingleSelectionModel<Tab>> selectionModelProperty() {
public ObjectProperty<SingleSelectionModel<Tab<?>>> selectionModelProperty() {
return selectionModel;
}
public void setSelectionModel(SingleSelectionModel<Tab> selectionModel) {
public void setSelectionModel(SingleSelectionModel<Tab<?>> selectionModel) {
this.selectionModel.set(selectionModel);
}
@ -104,7 +104,7 @@ public class TabHeader extends Control implements TabControl {
private final HeaderContainer header;
private boolean isSelectingTab = false;
private Tab selectedTab;
private Tab<?> selectedTab;
protected TabHeaderSkin(TabHeader control) {
super(control);
@ -537,12 +537,12 @@ public class TabHeader extends Control implements TabControl {
protected class TabHeaderContainer extends StackPane {
private final Tab tab;
private final Tab<?> tab;
private final Label tabText;
private final BorderPane inner;
private final JFXRippler rippler;
public TabHeaderContainer(Tab tab) {
public TabHeaderContainer(Tab<?> tab) {
this.tab = tab;
tabText = new Label();

View File

@ -32,9 +32,7 @@ public abstract class DecoratorTabPage extends DecoratorTransitionPage implement
public DecoratorTabPage() {
getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
if (newValue.getNode() == null && newValue.getNodeSupplier() != null) {
newValue.setNode(newValue.getNodeSupplier().get());
}
newValue.initializeIfNeeded();
if (newValue.getNode() != null) {
onNavigating(getCurrentPage());
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATING));
@ -45,31 +43,31 @@ public abstract class DecoratorTabPage extends DecoratorTransitionPage implement
});
}
public DecoratorTabPage(TabHeader.Tab... tabs) {
public DecoratorTabPage(TabHeader.Tab<?>... tabs) {
this();
if (tabs != null) {
getTabs().addAll(tabs);
}
}
private ObservableList<TabHeader.Tab> tabs = FXCollections.observableArrayList();
private ObservableList<TabHeader.Tab<?>> tabs = FXCollections.observableArrayList();
@Override
public ObservableList<TabHeader.Tab> getTabs() {
public ObservableList<TabHeader.Tab<?>> getTabs() {
return tabs;
}
private final ObjectProperty<SingleSelectionModel<TabHeader.Tab>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControl.TabControlSelectionModel(this));
private final ObjectProperty<SingleSelectionModel<TabHeader.Tab<?>>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControl.TabControlSelectionModel(this));
public SingleSelectionModel<TabHeader.Tab> getSelectionModel() {
public SingleSelectionModel<TabHeader.Tab<?>> getSelectionModel() {
return selectionModel.get();
}
public ObjectProperty<SingleSelectionModel<TabHeader.Tab>> selectionModelProperty() {
public ObjectProperty<SingleSelectionModel<TabHeader.Tab<?>>> selectionModelProperty() {
return selectionModel;
}
public void setSelectionModel(SingleSelectionModel<TabHeader.Tab> selectionModel) {
public void setSelectionModel(SingleSelectionModel<TabHeader.Tab<?>> selectionModel) {
this.selectionModel.set(selectionModel);
}
}

View File

@ -44,7 +44,7 @@ import java.util.function.Function;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class InstallerListPage extends ListPageBase<InstallerItem> {
public class InstallerListPage extends ListPageBase<InstallerItem> implements VersionPage.VersionLoadable {
private Profile profile;
private String versionId;
private Version version;
@ -62,13 +62,14 @@ public class InstallerListPage extends ListPageBase<InstallerItem> {
return new InstallerListPageSkin();
}
public CompletableFuture<?> loadVersion(Profile profile, String versionId) {
@Override
public void loadVersion(Profile profile, String versionId) {
this.profile = profile;
this.versionId = versionId;
this.version = profile.getRepository().getVersion(versionId);
this.gameVersion = null;
return CompletableFuture.supplyAsync(() -> {
CompletableFuture.supplyAsync(() -> {
gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)).orElse(null);
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));

View File

@ -47,7 +47,7 @@ import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class ModDownloadListPage extends Control implements DecoratorPage {
public class ModDownloadListPage extends Control implements DecoratorPage, VersionPage.VersionLoadable {
protected final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>();
private final BooleanProperty loading = new SimpleBooleanProperty(false);
private final BooleanProperty failed = new SimpleBooleanProperty(false);
@ -66,6 +66,7 @@ public class ModDownloadListPage extends Control implements DecoratorPage {
this.callback = callback;
}
@Override
public void loadVersion(Profile profile, String version) {
this.version.set(new Profile.ProfileVersion(profile, version));

View File

@ -32,7 +32,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.ListPageBase;
import org.jackhuang.hmcl.ui.construct.TabHeader;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.FileUtils;
@ -50,16 +49,13 @@ import java.util.stream.Collectors;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObject> {
public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObject> implements VersionPage.VersionLoadable {
private final BooleanProperty modded = new SimpleBooleanProperty(this, "modded", false);
private TabHeader.Tab tab;
private ModManager modManager;
private LibraryAnalyzer libraryAnalyzer;
public ModListPage(TabHeader.Tab tab) {
this.tab = tab;
public ModListPage() {
FXUtils.applyDragListener(this, it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it)), mods -> {
mods.forEach(it -> {
try {
@ -81,10 +77,11 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
loadMods(modManager);
}
public CompletableFuture<?> loadVersion(Profile profile, String id) {
@Override
public void loadVersion(Profile profile, String id) {
libraryAnalyzer = LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(id));
modded.set(libraryAnalyzer.hasModLoader());
return loadMods(profile.getRepository().getModManager(id));
loadMods(profile.getRepository().getModManager(id));
}
private CompletableFuture<?> loadMods(ModManager modManager) {
@ -99,13 +96,10 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}).whenCompleteAsync((list, exception) -> {
}, Schedulers.defaultScheduler()).whenCompleteAsync((list, exception) -> {
loadingProperty().set(false);
if (exception == null)
getProperties().put(ModListPage.class, FXUtils.onWeakChangeAndOperate(tab.selectedProperty(), newValue -> {
if (newValue)
itemsProperty().setAll(list.stream().map(ModListPageSkin.ModInfoObject::new).sorted().collect(Collectors.toList()));
}));
itemsProperty().setAll(list.stream().map(ModListPageSkin.ModInfoObject::new).sorted().collect(Collectors.toList()));
else
getProperties().remove(ModListPage.class);
}, Platform::runLater);

View File

@ -48,41 +48,45 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class VersionPage extends Control implements DecoratorPage, ModDownloadPage.DownloadCallback {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>();
private final BooleanProperty loading = new SimpleBooleanProperty();
private final TabHeader.Tab versionSettingsTab = new TabHeader.Tab("versionSettingsTab");
private final VersionSettingsPage versionSettingsPage = new VersionSettingsPage();
private final TabHeader.Tab modListTab = new TabHeader.Tab("modListTab");
private final ModListPage modListPage = new ModListPage(modListTab);
private final TabHeader.Tab curseModListTab = new TabHeader.Tab("modListTab");
private final ModDownloadListPage curseModListPage = new ModDownloadListPage(CurseModManager.SECTION_MOD, this);
private final TabHeader.Tab installerListTab = new TabHeader.Tab("installerListTab");
private final InstallerListPage installerListPage = new InstallerListPage();
private final TabHeader.Tab worldListTab = new TabHeader.Tab("worldList");
private final WorldListPage worldListPage = new WorldListPage();
private final TabHeader tab;
private final TabHeader.Tab<VersionSettingsPage> versionSettingsTab = new TabHeader.Tab<>("versionSettingsTab");
private final TabHeader.Tab<ModListPage> modListTab = new TabHeader.Tab<>("modListTab");
private final TabHeader.Tab<ModDownloadListPage> curseModListTab = new TabHeader.Tab<>("modListTab");
private final TabHeader.Tab<InstallerListPage> installerListTab = new TabHeader.Tab<>("installerListTab");
private final TabHeader.Tab<WorldListPage> worldListTab = new TabHeader.Tab<>("worldList");
private final TransitionPane transitionPane = new TransitionPane();
private final ObjectProperty<TabHeader.Tab> selectedTab = new SimpleObjectProperty<>();
private final BooleanProperty currentVersionUpgradable = new SimpleBooleanProperty();
private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>();
private String preferredVersionName = null;
{
versionSettingsTab.setNode(versionSettingsPage);
modListTab.setNode(modListPage);
curseModListTab.setNode(curseModListPage);
installerListTab.setNode(installerListPage);
worldListTab.setNode(worldListPage);
versionSettingsTab.setNodeSupplier(VersionSettingsPage::new);
modListTab.setNodeSupplier(ModListPage::new);
curseModListTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MOD, this));
installerListTab.setNodeSupplier(InstallerListPage::new);
worldListTab.setNodeSupplier(WorldListPage::new);
tab = new TabHeader(versionSettingsTab, modListTab, curseModListTab, installerListTab, worldListTab);
addEventHandler(Navigator.NavigationEvent.NAVIGATED, this::onNavigated);
selectedTab.set(versionSettingsTab);
FXUtils.onChangeAndOperate(selectedTab, newValue -> {
tab.getSelectionModel().select(versionSettingsTab);
FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> {
if (newValue.initializeIfNeeded()) {
if (this.version.get() != null) {
if (newValue.getNode() instanceof VersionLoadable) {
((VersionLoadable) newValue.getNode()).loadVersion(version.get().getProfile(), version.get().getVersion());
}
}
}
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
});
}
@ -103,14 +107,17 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
setVersion(version, profile);
preferredVersionName = version;
versionSettingsPage.loadVersion(profile, version);
curseModListPage.loadVersion(profile, version);
if (versionSettingsTab.getNode() != null)
versionSettingsTab.getNode().loadVersion(profile, version);
if (modListTab.getNode() != null)
modListTab.getNode().loadVersion(profile, version);
if (curseModListTab.getNode() != null)
curseModListTab.getNode().loadVersion(profile, version);
if (installerListTab.getNode() != null)
installerListTab.getNode().loadVersion(profile, version);
if (worldListTab.getNode() != null)
worldListTab.getNode().loadVersion(profile, version);
currentVersionUpgradable.set(profile.getRepository().isModpack(version));
CompletableFuture.allOf(
modListPage.loadVersion(profile, version),
installerListPage.loadVersion(profile, version),
worldListPage.loadVersion(profile, version));
}
private void onNavigated(Navigator.NavigationEvent event) {
@ -269,40 +276,40 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
versionSettingsItem.setTitle(i18n("settings"));
versionSettingsItem.setLeftGraphic(wrap(SVG.gearOutline(null, 20, 20)));
versionSettingsItem.setActionButtonVisible(false);
versionSettingsItem.activeProperty().bind(control.selectedTab.isEqualTo(control.versionSettingsTab));
versionSettingsItem.setOnAction(e -> control.selectedTab.set(control.versionSettingsTab));
versionSettingsItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.versionSettingsTab));
versionSettingsItem.setOnAction(e -> control.tab.getSelectionModel().select(control.versionSettingsTab));
AdvancedListItem modListItem = new AdvancedListItem();
modListItem.getStyleClass().add("navigation-drawer-item");
modListItem.setTitle(i18n("mods"));
modListItem.setLeftGraphic(wrap(SVG.puzzle(null, 20, 20)));
modListItem.setActionButtonVisible(false);
modListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.modListTab));
modListItem.setOnAction(e -> control.selectedTab.set(control.modListTab));
modListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.modListTab));
modListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.modListTab));
AdvancedListItem curseModListItem = new AdvancedListItem();
curseModListItem.getStyleClass().add("navigation-drawer-item");
curseModListItem.setTitle(i18n("mods.download"));
curseModListItem.setLeftGraphic(wrap(SVG.fire(null, 20, 20)));
curseModListItem.setActionButtonVisible(false);
curseModListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.curseModListTab));
curseModListItem.setOnAction(e -> control.selectedTab.set(control.curseModListTab));
curseModListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.curseModListTab));
curseModListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.curseModListTab));
AdvancedListItem installerListItem = new AdvancedListItem();
installerListItem.getStyleClass().add("navigation-drawer-item");
installerListItem.setTitle(i18n("settings.tabs.installers"));
installerListItem.setLeftGraphic(wrap(SVG.cube(null, 20, 20)));
installerListItem.setActionButtonVisible(false);
installerListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.installerListTab));
installerListItem.setOnAction(e -> control.selectedTab.set(control.installerListTab));
installerListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.installerListTab));
installerListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.installerListTab));
AdvancedListItem worldListItem = new AdvancedListItem();
worldListItem.getStyleClass().add("navigation-drawer-item");
worldListItem.setTitle(i18n("world"));
worldListItem.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20)));
worldListItem.setActionButtonVisible(false);
worldListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.worldListTab));
worldListItem.setOnAction(e -> control.selectedTab.set(control.worldListTab));
worldListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.worldListTab));
worldListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.worldListTab));
AdvancedListBox sideBar = new AdvancedListBox()
.add(versionSettingsItem)
@ -403,4 +410,7 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
return stackPane;
}
interface VersionLoadable {
void loadVersion(Profile profile, String version);
}
}

View File

@ -67,7 +67,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.newImage;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class VersionSettingsPage extends StackPane implements DecoratorPage {
public final class VersionSettingsPage extends StackPane implements DecoratorPage, VersionPage.VersionLoadable {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(new State("", null, false, false, false));
private VersionSetting lastVersionSetting = null;
@ -168,6 +168,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
advancedSettingsPane.disableProperty().bind(chkEnableSpecificSettings.selectedProperty().not());
}
@Override
public void loadVersion(Profile profile, String versionId) {
this.profile = profile;
this.versionId = versionId;

View File

@ -47,7 +47,7 @@ import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class WorldListPage extends ListPageBase<WorldListItem> {
public class WorldListPage extends ListPageBase<WorldListItem> implements VersionPage.VersionLoadable {
private final BooleanProperty showAll = new SimpleBooleanProperty(this, "showAll", false);
private Path savesDir;
@ -74,11 +74,11 @@ public class WorldListPage extends ListPageBase<WorldListItem> {
return new WorldListPageSkin();
}
public CompletableFuture<?> loadVersion(Profile profile, String id) {
public void loadVersion(Profile profile, String id) {
this.profile = profile;
this.id = id;
this.savesDir = profile.getRepository().getRunDirectory(id).toPath().resolve("saves");
return refresh();
refresh();
}
public CompletableFuture<?> refresh() {