合并 SettingsPage 与 SettingsView (#4955)

This commit is contained in:
Glavo
2025-12-08 16:45:29 +08:00
committed by GitHub
parent f7f0d55504
commit d2c985491a
2 changed files with 249 additions and 313 deletions

View File

@@ -17,22 +17,40 @@
*/ */
package org.jackhuang.hmcl.ui.main; package org.jackhuang.hmcl.ui.main;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXRadioButton;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.InvalidationListener; import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener; import javafx.beans.WeakInvalidationListener;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.*;
import javafx.scene.text.TextAlignment;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.setting.Settings;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.construct.ComponentList;
import org.jackhuang.hmcl.ui.construct.ComponentSublist;
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType; import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
import org.jackhuang.hmcl.ui.construct.OptionToggleButton;
import org.jackhuang.hmcl.upgrade.RemoteVersion; import org.jackhuang.hmcl.upgrade.RemoteVersion;
import org.jackhuang.hmcl.upgrade.UpdateChannel; import org.jackhuang.hmcl.upgrade.UpdateChannel;
import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateChecker;
import org.jackhuang.hmcl.upgrade.UpdateHandler; import org.jackhuang.hmcl.upgrade.UpdateHandler;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.i18n.SupportedLocale; import org.jackhuang.hmcl.util.i18n.SupportedLocale;
import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.IOUtils; import org.jackhuang.hmcl.util.io.IOUtils;
@@ -45,6 +63,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -52,33 +71,88 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import static org.jackhuang.hmcl.util.Lang.thread; import static org.jackhuang.hmcl.util.Lang.thread;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor; import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
import static org.jackhuang.hmcl.util.logging.Logger.LOG; import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class SettingsPage extends SettingsView { public final class SettingsPage extends ScrollPane {
private InvalidationListener updateListener; @SuppressWarnings("FieldCanBeLocal")
private final ToggleGroup updateChannelGroup;
@SuppressWarnings("FieldCanBeLocal")
private final InvalidationListener updateListener;
public SettingsPage() { public SettingsPage() {
FXUtils.smoothScrolling(scroll); this.setFitToWidth(true);
// ==== Languages ==== VBox rootPane = new VBox();
cboLanguage.getItems().setAll(SupportedLocale.getSupportedLocales()); rootPane.setPadding(new Insets(32, 10, 32, 10));
selectedItemPropertyFor(cboLanguage).bindBidirectional(config().localizationProperty()); this.setContent(rootPane);
FXUtils.smoothScrolling(this);
disableAutoGameOptionsPane.selectedProperty().bindBidirectional(config().disableAutoGameOptionsProperty()); ComponentList settingsPane = new ComponentList();
// ==== {
{
StackPane sponsorPane = new StackPane();
sponsorPane.setCursor(Cursor.HAND);
FXUtils.onClicked(sponsorPane, this::onSponsor);
sponsorPane.setPadding(new Insets(8, 0, 8, 0));
fileCommonLocation.selectedDataProperty().bindBidirectional(config().commonDirTypeProperty()); GridPane gridPane = new GridPane();
fileCommonLocationSublist.subtitleProperty().bind(
Bindings.createObjectBinding(() -> Optional.ofNullable(Settings.instance().getCommonDirectory())
.orElse(i18n("launcher.cache_directory.disabled")),
config().commonDirectoryProperty(), config().commonDirTypeProperty()));
// ==== Update ==== ColumnConstraints col = new ColumnConstraints();
col.setHgrow(Priority.SOMETIMES);
col.setMaxWidth(Double.POSITIVE_INFINITY);
gridPane.getColumnConstraints().setAll(col);
RowConstraints row = new RowConstraints();
row.setMinHeight(Double.NEGATIVE_INFINITY);
row.setValignment(VPos.TOP);
row.setVgrow(Priority.SOMETIMES);
gridPane.getRowConstraints().setAll(row);
{
Label label = new Label(i18n("sponsor.hmcl"));
label.setWrapText(true);
label.setTextAlignment(TextAlignment.JUSTIFY);
GridPane.setRowIndex(label, 0);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
sponsorPane.getChildren().setAll(gridPane);
settingsPane.getContent().add(sponsorPane);
}
{
ComponentSublist updatePane = new ComponentSublist();
updatePane.setTitle(i18n("update"));
updatePane.setHasSubtitle(true);
final Label lblUpdate;
final Label lblUpdateSub;
{
VBox headerLeft = new VBox();
lblUpdate = new Label(i18n("update"));
lblUpdate.getStyleClass().add("title-label");
lblUpdateSub = new Label();
lblUpdateSub.getStyleClass().add("subtitle-label");
headerLeft.getChildren().setAll(lblUpdate, lblUpdateSub);
updatePane.setHeaderLeft(headerLeft);
}
{
JFXButton btnUpdate = new JFXButton();
btnUpdate.setOnAction(e -> onUpdate());
btnUpdate.getStyleClass().add("toggle-icon4");
btnUpdate.setGraphic(SVG.UPDATE.createIcon(20));
FXUtils.installFastTooltip(btnUpdate, i18n("update.tooltip")); FXUtils.installFastTooltip(btnUpdate, i18n("update.tooltip"));
updateListener = any -> { updateListener = any -> {
btnUpdate.setVisible(UpdateChecker.isOutdated()); btnUpdate.setVisible(UpdateChecker.isOutdated());
@@ -107,24 +181,144 @@ public final class SettingsPage extends SettingsView {
UpdateChecker.checkingUpdateProperty().addListener(new WeakInvalidationListener(updateListener)); UpdateChecker.checkingUpdateProperty().addListener(new WeakInvalidationListener(updateListener));
updateListener.invalidated(null); updateListener.invalidated(null);
ToggleGroup updateChannelGroup = new ToggleGroup(); updatePane.setHeaderRight(btnUpdate);
}
{
VBox content = new VBox();
content.setSpacing(8);
JFXRadioButton chkUpdateStable = new JFXRadioButton(i18n("update.channel.stable"));
JFXRadioButton chkUpdateDev = new JFXRadioButton(i18n("update.channel.dev"));
updateChannelGroup = new ToggleGroup();
chkUpdateDev.setToggleGroup(updateChannelGroup); chkUpdateDev.setToggleGroup(updateChannelGroup);
chkUpdateDev.setUserData(UpdateChannel.DEVELOPMENT); chkUpdateDev.setUserData(UpdateChannel.DEVELOPMENT);
chkUpdateStable.setToggleGroup(updateChannelGroup); chkUpdateStable.setToggleGroup(updateChannelGroup);
chkUpdateStable.setUserData(UpdateChannel.STABLE); chkUpdateStable.setUserData(UpdateChannel.STABLE);
Label noteWrapper = new Label(i18n("update.note"));
VBox.setMargin(noteWrapper, new Insets(10, 0, 0, 0));
content.getChildren().setAll(chkUpdateStable, chkUpdateDev, noteWrapper);
updatePane.getContent().add(content);
}
settingsPane.getContent().add(updatePane);
}
{
OptionToggleButton previewPane = new OptionToggleButton();
previewPane.setTitle(i18n("update.preview"));
previewPane.selectedProperty().bindBidirectional(config().acceptPreviewUpdateProperty());
FXUtils.installFastTooltip(previewPane, i18n("update.preview.tooltip"));
ObjectProperty<UpdateChannel> updateChannel = selectedItemPropertyFor(updateChannelGroup, UpdateChannel.class); ObjectProperty<UpdateChannel> updateChannel = selectedItemPropertyFor(updateChannelGroup, UpdateChannel.class);
updateChannel.set(UpdateChannel.getChannel()); updateChannel.set(UpdateChannel.getChannel());
InvalidationListener checkUpdateListener = e -> { InvalidationListener checkUpdateListener = e -> {
UpdateChecker.requestCheckUpdate(updateChannel.get(), previewPane.isSelected()); UpdateChecker.requestCheckUpdate(updateChannel.get(), previewPane.isSelected());
}; };
updateChannel.addListener(checkUpdateListener); updateChannel.addListener(checkUpdateListener);
previewPane.selectedProperty().addListener(checkUpdateListener); previewPane.selectedProperty().addListener(checkUpdateListener);
// ====
settingsPane.getContent().add(previewPane);
} }
@Override {
protected void onUpdate() { MultiFileItem<EnumCommonDirectory> fileCommonLocation = new MultiFileItem<>();
fileCommonLocation.selectedDataProperty().bindBidirectional(config().commonDirTypeProperty());
fileCommonLocation.loadChildren(Arrays.asList(
new MultiFileItem.Option<>(i18n("launcher.cache_directory.default"), EnumCommonDirectory.DEFAULT),
new MultiFileItem.FileOption<>(i18n("settings.custom"), EnumCommonDirectory.CUSTOM)
.setChooserTitle(i18n("launcher.cache_directory.choose"))
.setDirectory(true)
.bindBidirectional(config().commonDirectoryProperty())
));
ComponentSublist fileCommonLocationSublist = new ComponentSublist();
fileCommonLocationSublist.getContent().add(fileCommonLocation);
fileCommonLocationSublist.setTitle(i18n("launcher.cache_directory"));
fileCommonLocationSublist.setHasSubtitle(true);
fileCommonLocationSublist.subtitleProperty().bind(
Bindings.createObjectBinding(() -> Optional.ofNullable(Settings.instance().getCommonDirectory())
.orElse(i18n("launcher.cache_directory.disabled")),
config().commonDirectoryProperty(), config().commonDirTypeProperty()));
JFXButton cleanButton = FXUtils.newBorderButton(i18n("launcher.cache_directory.clean"));
cleanButton.setOnAction(e -> clearCacheDirectory());
fileCommonLocationSublist.setHeaderRight(cleanButton);
settingsPane.getContent().add(fileCommonLocationSublist);
}
{
BorderPane languagePane = new BorderPane();
Label left = new Label(i18n("settings.launcher.language"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
languagePane.setLeft(left);
SupportedLocale currentLocale = I18n.getLocale();
JFXComboBox<SupportedLocale> cboLanguage = new JFXComboBox<>();
cboLanguage.setConverter(stringConverter(locale -> {
if (locale.isDefault())
return locale.getDisplayName(currentLocale);
else if (locale.isSameLanguage(currentLocale))
return locale.getDisplayName(locale);
else
return locale.getDisplayName(currentLocale) + " - " + locale.getDisplayName(locale);
}));
cboLanguage.getItems().setAll(SupportedLocale.getSupportedLocales());
selectedItemPropertyFor(cboLanguage).bindBidirectional(config().localizationProperty());
FXUtils.setLimitWidth(cboLanguage, 300);
languagePane.setRight(cboLanguage);
settingsPane.getContent().add(languagePane);
}
{
OptionToggleButton disableAutoGameOptionsPane = new OptionToggleButton();
disableAutoGameOptionsPane.setTitle(i18n("settings.launcher.disable_auto_game_options"));
disableAutoGameOptionsPane.selectedProperty().bindBidirectional(config().disableAutoGameOptionsProperty());
settingsPane.getContent().add(disableAutoGameOptionsPane);
}
{
BorderPane debugPane = new BorderPane();
Label left = new Label(i18n("settings.launcher.debug"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
debugPane.setLeft(left);
JFXButton openLogFolderButton = new JFXButton(i18n("settings.launcher.launcher_log.reveal"));
openLogFolderButton.setOnAction(e -> openLogFolder());
openLogFolderButton.getStyleClass().add("jfx-button-border");
if (LOG.getLogFile() == null)
openLogFolderButton.setDisable(true);
JFXButton logButton = FXUtils.newBorderButton(i18n("settings.launcher.launcher_log.export"));
logButton.setOnAction(e -> onExportLogs());
HBox buttonBox = new HBox();
buttonBox.setSpacing(10);
buttonBox.getChildren().addAll(openLogFolderButton, logButton);
BorderPane.setAlignment(buttonBox, Pos.CENTER_RIGHT);
debugPane.setRight(buttonBox);
settingsPane.getContent().add(debugPane);
}
rootPane.getChildren().add(settingsPane);
}
}
private void openLogFolder() {
FXUtils.openFolder(LOG.getLogFile().getParent());
}
private void onUpdate() {
RemoteVersion target = UpdateChecker.getLatestVersion(); RemoteVersion target = UpdateChecker.getLatestVersion();
if (target == null) { if (target == null) {
return; return;
@@ -168,8 +362,7 @@ public final class SettingsPage extends SettingsView {
} }
} }
@Override private void onExportLogs() {
protected void onExportLogs() {
thread(() -> { thread(() -> {
String nameBase = "hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")); String nameBase = "hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss"));
List<Path> recentLogFiles = LOG.findRecentLogFiles(5); List<Path> recentLogFiles = LOG.findRecentLogFiles(5);
@@ -249,13 +442,11 @@ public final class SettingsPage extends SettingsView {
}); });
} }
@Override private void onSponsor() {
protected void onSponsor() {
FXUtils.openLink("https://github.com/HMCL-dev/HMCL"); FXUtils.openLink("https://github.com/HMCL-dev/HMCL");
} }
@Override private void clearCacheDirectory() {
protected void clearCacheDirectory() {
String commonDirectory = Settings.instance().getCommonDirectory(); String commonDirectory = Settings.instance().getCommonDirectory();
if (commonDirectory != null) { if (commonDirectory != null) {
FileUtils.cleanDirectoryQuietly(Path.of(commonDirectory, "cache")); FileUtils.cleanDirectoryQuietly(Path.of(commonDirectory, "cache"));

View File

@@ -1,255 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
*
* 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 <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.ui.main;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXRadioButton;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import javafx.scene.text.TextAlignment;
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.construct.ComponentList;
import org.jackhuang.hmcl.ui.construct.ComponentSublist;
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
import org.jackhuang.hmcl.ui.construct.OptionToggleButton;
import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.i18n.SupportedLocale;
import java.util.Arrays;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public abstract class SettingsView extends StackPane {
protected final JFXComboBox<SupportedLocale> cboLanguage;
protected final OptionToggleButton disableAutoGameOptionsPane;
protected final MultiFileItem<EnumCommonDirectory> fileCommonLocation;
protected final ComponentSublist fileCommonLocationSublist;
protected final Label lblUpdate;
protected final Label lblUpdateSub;
protected final JFXRadioButton chkUpdateStable;
protected final JFXRadioButton chkUpdateDev;
protected final JFXButton btnUpdate;
protected final OptionToggleButton previewPane;
protected final ScrollPane scroll;
public SettingsView() {
scroll = new ScrollPane();
getChildren().setAll(scroll);
scroll.setStyle("-fx-font-size: 14;");
scroll.setFitToWidth(true);
{
VBox rootPane = new VBox();
rootPane.setPadding(new Insets(32, 10, 32, 10));
{
ComponentList settingsPane = new ComponentList();
{
{
StackPane sponsorPane = new StackPane();
sponsorPane.setCursor(Cursor.HAND);
FXUtils.onClicked(sponsorPane, this::onSponsor);
sponsorPane.setPadding(new Insets(8, 0, 8, 0));
GridPane gridPane = new GridPane();
ColumnConstraints col = new ColumnConstraints();
col.setHgrow(Priority.SOMETIMES);
col.setMaxWidth(Double.POSITIVE_INFINITY);
gridPane.getColumnConstraints().setAll(col);
RowConstraints row = new RowConstraints();
row.setMinHeight(Double.NEGATIVE_INFINITY);
row.setValignment(VPos.TOP);
row.setVgrow(Priority.SOMETIMES);
gridPane.getRowConstraints().setAll(row);
{
Label label = new Label(i18n("sponsor.hmcl"));
label.setWrapText(true);
label.setTextAlignment(TextAlignment.JUSTIFY);
GridPane.setRowIndex(label, 0);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
sponsorPane.getChildren().setAll(gridPane);
settingsPane.getContent().add(sponsorPane);
}
}
{
ComponentSublist updatePane = new ComponentSublist();
updatePane.setTitle(i18n("update"));
updatePane.setHasSubtitle(true);
{
VBox headerLeft = new VBox();
lblUpdate = new Label(i18n("update"));
lblUpdate.getStyleClass().add("title-label");
lblUpdateSub = new Label();
lblUpdateSub.getStyleClass().add("subtitle-label");
headerLeft.getChildren().setAll(lblUpdate, lblUpdateSub);
updatePane.setHeaderLeft(headerLeft);
}
{
btnUpdate = new JFXButton();
btnUpdate.setOnAction(e -> onUpdate());
btnUpdate.getStyleClass().add("toggle-icon4");
btnUpdate.setGraphic(SVG.UPDATE.createIcon(20));
updatePane.setHeaderRight(btnUpdate);
}
{
VBox content = new VBox();
content.setSpacing(8);
chkUpdateStable = new JFXRadioButton(i18n("update.channel.stable"));
chkUpdateDev = new JFXRadioButton(i18n("update.channel.dev"));
Label noteWrapper = new Label(i18n("update.note"));
VBox.setMargin(noteWrapper, new Insets(10, 0, 0, 0));
content.getChildren().setAll(chkUpdateStable, chkUpdateDev, noteWrapper);
updatePane.getContent().add(content);
}
settingsPane.getContent().add(updatePane);
}
{
previewPane = new OptionToggleButton();
previewPane.setTitle(i18n("update.preview"));
previewPane.selectedProperty().bindBidirectional(config().acceptPreviewUpdateProperty());
FXUtils.installFastTooltip(previewPane, i18n("update.preview.tooltip"));
settingsPane.getContent().add(previewPane);
}
{
fileCommonLocation = new MultiFileItem<>();
fileCommonLocationSublist = new ComponentSublist();
fileCommonLocationSublist.getContent().add(fileCommonLocation);
fileCommonLocationSublist.setTitle(i18n("launcher.cache_directory"));
fileCommonLocationSublist.setHasSubtitle(true);
fileCommonLocation.loadChildren(Arrays.asList(
new MultiFileItem.Option<>(i18n("launcher.cache_directory.default"), EnumCommonDirectory.DEFAULT),
new MultiFileItem.FileOption<>(i18n("settings.custom"), EnumCommonDirectory.CUSTOM)
.setChooserTitle(i18n("launcher.cache_directory.choose"))
.setDirectory(true)
.bindBidirectional(config().commonDirectoryProperty())
));
{
JFXButton cleanButton = FXUtils.newBorderButton(i18n("launcher.cache_directory.clean"));
cleanButton.setOnAction(e -> clearCacheDirectory());
fileCommonLocationSublist.setHeaderRight(cleanButton);
}
settingsPane.getContent().add(fileCommonLocationSublist);
}
{
BorderPane languagePane = new BorderPane();
Label left = new Label(i18n("settings.launcher.language"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
languagePane.setLeft(left);
SupportedLocale currentLocale = I18n.getLocale();
cboLanguage = new JFXComboBox<>();
cboLanguage.setConverter(stringConverter(locale -> {
if (locale.isDefault())
return locale.getDisplayName(currentLocale);
else if (locale.isSameLanguage(currentLocale))
return locale.getDisplayName(locale);
else
return locale.getDisplayName(currentLocale) + " - " + locale.getDisplayName(locale);
}));
FXUtils.setLimitWidth(cboLanguage, 300);
languagePane.setRight(cboLanguage);
settingsPane.getContent().add(languagePane);
}
{
disableAutoGameOptionsPane = new OptionToggleButton();
disableAutoGameOptionsPane.setTitle(i18n("settings.launcher.disable_auto_game_options"));
settingsPane.getContent().add(disableAutoGameOptionsPane);
}
{
BorderPane debugPane = new BorderPane();
Label left = new Label(i18n("settings.launcher.debug"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
debugPane.setLeft(left);
JFXButton openLogFolderButton = new JFXButton(i18n("settings.launcher.launcher_log.reveal"));
openLogFolderButton.setOnAction(e -> openLogFolder());
openLogFolderButton.getStyleClass().add("jfx-button-border");
if (LOG.getLogFile() == null)
openLogFolderButton.setDisable(true);
JFXButton logButton = FXUtils.newBorderButton(i18n("settings.launcher.launcher_log.export"));
logButton.setOnAction(e -> onExportLogs());
HBox buttonBox = new HBox();
buttonBox.setSpacing(10);
buttonBox.getChildren().addAll(openLogFolderButton, logButton);
BorderPane.setAlignment(buttonBox, Pos.CENTER_RIGHT);
debugPane.setRight(buttonBox);
settingsPane.getContent().add(debugPane);
}
rootPane.getChildren().add(settingsPane);
}
scroll.setContent(rootPane);
}
}
public void openLogFolder() {
FXUtils.openFolder(LOG.getLogFile().getParent());
}
protected abstract void onUpdate();
protected abstract void onExportLogs();
protected abstract void onSponsor();
protected abstract void clearCacheDirectory();
}