diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/game/HMCLGameRepository.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/game/HMCLGameRepository.kt
index 8ccd8c080..4d8f3b552 100644
--- a/HMCL/src/main/kotlin/org/jackhuang/hmcl/game/HMCLGameRepository.kt
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/game/HMCLGameRepository.kt
@@ -56,6 +56,7 @@ class HMCLGameRepository(val profile: Profile, baseDirectory: File)
return when (vs.gameDirType) {
EnumGameDirectory.VERSION_FOLDER -> getVersionRoot(id)
EnumGameDirectory.ROOT_FOLDER -> super.getRunDirectory(id)
+ EnumGameDirectory.CUSTOM -> File(vs.gameDir)
}
}
}
diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/EnumGameDirectory.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/EnumGameDirectory.kt
index c3fff72c1..fc2447500 100644
--- a/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/EnumGameDirectory.kt
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/EnumGameDirectory.kt
@@ -19,5 +19,6 @@ package org.jackhuang.hmcl.setting
enum class EnumGameDirectory {
ROOT_FOLDER,
- VERSION_FOLDER
+ VERSION_FOLDER,
+ CUSTOM
}
\ No newline at end of file
diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/VersionSetting.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/VersionSetting.kt
index 182026c02..b86d9f43b 100644
--- a/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/VersionSetting.kt
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/setting/VersionSetting.kt
@@ -166,9 +166,15 @@ class VersionSetting() {
* 0 - .minecraft
* 1 - .minecraft/versions/<version>/
*/
- val gameDirTypeProperty = ImmediateObjectProperty(this, "gameDirTypeProperty", EnumGameDirectory.ROOT_FOLDER)
+ val gameDirTypeProperty = ImmediateObjectProperty(this, "gameDirType", EnumGameDirectory.ROOT_FOLDER)
var gameDirType: EnumGameDirectory by gameDirTypeProperty
+ /**
+ * Your custom gameDir
+ */
+ val gameDirProperty = ImmediateStringProperty(this, "gameDir", "")
+ var gameDir: String by gameDirProperty
+
// launcher settings
/**
@@ -220,6 +226,7 @@ class VersionSetting() {
widthProperty.addListener(listener)
heightProperty.addListener(listener)
gameDirTypeProperty.addListener(listener)
+ gameDirProperty.addListener(listener)
launcherVisibilityProperty.addListener(listener)
}
@@ -272,6 +279,7 @@ class VersionSetting() {
addProperty("notCheckGame", src.notCheckGame)
addProperty("noCommon", src.noCommon)
addProperty("showLogs", src.showLogs)
+ addProperty("gameDir", src.gameDir)
addProperty("launcherVisibility", src.launcherVisibility.ordinal)
addProperty("gameDirType", src.gameDirType.ordinal)
}
@@ -299,6 +307,7 @@ class VersionSetting() {
serverIp = json["serverIp"]?.asString ?: ""
java = json["java"]?.asString ?: ""
wrapper = json["wrapper"]?.asString ?: ""
+ gameDir = json["gameDir"]?.asString ?: ""
fullscreen = json["fullscreen"]?.asBoolean ?: false
noJVMArgs = json["noJVMArgs"]?.asBoolean ?: false
notCheckGame = json["notCheckGame"]?.asBoolean ?: false
diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/SVG.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/SVG.kt
index 55d0e045c..183c08b7e 100644
--- a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/SVG.kt
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/SVG.kt
@@ -61,4 +61,5 @@ object SVG {
fun launch(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M1008 6.286q18.857 13.714 15.429 36.571l-146.286 877.714q-2.857 16.571-18.286 25.714-8 4.571-17.714 4.571-6.286 0-13.714-2.857l-258.857-105.714-138.286 168.571q-10.286 13.143-28 13.143-7.429 0-12.571-2.286-10.857-4-17.429-13.429t-6.571-20.857v-199.429l493.714-605.143-610.857 528.571-225.714-92.571q-21.143-8-22.857-31.429-1.143-22.857 18.286-33.714l950.857-548.571q8.571-5.143 18.286-5.14311.429 0 20.571 6.286z", fill, width, height)
fun pencil(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M20.71,4.04C21.1,3.65 21.1,3 20.71,2.63L18.37,0.29C18,-0.1 17.35,-0.1 16.96,0.29L15,2.25L18.75,6M17.75,7L14,3.25L4,13.25V17H7.75L17.75,7Z", fill, width, height)
fun refresh(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z", fill, width, height)
+ fun folderOpen(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z", fill, width, height)
}
\ No newline at end of file
diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/VersionSettingsController.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/VersionSettingsController.kt
index 1de521e5a..b1831579f 100644
--- a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/VersionSettingsController.kt
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/VersionSettingsController.kt
@@ -33,11 +33,13 @@ import javafx.scene.layout.VBox
import javafx.stage.DirectoryChooser
import javafx.stage.FileChooser
import org.jackhuang.hmcl.i18n
+import org.jackhuang.hmcl.setting.EnumGameDirectory
import org.jackhuang.hmcl.setting.Profile
import org.jackhuang.hmcl.setting.VersionSetting
import org.jackhuang.hmcl.task.Scheduler
import org.jackhuang.hmcl.task.task
import org.jackhuang.hmcl.ui.construct.ComponentList
+import org.jackhuang.hmcl.ui.construct.MultiFileItem
import org.jackhuang.hmcl.ui.construct.NumberValidator
import org.jackhuang.hmcl.util.JavaVersion
import org.jackhuang.hmcl.util.OS
@@ -55,20 +57,15 @@ class VersionSettingsController {
@FXML lateinit var txtWrapper: JFXTextField
@FXML lateinit var txtPrecallingCommand: JFXTextField
@FXML lateinit var txtServerIP: JFXTextField
- @FXML lateinit var txtJavaDir: JFXTextField
@FXML lateinit var advancedSettingsPane: ComponentList
@FXML lateinit var cboLauncherVisibility: JFXComboBox<*>
- @FXML lateinit var cboRunDirectory: JFXComboBox<*>
@FXML lateinit var chkFullscreen: JFXCheckBox
@FXML lateinit var lblPhysicalMemory: Label
@FXML lateinit var chkNoJVMArgs: JFXToggleButton
@FXML lateinit var chkNoCommon: JFXToggleButton
@FXML lateinit var chkNoGameCheck: JFXToggleButton
- @FXML lateinit var componentJava: ComponentList
- @FXML lateinit var javaPane: VBox
- @FXML lateinit var javaPaneCustom: BorderPane
- @FXML lateinit var radioCustom: JFXRadioButton
- @FXML lateinit var btnJavaSelect: JFXButton
+ @FXML lateinit var javaItem: MultiFileItem
+ @FXML lateinit var gameDirItem: MultiFileItem
@FXML lateinit var chkShowLogs: JFXToggleButton
@FXML lateinit var btnIconSelection: JFXButton
@FXML lateinit var iconView: ImageView
@@ -76,9 +73,6 @@ class VersionSettingsController {
lateinit var profile: Profile
lateinit var versionId: String
- val javaGroup = ToggleGroup()
-
-
fun initialize() {
lblPhysicalMemory.text = i18n("settings.physical_memory") + ": ${OS.TOTAL_MEMORY}MB"
@@ -88,7 +82,6 @@ class VersionSettingsController {
//txtJavaDir.limitWidth(limit)
txtMaxMemory.limitWidth(limit)
cboLauncherVisibility.limitWidth(limit)
- cboRunDirectory.limitWidth(limit)
val limitHeight = 10.0
chkNoJVMArgs.limitHeight(limitHeight)
@@ -107,37 +100,18 @@ class VersionSettingsController {
txtMetaspace.setValidators(validator(true))
txtMetaspace.setValidateWhileTextChanged()
- javaPaneCustom.limitHeight(20.0)
- radioCustom.toggleGroup = javaGroup
- txtJavaDir.disableProperty().bind(radioCustom.selectedProperty().not())
- btnJavaSelect.disableProperty().bind(radioCustom.selectedProperty().not())
-
task {
- val list = mutableListOf()
- list += createJavaPane(JavaVersion.fromCurrentEnvironment(), javaGroup)
- JavaVersion.getJREs().values.forEach { javaVersion ->
- list += createJavaPane(javaVersion, javaGroup)
+ it["list"] = JavaVersion.getJREs().values.map { javaVersion ->
+ javaItem.createChildren(javaVersion.longVersion, javaVersion.binary.absolutePath, javaVersion)
}
- list += javaPaneCustom
- it["list"] = list
}.subscribe(Scheduler.JAVAFX) {
- javaPane.children.setAll(it.get>("list"))
+ javaItem.loadChildren(it.get>("list"))
}
- }
- private fun createJavaPane(java: JavaVersion, group: ToggleGroup): Pane {
- return BorderPane().apply {
- style = "-fx-padding: 3;"
- limitHeight(20.0)
- left = JFXRadioButton(java.longVersion).apply {
- toggleGroup = group
- userData = java
- }
- right = Label(java.binary.absolutePath).apply {
- styleClass += "subtitle-label"
- style += "-fx-font-size: 10;"
- }
- }
+ gameDirItem.loadChildren(listOf(
+ gameDirItem.createChildren(i18n("advancedsettings.game_dir.default"), userData = EnumGameDirectory.ROOT_FOLDER),
+ gameDirItem.createChildren(i18n("advancedsettings.game_dir.independent"), userData = EnumGameDirectory.VERSION_FOLDER)
+ ))
}
fun loadVersionSetting(profile: Profile, versionId: String, version: VersionSetting) {
@@ -162,13 +136,13 @@ class VersionSettingsController {
javaDirProperty.unbind()
showLogsProperty.unbind()
unbindEnum(cboLauncherVisibility)
- unbindEnum(cboRunDirectory)
}
bindInt(txtWidth, version.widthProperty)
bindInt(txtHeight, version.heightProperty)
bindInt(txtMaxMemory, version.maxMemoryProperty)
- bindString(txtJavaDir, version.javaDirProperty)
+ bindString(javaItem.txtCustom, version.javaDirProperty)
+ bindString(gameDirItem.txtCustom, version.gameDirProperty)
bindString(txtJVMArgs, version.javaArgsProperty)
bindString(txtGameArgs, version.minecraftArgsProperty)
bindString(txtMetaspace, version.permSizeProperty)
@@ -176,7 +150,6 @@ class VersionSettingsController {
bindString(txtPrecallingCommand, version.precalledCommandProperty)
bindString(txtServerIP, version.serverIpProperty)
bindEnum(cboLauncherVisibility, version.launcherVisibilityProperty)
- bindEnum(cboRunDirectory, version.gameDirTypeProperty)
bindBoolean(chkFullscreen, version.fullscreenProperty)
bindBoolean(chkNoGameCheck, version.notCheckGameProperty)
bindBoolean(chkNoCommon, version.noCommonProperty)
@@ -184,29 +157,30 @@ class VersionSettingsController {
val javaGroupKey = "java_group.listener"
@Suppress("UNCHECKED_CAST")
- if (javaGroup.properties.containsKey(javaGroupKey))
- javaGroup.selectedToggleProperty().removeListener(javaGroup.properties[javaGroupKey] as ChangeListener)
+ (javaItem.group.properties[javaGroupKey] as? ChangeListener?)
+ ?.run(javaItem.group.selectedToggleProperty()::removeListener)
var flag = false
var defaultToggle: JFXRadioButton? = null
- for (toggle in javaGroup.toggles)
- if (toggle is JFXRadioButton)
- if (toggle.userData == version.javaVersion) {
- toggle.isSelected = true
- flag = true
- } else if (toggle.userData == JavaVersion.fromCurrentEnvironment()) {
- defaultToggle = toggle
- }
+ var customToggle = javaItem.radioCustom
+ javaItem.group.toggles.filter { it is JFXRadioButton }.forEach { toggle ->
+ if (toggle.userData == version.javaVersion) {
+ toggle.isSelected = true
+ flag = true
+ } else if (toggle.userData == JavaVersion.fromCurrentEnvironment()) {
+ defaultToggle = toggle as JFXRadioButton
+ }
+ }
val listener = ChangeListener { _, _, newValue ->
- if (newValue == radioCustom) { // Custom
+ if (newValue == javaItem.radioCustom) { // Custom
version.java = "Custom"
} else {
version.java = ((newValue as JFXRadioButton).userData as JavaVersion).longVersion
}
}
- javaGroup.properties[javaGroupKey] = listener
- javaGroup.selectedToggleProperty().addListener(listener)
+ javaItem.group.properties[javaGroupKey] = listener
+ javaItem.group.selectedToggleProperty().addListener(listener)
if (!flag) {
defaultToggle?.isSelected = true
@@ -216,6 +190,30 @@ class VersionSettingsController {
version.javaProperty.setChangedListener { initJavaSubtitle(version) }
initJavaSubtitle(version)
+ val gameDirKey = "game_dir.listener"
+ @Suppress("UNCHECKED_CAST")
+ (gameDirItem.group.properties[gameDirKey] as? ChangeListener?)
+ ?.run(gameDirItem.group.selectedToggleProperty()::removeListener)
+
+ gameDirItem.group.toggles.filter { it is JFXRadioButton }.forEach { toggle ->
+ if (toggle.userData == version.gameDirType) {
+ toggle.isSelected = true
+ flag = true
+ }
+ }
+
+ gameDirItem.radioCustom.userData = EnumGameDirectory.CUSTOM
+
+ val gameDirListener = ChangeListener { _, _, newValue ->
+ version.gameDirType = (newValue as JFXRadioButton).userData as EnumGameDirectory
+ }
+ gameDirItem.group.properties[gameDirKey] = gameDirListener
+ gameDirItem.group.selectedToggleProperty().addListener(gameDirListener)
+
+ version.gameDirProperty.setChangedListener { initGameDirSubtitle(version) }
+ version.gameDirTypeProperty.setChangedListener { initGameDirSubtitle(version) }
+ initGameDirSubtitle(version)
+
lastVersionSetting = version
loadIcon()
@@ -223,7 +221,11 @@ class VersionSettingsController {
private fun initJavaSubtitle(version: VersionSetting) {
task { it["java"] = version.javaVersion }
- .subscribe(task(Scheduler.JAVAFX) { componentJava.subtitle = it.get("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
+ .subscribe(task(Scheduler.JAVAFX) { javaItem.subtitle = it.get("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
+ }
+
+ private fun initGameDirSubtitle(version: VersionSetting) {
+ gameDirItem.subtitle = profile.repository.getRunDirectory(versionId).absolutePath
}
fun onShowAdvanced() {
@@ -233,14 +235,6 @@ class VersionSettingsController {
rootPane.children.remove(advancedSettingsPane)
}
- fun onExploreJavaDir() {
- val chooser = DirectoryChooser()
- chooser.title = i18n("settings.choose_javapath")
- val selectedDir = chooser.showDialog(Controllers.stage)
- if (selectedDir != null)
- txtJavaDir.text = selectedDir.absolutePath
- }
-
fun onExploreIcon() {
val chooser = FileChooser()
chooser.extensionFilters += FileChooser.ExtensionFilter("Image", "*.png")
diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/ComponentList.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/ComponentList.kt
index 5459821f0..caa06e98b 100644
--- a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/ComponentList.kt
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/ComponentList.kt
@@ -32,9 +32,9 @@ import kotlin.collections.plusAssign
import kotlin.collections.set
@DefaultProperty("content")
-class ComponentList: StackPane() {
+open class ComponentList: StackPane() {
- val vbox: VBox
+ val vbox = VBox()
val content: ObservableList = FXCollections.observableArrayList().apply {
addListener { change: ListChangeListener.Change ->
@@ -47,8 +47,6 @@ class ComponentList: StackPane() {
}
init {
- vbox = VBox().apply {
- }
children.setAll(vbox)
styleClass += "options-list"
diff --git a/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/MultiFileItem.kt b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/MultiFileItem.kt
new file mode 100644
index 000000000..d316acde8
--- /dev/null
+++ b/HMCL/src/main/kotlin/org/jackhuang/hmcl/ui/construct/MultiFileItem.kt
@@ -0,0 +1,111 @@
+/*
+ * Hello Minecraft! Launcher.
+ * Copyright (C) 2017 huangyuhui
+ *
+ * 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.ui.construct
+
+import com.jfoenix.controls.JFXButton
+import com.jfoenix.controls.JFXRadioButton
+import com.jfoenix.controls.JFXTextField
+import javafx.beans.property.SimpleStringProperty
+import javafx.geometry.Pos
+import javafx.scene.Node
+import javafx.scene.control.Label
+import javafx.scene.control.ToggleGroup
+import javafx.scene.layout.BorderPane
+import javafx.scene.layout.HBox
+import javafx.scene.layout.VBox
+import javafx.stage.DirectoryChooser
+import org.jackhuang.hmcl.i18n
+import org.jackhuang.hmcl.ui.Controllers
+import org.jackhuang.hmcl.ui.SVG
+import org.jackhuang.hmcl.ui.limitHeight
+import org.jackhuang.hmcl.util.*
+
+class MultiFileItem : ComponentList() {
+ val customTextProperty = SimpleStringProperty(this, "customText", "Custom")
+ var customText by customTextProperty
+
+ val chooserTitleProperty = SimpleStringProperty(this, "chooserTitle", "Select a file")
+ var chooserTitle by chooserTitleProperty
+
+ val group = ToggleGroup()
+ val txtCustom = JFXTextField().apply {
+ BorderPane.setAlignment(this, Pos.CENTER_RIGHT)
+ }
+ val btnSelect = JFXButton().apply {
+ graphic = SVG.folderOpen("black", 15.0, 15.0)
+ setOnMouseClicked {
+ // TODO
+ }
+ }
+ val radioCustom = JFXRadioButton().apply {
+ textProperty().bind(customTextProperty)
+ toggleGroup = group
+ }
+ val custom = BorderPane().apply {
+ left = radioCustom
+ style = "-fx-padding: 3;"
+ right = HBox().apply {
+ spacing = 3.0
+ children += txtCustom
+ children += btnSelect
+ }
+ limitHeight(20.0)
+ }
+
+ val pane = VBox().apply {
+ style = "-fx-padding: 0 0 10 0;"
+ spacing = 8.0
+ children += custom
+ }
+
+ init {
+ addChildren(pane)
+
+ txtCustom.disableProperty().bind(radioCustom.selectedProperty().not())
+ btnSelect.disableProperty().bind(radioCustom.selectedProperty().not())
+ }
+
+ @JvmOverloads
+ fun createChildren(title: String, subtitle: String = "", userData: Any? = null): Node {
+ return BorderPane().apply {
+ style = "-fx-padding: 3;"
+ limitHeight(20.0)
+ left = JFXRadioButton(title).apply {
+ toggleGroup = group
+ this.userData = userData
+ }
+ right = Label(subtitle).apply {
+ styleClass += "subtitle-label"
+ style += "-fx-font-size: 10;"
+ }
+ }
+ }
+
+ fun loadChildren(list: Collection) {
+ pane.children.setAll(list)
+ pane.children += custom
+ }
+
+ fun onExploreJavaDir() {
+ val chooser = DirectoryChooser()
+ chooser.title = i18n(chooserTitle)
+ val selectedDir = chooser.showDialog(Controllers.stage)
+ if (selectedDir != null)
+ txtCustom.text = selectedDir.absolutePath
+ }
+}
\ No newline at end of file
diff --git a/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml b/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml
index 1c8b27ac5..e100b8ed5 100644
--- a/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml
+++ b/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml
@@ -8,6 +8,7 @@
+
@@ -37,26 +38,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -88,22 +74,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/launch/DefaultLauncher.kt b/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/launch/DefaultLauncher.kt
index 1ed031fb7..0e10f8200 100644
--- a/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/launch/DefaultLauncher.kt
+++ b/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/launch/DefaultLauncher.kt
@@ -163,7 +163,7 @@ open class DefaultLauncher(repository: GameRepository, versionId: String, accoun
}
// Optional Minecraft arguments
- if (options.height != null && options.width != null) {
+ if (options.height != null && options.height != 0 && options.width != null && options.width != 0) {
res.add("--height")
res.add(options.height.toString())
res.add("--width")
diff --git a/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/JavaVersion.kt b/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/JavaVersion.kt
index 82ab5512f..9e2240d49 100644
--- a/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/JavaVersion.kt
+++ b/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/JavaVersion.kt
@@ -149,6 +149,7 @@ data class JavaVersion internal constructor(
if (javas != null)
throw IllegalStateException("JavaVersions have already been initialized.")
val temp = mutableMapOf()
+ temp += currentJava.longVersion to currentJava
(when (OS.CURRENT_OS) {
OS.WINDOWS -> queryWindows()
OS.OSX -> queryMacintosh()
diff --git a/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/Lib.kt b/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/Lib.kt
index 9af969dab..866616715 100644
--- a/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/Lib.kt
+++ b/HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/Lib.kt
@@ -33,4 +33,12 @@ fun ObservableList.onChange(op: (ListChangeListener.Change) -> Uni
addListener(ListChangeListener { op(it) })
}
-fun ObservableValue<*>.onInvalidated(op: () -> T) = apply { addListener { _ -> op() } }
\ No newline at end of file
+fun ObservableValue<*>.onInvalidated(op: () -> T) = apply { addListener { _ -> op() } }
+
+fun ObservableValue.setOnChangeListener(properties: MutableMap, key: String = "changeListener", changeListener: ChangeListener) {
+ @Suppress("UNCHECKED_CAST")
+ if (properties.containsKey(key))
+ removeListener(properties[key] as ChangeListener)
+ properties[key] = changeListener
+ addListener(changeListener)
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 6a461dda3..7a3265ee9 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f67fc4b3a..f16d26666 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Jul 19 17:02:19 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.0.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
diff --git a/gradlew b/gradlew
index d9116bf59..cccdd3d51 100644
--- a/gradlew
+++ b/gradlew
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -155,7 +155,7 @@ if $cygwin ; then
fi
# Escape application args
-save ( ) {
+save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
@@ -164,7 +164,7 @@ APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-# by default we should be in the correct project dir, but when execute from Finder on Mac, the cwd is wrong
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
diff --git a/gradlew.bat b/gradlew.bat
index f74b6cd90..f9553162f 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -5,7 +5,7 @@
@rem
@rem ##########################################################################
-@rem Set local scope for the variables then windows NT shell
+@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
@@ -69,7 +69,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
-@rem End local scope for the variables then windows NT shell
+@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail