Reconstruct MultiFileItem

This commit is contained in:
huangyuhui
2018-07-21 11:39:41 +08:00
parent 1b62972f06
commit 12838994ad
3 changed files with 87 additions and 67 deletions

View File

@@ -81,7 +81,7 @@ public final class VersionSetting {
} }
/** /**
* Java version or null if user customizes java directory. * Java version or "Custom" if user customizes java directory, "Default" if the jvm that this app relies on.
*/ */
public String getJava() { public String getJava() {
return javaProperty.get(); return javaProperty.get();
@@ -91,6 +91,15 @@ public final class VersionSetting {
javaProperty.set(java); javaProperty.set(java);
} }
public boolean isUsesCustomJavaDir() {
return "Custom".equals(getJava());
}
public void setUsesCustomJavaDir() {
setJava("Custom");
setDefaultJavaPath(null);
}
private final ImmediateStringProperty defaultJavaPathProperty = new ImmediateStringProperty(this, "defaultJavaPath", ""); private final ImmediateStringProperty defaultJavaPathProperty = new ImmediateStringProperty(this, "defaultJavaPath", "");
/** /**
@@ -455,7 +464,7 @@ public final class VersionSetting {
if (StringUtils.isBlank(getJava())) if (StringUtils.isBlank(getJava()))
setJava(StringUtils.isBlank(getJavaDir()) ? "Default" : "Custom"); setJava(StringUtils.isBlank(getJavaDir()) ? "Default" : "Custom");
if ("Default".equals(getJava())) return JavaVersion.fromCurrentEnvironment(); if ("Default".equals(getJava())) return JavaVersion.fromCurrentEnvironment();
else if ("Custom".equals(getJava())) { else if (isUsesCustomJavaDir()) {
try { try {
return JavaVersion.fromExecutable(new File(getJavaDir())); return JavaVersion.fromExecutable(new File(getJavaDir()));
} catch (IOException e) { } catch (IOException e) {
@@ -477,6 +486,11 @@ public final class VersionSetting {
} else throw new Error(); } else throw new Error();
} }
public void setJavaVersion(JavaVersion java) {
setJava(java.getVersion());
setDefaultJavaPath(java.getBinary().toString());
}
public void addPropertyChangedListener(InvalidationListener listener) { public void addPropertyChangedListener(InvalidationListener listener) {
usesGlobalProperty.addListener(listener); usesGlobalProperty.addListener(listener);
javaProperty.addListener(listener); javaProperty.addListener(listener);

View File

@@ -22,6 +22,7 @@ import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import com.jfoenix.controls.JFXToggleButton; import com.jfoenix.controls.JFXToggleButton;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
@@ -72,9 +73,9 @@ public final class VersionSettingsController {
@FXML private JFXToggleButton chkNoJVMArgs; @FXML private JFXToggleButton chkNoJVMArgs;
@FXML private JFXToggleButton chkNoCommon; @FXML private JFXToggleButton chkNoCommon;
@FXML private JFXToggleButton chkNoGameCheck; @FXML private JFXToggleButton chkNoGameCheck;
@FXML private MultiFileItem globalItem; @FXML private MultiFileItem<Boolean> globalItem;
@FXML private MultiFileItem javaItem; @FXML private MultiFileItem<JavaVersion> javaItem;
@FXML private MultiFileItem gameDirItem; @FXML private MultiFileItem<EnumGameDirectory> gameDirItem;
@FXML private JFXToggleButton chkShowLogs; @FXML private JFXToggleButton chkShowLogs;
@FXML private ImagePickerItem iconPickerItem; @FXML private ImagePickerItem iconPickerItem;
@@ -94,9 +95,12 @@ public final class VersionSettingsController {
initializeSelectedJava(); initializeSelectedJava();
}); });
javaItem.setSelectedData(null);
javaItem.setFallbackData(JavaVersion.fromCurrentEnvironment());
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS)
javaItem.getExtensionFilters().add(new FileChooser.ExtensionFilter("Java", "java.exe", "javaw.exe")); javaItem.getExtensionFilters().add(new FileChooser.ExtensionFilter("Java", "java.exe", "javaw.exe"));
gameDirItem.setCustomUserData(EnumGameDirectory.CUSTOM);
gameDirItem.loadChildren(Arrays.asList( gameDirItem.loadChildren(Arrays.asList(
gameDirItem.createChildren(i18n("settings.advanced.game_dir.default"), EnumGameDirectory.ROOT_FOLDER), gameDirItem.createChildren(i18n("settings.advanced.game_dir.default"), EnumGameDirectory.ROOT_FOLDER),
gameDirItem.createChildren(i18n("settings.advanced.game_dir.independent"), EnumGameDirectory.VERSION_FOLDER) gameDirItem.createChildren(i18n("settings.advanced.game_dir.independent"), EnumGameDirectory.VERSION_FOLDER)
@@ -136,12 +140,16 @@ public final class VersionSettingsController {
FXUtils.unbindBoolean(chkNoJVMArgs, lastVersionSetting.noJVMArgsProperty()); FXUtils.unbindBoolean(chkNoJVMArgs, lastVersionSetting.noJVMArgsProperty());
FXUtils.unbindBoolean(chkShowLogs, lastVersionSetting.showLogsProperty()); FXUtils.unbindBoolean(chkShowLogs, lastVersionSetting.showLogsProperty());
FXUtils.unbindEnum(cboLauncherVisibility); FXUtils.unbindEnum(cboLauncherVisibility);
globalItem.selectedDataProperty().unbindBidirectional(lastVersionSetting.usesGlobalProperty());
gameDirItem.selectedDataProperty().unbindBidirectional(lastVersionSetting.gameDirTypeProperty());
gameDirItem.subtitleProperty().unbind();
} }
// unbind data fields // unbind data fields
globalItem.setToggleSelectedListener(null); globalItem.setToggleSelectedListener(null);
javaItem.setToggleSelectedListener(null); javaItem.setToggleSelectedListener(null);
gameDirItem.setToggleSelectedListener(null);
// bind new data fields // bind new data fields
FXUtils.bindInt(txtWidth, versionSetting.widthProperty()); FXUtils.bindInt(txtWidth, versionSetting.widthProperty());
@@ -164,12 +172,9 @@ public final class VersionSettingsController {
javaItem.setToggleSelectedListener(newValue -> { javaItem.setToggleSelectedListener(newValue -> {
if (javaItem.isCustomToggle(newValue)) { if (javaItem.isCustomToggle(newValue)) {
versionSetting.setJava("Custom"); versionSetting.setUsesCustomJavaDir();
versionSetting.setDefaultJavaPath(null);
} else { } else {
JavaVersion java = (JavaVersion) newValue.getUserData(); versionSetting.setJavaVersion((JavaVersion) newValue.getUserData());
versionSetting.setJava(java.getVersion());
versionSetting.setDefaultJavaPath(java.getBinary().toString());
} }
}); });
@@ -177,13 +182,13 @@ public final class VersionSettingsController {
versionSetting.javaProperty().setChangedListener(it -> initJavaSubtitle(versionSetting)); versionSetting.javaProperty().setChangedListener(it -> initJavaSubtitle(versionSetting));
initJavaSubtitle(versionSetting); initJavaSubtitle(versionSetting);
if (versionSetting.isUsesGlobal()) globalItem.selectedDataProperty().bindBidirectional(versionSetting.usesGlobalProperty());
globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.TRUE).findFirst().ifPresent(it -> it.setSelected(true)); globalItem.subtitleProperty().bind(Bindings.createStringBinding(() -> i18n(versionSetting.isUsesGlobal() ? "settings.type.global" : "settings.type.special"),
else versionSetting.usesGlobalProperty()));
globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.FALSE).findFirst().ifPresent(it -> it.setSelected(true));
globalItem.setToggleSelectedListener(newValue -> { globalItem.setToggleSelectedListener(newValue -> {
// do not call versionSettings.setUsesGlobal(true/false) // do not call versionSettings.setUsesGlobal(true/false)
// because versionSettings can be the global one. // because versionSettings can be the global one.
// global versionSettings.usesGlobal is always true.
if ((Boolean) newValue.getUserData()) if ((Boolean) newValue.getUserData())
profile.globalizeVersionSetting(versionId); profile.globalizeVersionSetting(versionId);
else else
@@ -192,19 +197,9 @@ public final class VersionSettingsController {
Platform.runLater(() -> loadVersionSetting(profile, versionId)); Platform.runLater(() -> loadVersionSetting(profile, versionId));
}); });
versionSetting.usesGlobalProperty().setChangedListenerAndOperate(it -> gameDirItem.selectedDataProperty().bindBidirectional(versionSetting.gameDirTypeProperty());
globalItem.setSubtitle(i18n(versionSetting.isUsesGlobal() ? "settings.type.global" : "settings.type.special"))); gameDirItem.subtitleProperty().bind(Bindings.createStringBinding(() -> profile.getRepository().getRunDirectory(versionId).getAbsolutePath(),
versionSetting.gameDirProperty(), versionSetting.gameDirTypeProperty()));
gameDirItem.getGroup().getToggles().stream()
.filter(it -> it.getUserData() == versionSetting.getGameDirType())
.findFirst().ifPresent(toggle -> toggle.setSelected(true));
gameDirItem.setCustomUserData(EnumGameDirectory.CUSTOM);
gameDirItem.setToggleSelectedListener(newValue -> versionSetting.setGameDirType((EnumGameDirectory) newValue.getUserData()));
versionSetting.gameDirProperty().setChangedListener(it -> initGameDirSubtitle(versionSetting));
versionSetting.gameDirTypeProperty().setChangedListener(it -> initGameDirSubtitle(versionSetting));
initGameDirSubtitle(versionSetting);
lastVersionSetting = versionSetting; lastVersionSetting = versionSetting;
@@ -219,30 +214,14 @@ public final class VersionSettingsController {
return; return;
} }
List<Toggle> toggles = javaItem.getGroup().getToggles(); if (lastVersionSetting.isUsesCustomJavaDir()) {
if ("Custom".equals(lastVersionSetting.getJava())) { javaItem.setSelectedData(null);
toggles.stream()
.filter(javaItem::isCustomToggle)
.findFirst()
.get().setSelected(true);
} else { } else {
JavaVersion selectedJava;
try { try {
selectedJava = lastVersionSetting.getJavaVersion(); javaItem.setSelectedData(lastVersionSetting.getJavaVersion());
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
return;
} }
toggles.stream()
.filter(it -> it.getUserData() == selectedJava)
.findFirst()
.orElseGet( // fallback to select current java
() -> toggles.stream()
.filter(it -> it.getUserData() == JavaVersion.fromCurrentEnvironment())
.findFirst()
.get())
.setSelected(true);
;
} }
} }
@@ -253,10 +232,6 @@ public final class VersionSettingsController {
.map(JavaVersion::getBinary).map(File::getAbsolutePath).orElse("Invalid Java Directory")))); .map(JavaVersion::getBinary).map(File::getAbsolutePath).orElse("Invalid Java Directory"))));
} }
private void initGameDirSubtitle(VersionSetting versionSetting) {
gameDirItem.setSubtitle(profile.getRepository().getRunDirectory(versionId).getAbsolutePath());
}
@FXML @FXML
private void onExploreIcon() { private void onExploreIcon() {
FileChooser chooser = new FileChooser(); FileChooser chooser = new FileChooser();

View File

@@ -21,10 +21,7 @@ import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXRadioButton; import com.jfoenix.controls.JFXRadioButton;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import javafx.beans.NamedArg; import javafx.beans.NamedArg;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.*;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@@ -46,12 +43,15 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import java.io.File; import java.io.File;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
public class MultiFileItem extends ComponentList { public class MultiFileItem<T> extends ComponentList {
private final StringProperty customTitle = new SimpleStringProperty(this, "customTitle", i18n("selector.custom")); private final StringProperty customTitle = new SimpleStringProperty(this, "customTitle", i18n("selector.custom"));
private final StringProperty chooserTitle = new SimpleStringProperty(this, "chooserTitle", i18n("selector.choose_file")); private final StringProperty chooserTitle = new SimpleStringProperty(this, "chooserTitle", i18n("selector.choose_file"));
private final BooleanProperty directory = new SimpleBooleanProperty(this, "directory", false); private final BooleanProperty directory = new SimpleBooleanProperty(this, "directory", false);
private final ObjectProperty<T> selectedData = new SimpleObjectProperty<>(this, "selectedData");
private final ObjectProperty<T> fallbackData = new SimpleObjectProperty<>(this, "fallbackData");
private final ObservableList<FileChooser.ExtensionFilter> extensionFilters = FXCollections.observableArrayList(); private final ObservableList<FileChooser.ExtensionFilter> extensionFilters = FXCollections.observableArrayList();
private final ToggleGroup group = new ToggleGroup(); private final ToggleGroup group = new ToggleGroup();
@@ -64,6 +64,7 @@ public class MultiFileItem extends ComponentList {
private Consumer<Toggle> toggleSelectedListener; private Consumer<Toggle> toggleSelectedListener;
@SuppressWarnings("unchecked")
public MultiFileItem(@NamedArg(value = "hasCustom", defaultValue = "true") boolean hasCustom) { public MultiFileItem(@NamedArg(value = "hasCustom", defaultValue = "true") boolean hasCustom) {
this.hasCustom = hasCustom; this.hasCustom = hasCustom;
@@ -110,6 +111,20 @@ public class MultiFileItem extends ComponentList {
group.selectedToggleProperty().addListener((a, b, newValue) -> { group.selectedToggleProperty().addListener((a, b, newValue) -> {
if (toggleSelectedListener != null) if (toggleSelectedListener != null)
toggleSelectedListener.accept(newValue); toggleSelectedListener.accept(newValue);
selectedData.set((T) newValue.getUserData());
});
selectedData.addListener((a, b, newValue) -> {
Optional<Toggle> selecting = group.getToggles().stream()
.filter(it -> it.getUserData() == newValue)
.findFirst();
if (!selecting.isPresent()) {
selecting = group.getToggles().stream()
.filter(it -> it.getUserData() == getFallbackData())
.findFirst();
}
selecting.ifPresent(toggle -> toggle.setSelected(true));
}); });
} }
@@ -117,11 +132,11 @@ public class MultiFileItem extends ComponentList {
return createChildren(title, null); return createChildren(title, null);
} }
public Node createChildren(String title, Object userData) { public Node createChildren(String title, T userData) {
return createChildren(title, "", userData); return createChildren(title, "", userData);
} }
public Node createChildren(String title, String subtitle, Object userData) { public Node createChildren(String title, String subtitle, T userData) {
BorderPane pane = new BorderPane(); BorderPane pane = new BorderPane();
pane.setStyle("-fx-padding: 3;"); pane.setStyle("-fx-padding: 3;");
FXUtils.setLimitHeight(pane, 20); FXUtils.setLimitHeight(pane, 20);
@@ -146,14 +161,6 @@ public class MultiFileItem extends ComponentList {
pane.getChildren().add(custom); pane.getChildren().add(custom);
} }
public void onExploreJavaDir() {
DirectoryChooser chooser = new DirectoryChooser();
chooser.setTitle(i18n(getChooserTitle()));
File selectedDir = chooser.showDialog(Controllers.getStage());
if (selectedDir != null)
txtCustom.setText(selectedDir.getAbsolutePath());
}
public ToggleGroup getGroup() { public ToggleGroup getGroup() {
return group; return group;
} }
@@ -182,7 +189,7 @@ public class MultiFileItem extends ComponentList {
this.chooserTitle.set(chooserTitle); this.chooserTitle.set(chooserTitle);
} }
public void setCustomUserData(Object userData) { public void setCustomUserData(T userData) {
radioCustom.setUserData(userData); radioCustom.setUserData(userData);
} }
@@ -225,4 +232,28 @@ public class MultiFileItem extends ComponentList {
public ObservableList<FileChooser.ExtensionFilter> getExtensionFilters() { public ObservableList<FileChooser.ExtensionFilter> getExtensionFilters() {
return extensionFilters; return extensionFilters;
} }
public T getSelectedData() {
return selectedData.get();
}
public ObjectProperty<T> selectedDataProperty() {
return selectedData;
}
public void setSelectedData(T selectedData) {
this.selectedData.set(selectedData);
}
public T getFallbackData() {
return fallbackData.get();
}
public ObjectProperty<T> fallbackDataProperty() {
return fallbackData;
}
public void setFallbackData(T fallbackData) {
this.fallbackData.set(fallbackData);
}
} }