mirror of
https://github.com/SKCraft/Launcher.git
synced 2025-02-15 01:31:22 +01:00
Add instance settings dialog
This commit is contained in:
parent
e12eec29b5
commit
faa1bc9a38
@ -5,26 +5,10 @@ import com.skcraft.launcher.launch.JavaRuntime;
|
||||
import com.skcraft.launcher.launch.MemorySettings;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class InstanceSettings {
|
||||
private JavaRuntime runtime;
|
||||
private MemorySettings memorySettings;
|
||||
private String customJvmArgs;
|
||||
|
||||
/**
|
||||
* @return Empty optional if there is no custom runtime set, present optional if there is.
|
||||
*/
|
||||
public Optional<JavaRuntime> getRuntime() {
|
||||
return Optional.ofNullable(runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Empty optional if there are no custom memory settings, present optional if there are.
|
||||
*/
|
||||
public Optional<MemorySettings> getMemorySettings() {
|
||||
return Optional.ofNullable(memorySettings);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,153 @@
|
||||
package com.skcraft.launcher.dialog;
|
||||
|
||||
import com.skcraft.launcher.Instance;
|
||||
import com.skcraft.launcher.InstanceSettings;
|
||||
import com.skcraft.launcher.dialog.component.BetterComboBox;
|
||||
import com.skcraft.launcher.launch.JavaRuntime;
|
||||
import com.skcraft.launcher.launch.JavaRuntimeFinder;
|
||||
import com.skcraft.launcher.launch.MemorySettings;
|
||||
import com.skcraft.launcher.persistence.Persistence;
|
||||
import com.skcraft.launcher.swing.FormPanel;
|
||||
import com.skcraft.launcher.swing.LinedBoxPanel;
|
||||
import com.skcraft.launcher.util.SharedLocale;
|
||||
import lombok.extern.java.Log;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
@Log
|
||||
public class InstanceSettingsDialog extends JDialog {
|
||||
private final InstanceSettings settings;
|
||||
|
||||
private final LinedBoxPanel formsPanel = new LinedBoxPanel(false);
|
||||
private final FormPanel memorySettingsPanel = new FormPanel();
|
||||
private final JCheckBox enableMemorySettings = new JCheckBox(SharedLocale.tr("instance.options.customMemory"));
|
||||
private final JSpinner minMemorySpinner = new JSpinner();
|
||||
private final JSpinner maxMemorySpinner = new JSpinner();
|
||||
|
||||
private final JCheckBox enableCustomRuntime = new JCheckBox(SharedLocale.tr("instance.options.customJava"));
|
||||
private final FormPanel runtimePanel = new FormPanel();
|
||||
private final JComboBox<JavaRuntime> javaRuntimeBox = new BetterComboBox<>();
|
||||
private final JTextField javaArgsBox = new JTextField();
|
||||
|
||||
private final LinedBoxPanel buttonsPanel = new LinedBoxPanel(true);
|
||||
private final JButton okButton = new JButton(SharedLocale.tr("button.save"));
|
||||
private final JButton cancelButton = new JButton(SharedLocale.tr("button.cancel"));
|
||||
|
||||
private boolean saved = false;
|
||||
|
||||
public InstanceSettingsDialog(Window owner, InstanceSettings settings) {
|
||||
super(owner);
|
||||
this.settings = settings;
|
||||
|
||||
setTitle(SharedLocale.tr("instance.options.title"));
|
||||
setModalityType(DEFAULT_MODALITY_TYPE);
|
||||
initComponents();
|
||||
setSize(new Dimension(400, 500));
|
||||
setLocationRelativeTo(owner);
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
memorySettingsPanel.addRow(enableMemorySettings);
|
||||
memorySettingsPanel.addRow(new JLabel(SharedLocale.tr("options.minMemory")), minMemorySpinner);
|
||||
memorySettingsPanel.addRow(new JLabel(SharedLocale.tr("options.maxMemory")), maxMemorySpinner);
|
||||
|
||||
// TODO: Do we keep this list centrally somewhere? Or is actively refreshing good?
|
||||
JavaRuntime[] javaRuntimes = JavaRuntimeFinder.getAvailableRuntimes().toArray(new JavaRuntime[0]);
|
||||
javaRuntimeBox.setModel(new DefaultComboBoxModel<>(javaRuntimes));
|
||||
|
||||
runtimePanel.addRow(enableCustomRuntime);
|
||||
runtimePanel.addRow(new JLabel(SharedLocale.tr("options.jvmPath")), javaRuntimeBox);
|
||||
runtimePanel.addRow(new JLabel(SharedLocale.tr("options.jvmArguments")), javaArgsBox);
|
||||
|
||||
okButton.setMargin(new Insets(0, 10, 0, 10));
|
||||
buttonsPanel.addGlue();
|
||||
buttonsPanel.addElement(okButton);
|
||||
buttonsPanel.addElement(cancelButton);
|
||||
|
||||
enableMemorySettings.addActionListener(e -> {
|
||||
if (enableMemorySettings.isSelected()) {
|
||||
settings.setMemorySettings(new MemorySettings());
|
||||
} else {
|
||||
settings.setMemorySettings(null);
|
||||
}
|
||||
|
||||
updateComponents();
|
||||
});
|
||||
|
||||
enableCustomRuntime.addActionListener(e -> {
|
||||
runtimePanel.setEnabled(enableCustomRuntime.isSelected());
|
||||
});
|
||||
|
||||
okButton.addActionListener(e -> {
|
||||
save();
|
||||
dispose();
|
||||
});
|
||||
|
||||
cancelButton.addActionListener(e -> dispose());
|
||||
|
||||
formsPanel.addElement(memorySettingsPanel);
|
||||
formsPanel.addElement(runtimePanel);
|
||||
|
||||
add(formsPanel, BorderLayout.NORTH);
|
||||
add(buttonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
private void updateComponents() {
|
||||
if (settings.getMemorySettings() != null) {
|
||||
memorySettingsPanel.setEnabled(true);
|
||||
enableMemorySettings.setSelected(true);
|
||||
|
||||
minMemorySpinner.setValue(settings.getMemorySettings().getMinMemory());
|
||||
maxMemorySpinner.setValue(settings.getMemorySettings().getMaxMemory());
|
||||
} else {
|
||||
memorySettingsPanel.setEnabled(false);
|
||||
enableMemorySettings.setSelected(false);
|
||||
}
|
||||
|
||||
if (settings.getRuntime() != null) {
|
||||
runtimePanel.setEnabled(true);
|
||||
enableCustomRuntime.setSelected(true);
|
||||
} else {
|
||||
runtimePanel.setEnabled(false);
|
||||
enableCustomRuntime.setSelected(false);
|
||||
}
|
||||
|
||||
javaRuntimeBox.setSelectedItem(settings.getRuntime());
|
||||
javaArgsBox.setText(settings.getCustomJvmArgs());
|
||||
}
|
||||
|
||||
private void save() {
|
||||
if (enableMemorySettings.isSelected()) {
|
||||
MemorySettings memorySettings = settings.getMemorySettings();
|
||||
|
||||
memorySettings.setMinMemory((int) minMemorySpinner.getValue());
|
||||
memorySettings.setMaxMemory((int) maxMemorySpinner.getValue());
|
||||
} else {
|
||||
settings.setMemorySettings(null);
|
||||
}
|
||||
|
||||
if (enableCustomRuntime.isSelected()) {
|
||||
settings.setRuntime((JavaRuntime) javaRuntimeBox.getSelectedItem());
|
||||
settings.setCustomJvmArgs(javaArgsBox.getText());
|
||||
} else {
|
||||
settings.setRuntime(null);
|
||||
settings.setCustomJvmArgs(null);
|
||||
}
|
||||
|
||||
saved = true;
|
||||
}
|
||||
|
||||
public static boolean open(Window parent, Instance instance) {
|
||||
InstanceSettingsDialog dialog = new InstanceSettingsDialog(parent, instance.getSettings());
|
||||
dialog.setVisible(true);
|
||||
|
||||
if (dialog.saved) {
|
||||
Persistence.commitAndForget(instance);
|
||||
}
|
||||
|
||||
return dialog.saved;
|
||||
}
|
||||
}
|
@ -241,6 +241,12 @@ public class LauncherFrame extends JFrame {
|
||||
});
|
||||
popup.add(menuItem);
|
||||
|
||||
menuItem = new JMenuItem(SharedLocale.tr("instance.openSettings"));
|
||||
menuItem.addActionListener(e -> {
|
||||
InstanceSettingsDialog.open(this, selected);
|
||||
});
|
||||
popup.add(menuItem);
|
||||
|
||||
popup.addSeparator();
|
||||
|
||||
if (!selected.isUpdatePending()) {
|
||||
|
@ -1,5 +1,9 @@
|
||||
package com.skcraft.launcher.launch;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import com.google.common.base.Objects;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
@ -9,11 +13,22 @@ public class JavaRuntime implements Comparable<JavaRuntime> {
|
||||
private final File dir;
|
||||
private final String version;
|
||||
private final boolean is64Bit;
|
||||
private boolean isMinecraftBundled = false;
|
||||
private boolean isMinecraftBundled = false; // Used only in list sorting & not serialized.
|
||||
|
||||
@JsonValue
|
||||
public File getDir() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static JavaRuntime fromDir(String dir) {
|
||||
return JavaRuntimeFinder.getRuntimeFromPath(dir);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public int getMajorVersion() {
|
||||
if (version == null) {
|
||||
return 0; //
|
||||
return 0; // uhh make this an error?
|
||||
}
|
||||
|
||||
String[] parts = version.split("\\.");
|
||||
@ -29,6 +44,19 @@ public class JavaRuntime implements Comparable<JavaRuntime> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
JavaRuntime that = (JavaRuntime) o;
|
||||
return Objects.equal(dir, that.dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(JavaRuntime o) {
|
||||
if (isMinecraftBundled && !o.isMinecraftBundled) {
|
||||
|
@ -45,7 +45,6 @@ public final class JavaRuntimeFinder {
|
||||
getEntriesFromRegistry(entries, "SOFTWARE\\JavaSoft\\Java Development Kit");
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
Collections.sort(entries);
|
||||
} else if (env.getPlatform() == Platform.LINUX) {
|
||||
launcherDir = new File(System.getenv("HOME"), ".minecraft");
|
||||
|
||||
@ -68,40 +67,39 @@ public final class JavaRuntimeFinder {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (!launcherDir.isDirectory()) {
|
||||
return entries;
|
||||
}
|
||||
|
||||
File runtimes = new File(launcherDir, "runtime");
|
||||
File[] runtimeList = runtimes.listFiles();
|
||||
if (runtimeList == null) {
|
||||
return entries;
|
||||
}
|
||||
if (runtimeList != null) {
|
||||
for (File potential : runtimeList) {
|
||||
if (potential.getName().startsWith("jre-x")) {
|
||||
boolean is64Bit = potential.getName().equals("jre-x64");
|
||||
|
||||
for (File potential : runtimeList) {
|
||||
if (potential.getName().startsWith("jre-x")) {
|
||||
boolean is64Bit = potential.getName().equals("jre-x64");
|
||||
JavaRuntime runtime = new JavaRuntime(potential.getAbsoluteFile(), readVersionFromRelease(potential), is64Bit);
|
||||
runtime.setMinecraftBundled(true);
|
||||
entries.add(runtime);
|
||||
} else {
|
||||
String runtimeName = potential.getName();
|
||||
|
||||
entries.add(new JavaRuntime(potential.getAbsoluteFile(), readVersionFromRelease(potential), is64Bit));
|
||||
} else {
|
||||
String runtimeName = potential.getName();
|
||||
String[] children = potential.list();
|
||||
if (children == null || children.length == 0) continue;
|
||||
String platformName = children[0];
|
||||
|
||||
String[] children = potential.list();
|
||||
if (children == null || children.length == 0) continue;
|
||||
String platformName = children[0];
|
||||
String[] parts = platformName.split("-");
|
||||
if (parts.length < 2) continue;
|
||||
|
||||
String[] parts = platformName.split("-");
|
||||
if (parts.length < 2) continue;
|
||||
String arch = parts[1];
|
||||
boolean is64Bit = arch.equals("x64");
|
||||
|
||||
String arch = parts[1];
|
||||
boolean is64Bit = arch.equals("x64");
|
||||
File javaDir = new File(potential, String.format("%s/%s", platformName, runtimeName));
|
||||
JavaRuntime runtime = new JavaRuntime(javaDir.getAbsoluteFile(), readVersionFromRelease(javaDir), is64Bit);
|
||||
runtime.setMinecraftBundled(true);
|
||||
|
||||
File javaDir = new File(potential, String.format("%s/%s", platformName, runtimeName));
|
||||
|
||||
entries.add(new JavaRuntime(javaDir.getAbsoluteFile(), readVersionFromRelease(javaDir), is64Bit));
|
||||
entries.add(runtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(entries);
|
||||
return entries;
|
||||
}
|
||||
|
||||
@ -127,8 +125,18 @@ public final class JavaRuntimeFinder {
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public static Optional<JavaRuntime> findAnyJavaRuntime() {
|
||||
return getAvailableRuntimes().stream().sorted().findFirst();
|
||||
}
|
||||
|
||||
public static JavaRuntime getRuntimeFromPath(String path) {
|
||||
File target = new File(path);
|
||||
|
||||
if (target.isFile()) {
|
||||
// Probably referring directly to bin/java, back up two levels
|
||||
target = target.getParentFile().getParentFile();
|
||||
}
|
||||
|
||||
{
|
||||
File jre = new File(target, "jre/release");
|
||||
if (jre.isFile()) {
|
||||
|
@ -212,12 +212,14 @@ public class Runner implements Callable<Process>, ProgressObservable {
|
||||
*
|
||||
* @throws IOException on I/O error
|
||||
*/
|
||||
private void addJvmArgs() throws IOException {
|
||||
int minMemory = instance.getSettings().getMemorySettings()
|
||||
private void addJvmArgs() throws IOException, LauncherException {
|
||||
Optional<MemorySettings> memorySettings = Optional.ofNullable(instance.getSettings().getMemorySettings());
|
||||
|
||||
int minMemory = memorySettings
|
||||
.map(MemorySettings::getMinMemory)
|
||||
.orElse(config.getMinMemory());
|
||||
|
||||
int maxMemory = instance.getSettings().getMemorySettings()
|
||||
int maxMemory = memorySettings
|
||||
.map(MemorySettings::getMaxMemory)
|
||||
.orElse(config.getMaxMemory());
|
||||
|
||||
@ -247,14 +249,18 @@ public class Runner implements Callable<Process>, ProgressObservable {
|
||||
builder.setMaxMemory(maxMemory);
|
||||
builder.setPermGen(permGen);
|
||||
|
||||
JavaRuntime selectedRuntime = instance.getSettings().getRuntime()
|
||||
JavaRuntime selectedRuntime = Optional.ofNullable(instance.getSettings().getRuntime())
|
||||
.orElseGet(() -> Optional.ofNullable(versionManifest.getJavaVersion())
|
||||
.flatMap(JavaRuntimeFinder::findBestJavaRuntime)
|
||||
.orElse(config.getJavaRuntime())
|
||||
);
|
||||
String rawJvmPath = selectedRuntime.getDir().getAbsolutePath();
|
||||
if (!Strings.isNullOrEmpty(rawJvmPath)) {
|
||||
builder.tryJvmPath(new File(rawJvmPath));
|
||||
|
||||
// Builder defaults to a found runtime or just the PATH `java` otherwise
|
||||
if (selectedRuntime != null) {
|
||||
String rawJvmPath = selectedRuntime.getDir().getAbsolutePath();
|
||||
if (!Strings.isNullOrEmpty(rawJvmPath)) {
|
||||
builder.tryJvmPath(new File(rawJvmPath));
|
||||
}
|
||||
}
|
||||
|
||||
List<String> flags = builder.getFlags();
|
||||
|
@ -22,6 +22,7 @@ errors.selfUpdateCheckError=Checking for an update to the launcher has failed.
|
||||
|
||||
button.cancel=Cancel
|
||||
button.ok=OK
|
||||
button.save=Save
|
||||
|
||||
options.title = Options
|
||||
options.useProxyCheck = Use following proxy in Minecraft
|
||||
@ -52,6 +53,7 @@ instance.openSaves=View saves
|
||||
instance.openResourcePacks=View resource packs
|
||||
instance.openScreenshots=View screenshots
|
||||
instance.copyAsPath=Copy as path
|
||||
instance.openSettings=Settings...
|
||||
instance.forceUpdate=Force update
|
||||
instance.hardForceUpdate=Hard force update...
|
||||
instance.deleteFiles=Delete files...
|
||||
@ -62,6 +64,10 @@ instance.confirmHardUpdate=A hard force update will delete the contents of confi
|
||||
instance.resettingTitle=Resetting instance...
|
||||
instance.resettingStatus=Resetting ''{0}''...
|
||||
|
||||
instance.options.title=Instance Settings
|
||||
instance.options.customJava=Use a custom Java runtime
|
||||
instance.options.customMemory=Use custom memory settings
|
||||
|
||||
launcher.launch=Launch...
|
||||
launcher.checkForUpdates=Check for updates
|
||||
launcher.options=Options...
|
||||
|
Loading…
Reference in New Issue
Block a user