background customizing
This commit is contained in:
@@ -31,6 +31,9 @@ public final class Config {
|
|||||||
@SerializedName("last")
|
@SerializedName("last")
|
||||||
private String selectedProfile = "";
|
private String selectedProfile = "";
|
||||||
|
|
||||||
|
@SerializedName("backgroundType")
|
||||||
|
private int backgroundImageType = 0;
|
||||||
|
|
||||||
@SerializedName("bgpath")
|
@SerializedName("bgpath")
|
||||||
private String backgroundImage = null;
|
private String backgroundImage = null;
|
||||||
|
|
||||||
@@ -100,6 +103,15 @@ public final class Config {
|
|||||||
Settings.INSTANCE.save();
|
Settings.INSTANCE.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getBackgroundImageType() {
|
||||||
|
return backgroundImageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundImageType(int backgroundImageType) {
|
||||||
|
this.backgroundImageType = backgroundImageType;
|
||||||
|
Settings.INSTANCE.save();
|
||||||
|
}
|
||||||
|
|
||||||
public String getCommonDirectory() {
|
public String getCommonDirectory() {
|
||||||
return commonDirectory;
|
return commonDirectory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* 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.setting;
|
||||||
|
|
||||||
|
public enum EnumBackgroundImage {
|
||||||
|
DEFAULT,
|
||||||
|
CUSTOM;
|
||||||
|
|
||||||
|
public static EnumBackgroundImage indexOf(int index) {
|
||||||
|
if (index >= values().length || index < 0)
|
||||||
|
return DEFAULT;
|
||||||
|
else
|
||||||
|
return values()[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,9 +19,11 @@ package org.jackhuang.hmcl.setting;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.auth.Account;
|
import org.jackhuang.hmcl.auth.Account;
|
||||||
@@ -359,6 +361,52 @@ public class Settings {
|
|||||||
selectedAccount.get();
|
selectedAccount.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************
|
||||||
|
* BACKGROUND *
|
||||||
|
****************************************/
|
||||||
|
|
||||||
|
private final ImmediateStringProperty backgroundImage = new ImmediateStringProperty(this, "backgroundImage", SETTINGS.getBackgroundImage()) {
|
||||||
|
@Override
|
||||||
|
public void invalidated() {
|
||||||
|
super.invalidated();
|
||||||
|
|
||||||
|
SETTINGS.setBackgroundImage(get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getBackgroundImage() {
|
||||||
|
return backgroundImage.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmediateStringProperty backgroundImageProperty() {
|
||||||
|
return backgroundImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundImage(String backgroundImage) {
|
||||||
|
this.backgroundImage.set(backgroundImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ImmediateObjectProperty<EnumBackgroundImage> backgroundImageType = new ImmediateObjectProperty<EnumBackgroundImage>(this, "backgroundImageType", EnumBackgroundImage.indexOf(SETTINGS.getBackgroundImageType())) {
|
||||||
|
@Override
|
||||||
|
public void invalidated() {
|
||||||
|
super.invalidated();
|
||||||
|
|
||||||
|
SETTINGS.setBackgroundImageType(get().ordinal());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public EnumBackgroundImage getBackgroundImageType() {
|
||||||
|
return backgroundImageType.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmediateObjectProperty<EnumBackgroundImage> backgroundImageTypeProperty() {
|
||||||
|
return backgroundImageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundImageType(EnumBackgroundImage backgroundImageType) {
|
||||||
|
this.backgroundImageType.set(backgroundImageType);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* PROFILES *
|
* PROFILES *
|
||||||
****************************************/
|
****************************************/
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import javafx.scene.Cursor;
|
|||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
@@ -44,15 +45,23 @@ import javafx.stage.Screen;
|
|||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
|
import org.jackhuang.hmcl.setting.EnumBackgroundImage;
|
||||||
|
import org.jackhuang.hmcl.setting.Settings;
|
||||||
import org.jackhuang.hmcl.ui.animation.AnimationProducer;
|
import org.jackhuang.hmcl.ui.animation.AnimationProducer;
|
||||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||||
import org.jackhuang.hmcl.ui.animation.TransitionHandler;
|
import org.jackhuang.hmcl.ui.animation.TransitionHandler;
|
||||||
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
|
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
|
||||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogWizardDisplayer;
|
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogWizardDisplayer;
|
||||||
import org.jackhuang.hmcl.ui.wizard.*;
|
import org.jackhuang.hmcl.ui.wizard.*;
|
||||||
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
public final class Decorator extends StackPane implements TaskExecutorDialogWizardDisplayer {
|
public final class Decorator extends StackPane implements TaskExecutorDialogWizardDisplayer {
|
||||||
@@ -167,6 +176,76 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza
|
|||||||
|
|
||||||
FXUtils.setOverflowHidden((Pane) lookup("#contentPlaceHolderRoot"));
|
FXUtils.setOverflowHidden((Pane) lookup("#contentPlaceHolderRoot"));
|
||||||
FXUtils.setOverflowHidden(drawerWrapper);
|
FXUtils.setOverflowHidden(drawerWrapper);
|
||||||
|
|
||||||
|
loadBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadBackground() {
|
||||||
|
Image background;
|
||||||
|
|
||||||
|
if (Settings.INSTANCE.getBackgroundImageType() == EnumBackgroundImage.DEFAULT)
|
||||||
|
background = searchBackgroundImage(new Image("/assets/img/background.jpg"), "");
|
||||||
|
else
|
||||||
|
background = searchBackgroundImage(new Image("/assets/img/background.jpg"), Settings.INSTANCE.getBackgroundImage());
|
||||||
|
|
||||||
|
drawerWrapper.setBackground(new Background(new BackgroundImage(background, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, new BackgroundSize(800, 480, false, false, true, true))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image searchBackgroundImage(Image def, String customPath) {
|
||||||
|
Random random = new Random();
|
||||||
|
boolean loaded = false;
|
||||||
|
Image background = def;
|
||||||
|
|
||||||
|
// custom path
|
||||||
|
if (StringUtils.isNotBlank(customPath)) {
|
||||||
|
try {
|
||||||
|
background = new Image("file:" + customPath);
|
||||||
|
loaded = true;
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bgskin
|
||||||
|
if (!loaded) {
|
||||||
|
File backgroundImageFile = new File("bg");
|
||||||
|
if (backgroundImageFile.isDirectory()) {
|
||||||
|
File[] backgroundPath = backgroundImageFile.listFiles(file -> StringUtils.containsOne(FileUtils.getExtension(file), "png", "jpg"));
|
||||||
|
if (backgroundPath != null && backgroundPath.length > 0) {
|
||||||
|
int index = random.nextInt(backgroundPath.length);
|
||||||
|
try {
|
||||||
|
background = new Image("file:" + backgroundPath[index].getAbsolutePath());
|
||||||
|
loaded = true;
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// background.png
|
||||||
|
if (!loaded) {
|
||||||
|
File backgroundImageFile = new File("background.png");
|
||||||
|
if (backgroundImageFile.exists()) {
|
||||||
|
try {
|
||||||
|
background = new Image("file:" + backgroundImageFile.getAbsolutePath());
|
||||||
|
loaded = true;
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// background.jpg
|
||||||
|
if (!loaded) {
|
||||||
|
File backgroundImageFile = new File("background.jpg");
|
||||||
|
if (backgroundImageFile.exists()) {
|
||||||
|
try {
|
||||||
|
background = new Image("file:" + backgroundImageFile.getAbsolutePath());
|
||||||
|
loaded = true;
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return background;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public final class LeftPaneController {
|
|||||||
VersionListItem item = new VersionListItem(profile.getName());
|
VersionListItem item = new VersionListItem(profile.getName());
|
||||||
RipplerContainer ripplerContainer = new RipplerContainer(item);
|
RipplerContainer ripplerContainer = new RipplerContainer(item);
|
||||||
item.setOnSettingsButtonClicked(() -> Controllers.getDecorator().showPage(new ProfilePage(profile)));
|
item.setOnSettingsButtonClicked(() -> Controllers.getDecorator().showPage(new ProfilePage(profile)));
|
||||||
ripplerContainer.setRipplerFill(Paint.valueOf("#89E1F9"));
|
ripplerContainer.setRipplerFill(Paint.valueOf("#757de8"));
|
||||||
ripplerContainer.setOnMouseClicked(e -> {
|
ripplerContainer.setOnMouseClicked(e -> {
|
||||||
// clean selected property
|
// clean selected property
|
||||||
for (Node node : profilePane.getChildren())
|
for (Node node : profilePane.getChildren())
|
||||||
|
|||||||
@@ -31,16 +31,17 @@ import javafx.scene.control.Tooltip;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.setting.DownloadProviders;
|
import org.jackhuang.hmcl.setting.*;
|
||||||
import org.jackhuang.hmcl.setting.Locales;
|
|
||||||
import org.jackhuang.hmcl.setting.Proxies;
|
|
||||||
import org.jackhuang.hmcl.setting.Settings;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.FileItem;
|
import org.jackhuang.hmcl.ui.construct.FileItem;
|
||||||
import org.jackhuang.hmcl.ui.construct.FontComboBox;
|
import org.jackhuang.hmcl.ui.construct.FontComboBox;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public final class SettingsPage extends StackPane implements DecoratorPage {
|
public final class SettingsPage extends StackPane implements DecoratorPage {
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title", Main.i18n("settings.launcher"));
|
private final StringProperty title = new SimpleStringProperty(this, "title", Main.i18n("settings.launcher"));
|
||||||
|
|
||||||
@@ -65,8 +66,6 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
@FXML
|
@FXML
|
||||||
private FileItem fileCommonLocation;
|
private FileItem fileCommonLocation;
|
||||||
@FXML
|
@FXML
|
||||||
private FileItem fileBackgroundLocation;
|
|
||||||
@FXML
|
|
||||||
private Label lblDisplay;
|
private Label lblDisplay;
|
||||||
@FXML
|
@FXML
|
||||||
private Label lblUpdate;
|
private Label lblUpdate;
|
||||||
@@ -76,6 +75,8 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
private JFXButton btnUpdate;
|
private JFXButton btnUpdate;
|
||||||
@FXML
|
@FXML
|
||||||
private ScrollPane scroll;
|
private ScrollPane scroll;
|
||||||
|
@FXML
|
||||||
|
private MultiFileItem backgroundItem;
|
||||||
|
|
||||||
{
|
{
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/setting.fxml");
|
FXUtils.loadFXML(this, "/assets/fxml/setting.fxml");
|
||||||
@@ -134,6 +135,34 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
|
|||||||
|
|
||||||
FXUtils.installTooltip(btnUpdate, 0, 5000, 0, new Tooltip(Main.i18n("update.tooltip")));
|
FXUtils.installTooltip(btnUpdate, 0, 5000, 0, new Tooltip(Main.i18n("update.tooltip")));
|
||||||
checkUpdate();
|
checkUpdate();
|
||||||
|
|
||||||
|
backgroundItem.loadChildren(Collections.singletonList(
|
||||||
|
backgroundItem.createChildren(Main.i18n("launcher.background.default"), EnumBackgroundImage.DEFAULT)
|
||||||
|
));
|
||||||
|
|
||||||
|
FXUtils.bindString(backgroundItem.getTxtCustom(), Settings.INSTANCE.backgroundImageProperty());
|
||||||
|
|
||||||
|
backgroundItem.setCustomUserData(EnumBackgroundImage.CUSTOM);
|
||||||
|
backgroundItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Settings.INSTANCE.getBackgroundImageType()).findFirst().ifPresent(it -> it.setSelected(true));
|
||||||
|
|
||||||
|
Settings.INSTANCE.backgroundImageProperty().setChangedListener(it -> initBackgroundItemSubtitle());
|
||||||
|
Settings.INSTANCE.backgroundImageTypeProperty().setChangedListener(it -> initBackgroundItemSubtitle());
|
||||||
|
initBackgroundItemSubtitle();
|
||||||
|
|
||||||
|
backgroundItem.setToggleSelectedListener(newValue -> {
|
||||||
|
Settings.INSTANCE.setBackgroundImageType((EnumBackgroundImage) newValue.getUserData());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initBackgroundItemSubtitle() {
|
||||||
|
switch (Settings.INSTANCE.getBackgroundImageType()) {
|
||||||
|
case DEFAULT:
|
||||||
|
backgroundItem.setSubtitle(Main.i18n("launcher.background.default"));
|
||||||
|
break;
|
||||||
|
case CUSTOM:
|
||||||
|
backgroundItem.setSubtitle(Settings.INSTANCE.getBackgroundImage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.ui;
|
|||||||
|
|
||||||
import com.jfoenix.controls.*;
|
import com.jfoenix.controls.*;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
@@ -178,34 +177,24 @@ public final class VersionSettingsController {
|
|||||||
FXUtils.bindBoolean(chkShowLogs, versionSetting.showLogsProperty());
|
FXUtils.bindBoolean(chkShowLogs, versionSetting.showLogsProperty());
|
||||||
FXUtils.bindEnum(cboLauncherVisibility, versionSetting.launcherVisibilityProperty());
|
FXUtils.bindEnum(cboLauncherVisibility, versionSetting.launcherVisibilityProperty());
|
||||||
|
|
||||||
String javaGroupKey = "java_group.listener";
|
|
||||||
|
|
||||||
Lang.get(javaItem.getGroup().getProperties(), javaGroupKey, ChangeListener.class)
|
|
||||||
.ifPresent(javaItem.getGroup().selectedToggleProperty()::removeListener);
|
|
||||||
|
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
JFXRadioButton defaultToggle = null;
|
Toggle defaultToggle = null;
|
||||||
for (Toggle toggle : javaItem.getGroup().getToggles()) {
|
for (Toggle toggle : javaItem.getGroup().getToggles()) {
|
||||||
if (toggle instanceof JFXRadioButton) {
|
if (toggle.getUserData() == Lang.invoke(versionSetting::getJavaVersion)) {
|
||||||
if (toggle.getUserData() == Lang.invoke(versionSetting::getJavaVersion)) {
|
toggle.setSelected(true);
|
||||||
toggle.setSelected(true);
|
flag = true;
|
||||||
flag = true;
|
} else if (toggle.getUserData() == JavaVersion.fromCurrentEnvironment()) {
|
||||||
} else if (toggle.getUserData() == JavaVersion.fromCurrentEnvironment()) {
|
defaultToggle = toggle;
|
||||||
defaultToggle = (JFXRadioButton) toggle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChangeListener<Toggle> listener = (a, b, newValue) -> {
|
javaItem.setToggleSelectedListener(newValue -> {
|
||||||
if (newValue == javaItem.getRadioCustom()) {
|
if (javaItem.isCustomToggle(newValue)) {
|
||||||
versionSetting.setJava("Custom");
|
versionSetting.setJava("Custom");
|
||||||
} else {
|
} else {
|
||||||
versionSetting.setJava(((JavaVersion) newValue.getUserData()).getVersion());
|
versionSetting.setJava(((JavaVersion) newValue.getUserData()).getVersion());
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
javaItem.getGroup().getProperties().put(javaGroupKey, listener);
|
|
||||||
javaItem.getGroup().selectedToggleProperty().addListener(listener);
|
|
||||||
|
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
Optional.ofNullable(defaultToggle).ifPresent(t -> t.setSelected(true));
|
Optional.ofNullable(defaultToggle).ifPresent(t -> t.setSelected(true));
|
||||||
@@ -215,49 +204,30 @@ public final class VersionSettingsController {
|
|||||||
versionSetting.javaProperty().setChangedListener(it -> initJavaSubtitle(versionSetting));
|
versionSetting.javaProperty().setChangedListener(it -> initJavaSubtitle(versionSetting));
|
||||||
initJavaSubtitle(versionSetting);
|
initJavaSubtitle(versionSetting);
|
||||||
|
|
||||||
|
if (versionSetting.isUsesGlobal())
|
||||||
String globalGroupKey = "global_group.listener";
|
globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.TRUE).findFirst().ifPresent(it -> it.setSelected(true));
|
||||||
|
else
|
||||||
Lang.get(globalItem.getGroup().getProperties(), globalGroupKey, ChangeListener.class)
|
globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.FALSE).findFirst().ifPresent(it -> it.setSelected(true));
|
||||||
.ifPresent(globalItem.getGroup().selectedToggleProperty()::removeListener);
|
globalItem.setToggleSelectedListener(newValue -> {
|
||||||
ChangeListener<Toggle> globalListener = (a, b, newValue) -> {
|
|
||||||
if ((Boolean) newValue.getUserData())
|
if ((Boolean) newValue.getUserData())
|
||||||
profile.globalizeVersionSetting(versionId);
|
profile.globalizeVersionSetting(versionId);
|
||||||
else
|
else
|
||||||
profile.specializeVersionSetting(versionId);
|
profile.specializeVersionSetting(versionId);
|
||||||
|
|
||||||
Platform.runLater(() -> loadVersionSetting(profile, versionId));
|
Platform.runLater(() -> loadVersionSetting(profile, versionId));
|
||||||
};
|
});
|
||||||
if (versionSetting.isUsesGlobal())
|
|
||||||
globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.TRUE).findFirst().ifPresent(it -> it.setSelected(true));
|
|
||||||
else
|
|
||||||
globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.FALSE).findFirst().ifPresent(it -> it.setSelected(true));
|
|
||||||
globalItem.getGroup().getProperties().put(globalGroupKey, globalListener);
|
|
||||||
globalItem.getGroup().selectedToggleProperty().addListener(globalListener);
|
|
||||||
versionSetting.usesGlobalProperty().setChangedListener(it -> initUsesGlobalSubtitle(versionSetting));
|
|
||||||
initUsesGlobalSubtitle(versionSetting);
|
|
||||||
|
|
||||||
String gameDirKey = "game_dir.listener";
|
versionSetting.usesGlobalProperty().setChangedListenerAndOperate(it ->
|
||||||
Lang.get(gameDirItem.getGroup().getProperties(), gameDirKey, ChangeListener.class)
|
globalItem.setSubtitle(Main.i18n(versionSetting.isUsesGlobal() ? "settings.type.global" : "settings.type.special")));
|
||||||
.ifPresent(gameDirItem.getGroup().selectedToggleProperty()::removeListener);
|
|
||||||
|
|
||||||
for (Toggle toggle : gameDirItem.getGroup().getToggles()) {
|
gameDirItem.getGroup().getToggles().stream()
|
||||||
if (toggle instanceof JFXRadioButton) {
|
.filter(it -> it.getUserData() == versionSetting.getGameDirType())
|
||||||
if (toggle.getUserData() == versionSetting.getGameDirType()) {
|
.findFirst().ifPresent(toggle -> toggle.setSelected(true));
|
||||||
toggle.setSelected(true);
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gameDirItem.setCustomUserData(EnumGameDirectory.CUSTOM);
|
gameDirItem.setCustomUserData(EnumGameDirectory.CUSTOM);
|
||||||
|
gameDirItem.setToggleSelectedListener(newValue -> {
|
||||||
ChangeListener<Toggle> gameDirListener = (a, b, newValue) -> {
|
|
||||||
versionSetting.setGameDirType((EnumGameDirectory) newValue.getUserData());
|
versionSetting.setGameDirType((EnumGameDirectory) newValue.getUserData());
|
||||||
};
|
});
|
||||||
|
|
||||||
gameDirItem.getGroup().getProperties().put(gameDirKey, gameDirListener);
|
|
||||||
gameDirItem.getGroup().selectedToggleProperty().addListener(gameDirListener);
|
|
||||||
|
|
||||||
versionSetting.gameDirProperty().setChangedListener(it -> initGameDirSubtitle(versionSetting));
|
versionSetting.gameDirProperty().setChangedListener(it -> initGameDirSubtitle(versionSetting));
|
||||||
versionSetting.gameDirTypeProperty().setChangedListener(it -> initGameDirSubtitle(versionSetting));
|
versionSetting.gameDirTypeProperty().setChangedListener(it -> initGameDirSubtitle(versionSetting));
|
||||||
@@ -279,10 +249,6 @@ public final class VersionSettingsController {
|
|||||||
gameDirItem.setSubtitle(profile.getRepository().getRunDirectory(versionId).getAbsolutePath());
|
gameDirItem.setSubtitle(profile.getRepository().getRunDirectory(versionId).getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initUsesGlobalSubtitle(VersionSetting versionSetting) {
|
|
||||||
globalItem.setSubtitle(Main.i18n(versionSetting.isUsesGlobal() ? "settings.type.global" : "settings.type.special"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void onShowAdvanced() {
|
private void onShowAdvanced() {
|
||||||
if (!rootPane.getChildren().contains(advancedSettingsPane))
|
if (!rootPane.getChildren().contains(advancedSettingsPane))
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import javafx.collections.ObservableList;
|
|||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Toggle;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
@@ -43,6 +44,7 @@ import org.jackhuang.hmcl.ui.SVG;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class MultiFileItem extends ComponentList {
|
public class MultiFileItem extends ComponentList {
|
||||||
private final StringProperty customTitle = new SimpleStringProperty(this, "customTitle", Main.i18n("selector.custom"));
|
private final StringProperty customTitle = new SimpleStringProperty(this, "customTitle", Main.i18n("selector.custom"));
|
||||||
@@ -58,6 +60,8 @@ public class MultiFileItem extends ComponentList {
|
|||||||
private final VBox pane = new VBox();
|
private final VBox pane = new VBox();
|
||||||
private final boolean hasCustom;
|
private final boolean hasCustom;
|
||||||
|
|
||||||
|
private Consumer<Toggle> toggleSelectedListener;
|
||||||
|
|
||||||
public MultiFileItem(@NamedArg(value = "hasCustom", defaultValue = "true") boolean hasCustom) {
|
public MultiFileItem(@NamedArg(value = "hasCustom", defaultValue = "true") boolean hasCustom) {
|
||||||
this.hasCustom = hasCustom;
|
this.hasCustom = hasCustom;
|
||||||
|
|
||||||
@@ -100,6 +104,11 @@ public class MultiFileItem extends ComponentList {
|
|||||||
if (hasCustom)
|
if (hasCustom)
|
||||||
pane.getChildren().add(custom);
|
pane.getChildren().add(custom);
|
||||||
addChildren(pane);
|
addChildren(pane);
|
||||||
|
|
||||||
|
group.selectedToggleProperty().addListener((a, b, newValue) -> {
|
||||||
|
if (toggleSelectedListener != null)
|
||||||
|
toggleSelectedListener.accept(newValue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node createChildren(String title) {
|
public Node createChildren(String title) {
|
||||||
@@ -175,8 +184,12 @@ public class MultiFileItem extends ComponentList {
|
|||||||
radioCustom.setUserData(userData);
|
radioCustom.setUserData(userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JFXRadioButton getRadioCustom() {
|
public boolean isCustomToggle(Toggle toggle) {
|
||||||
return radioCustom;
|
return radioCustom == toggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToggleSelectedListener(Consumer<Toggle> consumer) {
|
||||||
|
toggleSelectedListener = consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty customTextProperty() {
|
public StringProperty customTextProperty() {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tab-header-background {
|
.tab-header-background {
|
||||||
-fx-background: gray;
|
-fx-background-color: #757de8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -1002,8 +1002,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.jfx-decorator-drawer {
|
.jfx-decorator-drawer {
|
||||||
-fx-background-image: url("/assets/img/background.jpg");
|
|
||||||
-fx-background-size: cover;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.resize-border {
|
.resize-border {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
|
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
|
||||||
<?import org.jackhuang.hmcl.ui.construct.FileItem?>
|
<?import org.jackhuang.hmcl.ui.construct.FileItem?>
|
||||||
<?import org.jackhuang.hmcl.ui.construct.FontComboBox?>
|
<?import org.jackhuang.hmcl.ui.construct.FontComboBox?>
|
||||||
|
<?import org.jackhuang.hmcl.ui.construct.MultiFileItem?>
|
||||||
<fx:root xmlns="http://javafx.com/javafx"
|
<fx:root xmlns="http://javafx.com/javafx"
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
type="StackPane">
|
type="StackPane">
|
||||||
@@ -32,8 +33,11 @@
|
|||||||
</right>
|
</right>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
|
|
||||||
<FileItem fx:id="fileCommonLocation" name="%launcher.common_location" title="%launcher.choose_commonpath" tooltip="%settings.launcher.common_path.tooltip" />
|
<FileItem fx:id="fileCommonLocation" name="%launcher.common_directory" title="%launcher.common_directory.choose" tooltip="%settings.launcher.common_path.tooltip" />
|
||||||
<!--FileItem fx:id="fileBackgroundLocation" name="%launcher.background_location" title="%launcher.choose_bgpath" tooltip="%launcher.background_tooltip" /-->
|
|
||||||
|
<MultiFileItem fx:id="backgroundItem" title="%launcher.background" chooserTitle="%launcher.background.choose"
|
||||||
|
hasSubtitle="true" customText="%settings.custom" />
|
||||||
|
|
||||||
<BorderPane><left><Label text="%settings.launcher.download_source" BorderPane.alignment="CENTER_LEFT" /></left><right><JFXComboBox fx:id="cboDownloadSource">
|
<BorderPane><left><Label text="%settings.launcher.download_source" BorderPane.alignment="CENTER_LEFT" /></left><right><JFXComboBox fx:id="cboDownloadSource">
|
||||||
<items>
|
<items>
|
||||||
<FXCollections fx:factory="observableArrayList">
|
<FXCollections fx:factory="observableArrayList">
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
</right>
|
</right>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
|
|
||||||
<MultiFileItem fx:id="javaItem" title="%settings.game.java_directory" chooserTitle="%settings.choose_javapath"
|
<MultiFileItem fx:id="javaItem" title="%settings.game.java_directory" chooserTitle="%settings.game.java_directory.choose"
|
||||||
hasSubtitle="true" customText="%settings.custom" directory="false" />
|
hasSubtitle="true" customText="%settings.custom" directory="false" />
|
||||||
|
|
||||||
<MultiFileItem fx:id="gameDirItem" title="%profile.instance_directory" chooserTitle="%settings.choose_gamedir"
|
<MultiFileItem fx:id="gameDirItem" title="%profile.instance_directory" chooserTitle="%settings.choose_gamedir"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<JFXButton fx:id="btnDelete" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onDelete"
|
<JFXButton fx:id="btnDelete" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onDelete"
|
||||||
styleClass="toggle-icon3" ripplerFill="white">
|
styleClass="toggle-icon3" ripplerFill="white">
|
||||||
<graphic>
|
<graphic>
|
||||||
<fx:include source="/assets/svg/delete-black.fxml"/>
|
<fx:include source="/assets/svg/delete-white.fxml"/>
|
||||||
</graphic>
|
</graphic>
|
||||||
</JFXButton>
|
</JFXButton>
|
||||||
<JFXButton fx:id="btnExport" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onExport"
|
<JFXButton fx:id="btnExport" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onExport"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<JFXButton fx:id="btnManagementMenu" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onManagementMenu"
|
<JFXButton fx:id="btnManagementMenu" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onManagementMenu"
|
||||||
styleClass="toggle-icon3" ripplerFill="white">
|
styleClass="toggle-icon3" ripplerFill="white">
|
||||||
<graphic>
|
<graphic>
|
||||||
<fx:include source="/assets/svg/wrench-black.fxml"/>
|
<fx:include source="/assets/svg/wrench-white.fxml"/>
|
||||||
</graphic>
|
</graphic>
|
||||||
</JFXButton>
|
</JFXButton>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|||||||
@@ -174,11 +174,12 @@ launch.unsupported_launcher_version=Sorry, the launcher cannot launch minecraft,
|
|||||||
launch.wrong_javadir=Incorrect Java directory, will reset to default Java directory.
|
launch.wrong_javadir=Incorrect Java directory, will reset to default Java directory.
|
||||||
|
|
||||||
launcher=Launcher
|
launcher=Launcher
|
||||||
launcher.background_location=Background Location
|
launcher.background=Background Image
|
||||||
launcher.background_tooltip=The laucher uses a default background.\nIf you use custom background.png, link it and it will be used.\nIf there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.\nIf you set the background setting, this app will use it.
|
launcher.background.choose=Choose background path.
|
||||||
launcher.choose_bgpath=Choose background path.
|
launcher.background.default=Default
|
||||||
launcher.choose_commonpath=Choose common path.
|
launcher.background.tooltip=The laucher uses a default background.\nIf you use custom background.png, link it and it will be used.\nIf there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.\nIf you set the background setting, this app will use it.
|
||||||
launcher.common_location=Common Directory
|
launcher.common_directory=Common Directory
|
||||||
|
launcher.common_directory.choose=Choose common directory.
|
||||||
launcher.contact=Contact Us
|
launcher.contact=Contact Us
|
||||||
launcher.crash=Hello Minecraft! Launcher has crashed!
|
launcher.crash=Hello Minecraft! Launcher has crashed!
|
||||||
launcher.crash_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it!
|
launcher.crash_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it!
|
||||||
@@ -326,7 +327,6 @@ settings.advanced.wrapper_launcher=Wrapper Launcher(i.e. optirun...)
|
|||||||
|
|
||||||
settings.cannot_remove_default_config=Cannot remove the default configution.
|
settings.cannot_remove_default_config=Cannot remove the default configution.
|
||||||
settings.choose_gamedir=Choose Game Directory
|
settings.choose_gamedir=Choose Game Directory
|
||||||
settings.choose_javapath=Choose Java Directory.
|
|
||||||
settings.custom=Custom
|
settings.custom=Custom
|
||||||
settings.default=Default
|
settings.default=Default
|
||||||
settings.failed_load=Failed to load settings file. Remove it?
|
settings.failed_load=Failed to load settings file. Remove it?
|
||||||
@@ -336,6 +336,7 @@ settings.game.dimension=Game Window Dimension
|
|||||||
settings.game.exploration=Explore
|
settings.game.exploration=Explore
|
||||||
settings.game.fullscreen=Fullscreen
|
settings.game.fullscreen=Fullscreen
|
||||||
settings.game.java_directory=Java Dir
|
settings.game.java_directory=Java Dir
|
||||||
|
settings.game.java_directory.choose=Choose Java Directory.
|
||||||
settings.game.management=Manage
|
settings.game.management=Manage
|
||||||
|
|
||||||
settings.icon=Game Icon
|
settings.icon=Game Icon
|
||||||
|
|||||||
@@ -174,11 +174,12 @@ launch.unsupported_launcher_version=对不起,本启动器现在可能不能
|
|||||||
launch.wrong_javadir=错误的Java路径,将自动重置为默认Java路径。
|
launch.wrong_javadir=错误的Java路径,将自动重置为默认Java路径。
|
||||||
|
|
||||||
launcher=启动器
|
launcher=启动器
|
||||||
launcher.background_location=背景地址
|
launcher.background=背景地址
|
||||||
launcher.background_tooltip=启动器默认使用自带的背景\n如果当前目录有background.png,则会使用该文件作为背景\n如果当前目录有bg子目录,则会随机使用里面的一张图作为背景\n如果该背景地址被修改,则会使用背景地址里的一张图作为背景\n背景地址允许有多个地址,使用半角分号";"(不包含双引号)分隔
|
launcher.background.choose=选择背景路径
|
||||||
launcher.choose_bgpath=选择背景路径
|
launcher.background.default=默认
|
||||||
launcher.choose_commonpath=选择公共路径
|
launcher.background.tooltip=启动器默认使用自带的背景\n如果当前目录有background.png,则会使用该文件作为背景\n如果当前目录有bg子目录,则会随机使用里面的一张图作为背景\n如果该背景地址被修改,则会使用背景地址里的一张图作为背景\n背景地址允许有多个地址,使用半角分号";"(不包含双引号)分隔
|
||||||
launcher.common_location=公共文件夹
|
launcher.common_directory=公共文件夹
|
||||||
|
launcher.common_directory.choose=选择公共文件夹
|
||||||
launcher.contact=联系我们
|
launcher.contact=联系我们
|
||||||
launcher.crash=Hello Minecraft!遇到了无法处理的错误,请复制下列内容并通过mcbbs、贴吧、Github或Minecraft Forum反馈bug。
|
launcher.crash=Hello Minecraft!遇到了无法处理的错误,请复制下列内容并通过mcbbs、贴吧、Github或Minecraft Forum反馈bug。
|
||||||
launcher.crash_out_dated=Hello Minecraft! Launcher遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试!
|
launcher.crash_out_dated=Hello Minecraft! Launcher遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试!
|
||||||
@@ -326,7 +327,6 @@ settings.advanced.wrapper_launcher=前置指令(不必填写,如optirun)
|
|||||||
|
|
||||||
settings.cannot_remove_default_config=不能删除默认配置
|
settings.cannot_remove_default_config=不能删除默认配置
|
||||||
settings.choose_gamedir=选择游戏路径
|
settings.choose_gamedir=选择游戏路径
|
||||||
settings.choose_javapath=选择Java路径
|
|
||||||
settings.custom=自定义
|
settings.custom=自定义
|
||||||
settings.default=默认
|
settings.default=默认
|
||||||
settings.failed_load=设置文件加载失败,可能是升级了启动器或被人工修改造成错误,是否清除?
|
settings.failed_load=设置文件加载失败,可能是升级了启动器或被人工修改造成错误,是否清除?
|
||||||
@@ -336,6 +336,7 @@ settings.game.dimension=游戏窗口分辨率
|
|||||||
settings.game.exploration=浏览
|
settings.game.exploration=浏览
|
||||||
settings.game.fullscreen=全屏
|
settings.game.fullscreen=全屏
|
||||||
settings.game.java_directory=Java路径
|
settings.game.java_directory=Java路径
|
||||||
|
settings.game.java_directory.choose=选择Java路径
|
||||||
settings.game.management=管理
|
settings.game.management=管理
|
||||||
|
|
||||||
settings.icon=游戏图标
|
settings.icon=游戏图标
|
||||||
|
|||||||
3
HMCL/src/main/resources/assets/svg/delete-white.fxml
Normal file
3
HMCL/src/main/resources/assets/svg/delete-white.fxml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
|
<javafx.scene.shape.SVGPath fill="white" content="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" />
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?import javafx.scene.shape.SVGPath?>
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
<javafx.scene.shape.SVGPath fill="black" content="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
|
<javafx.scene.shape.SVGPath fill="white" content="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?import javafx.scene.shape.SVGPath?>
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
<javafx.scene.shape.SVGPath fill="black" content="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" />
|
<javafx.scene.shape.SVGPath fill="white" content="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" />
|
||||||
|
|||||||
3
HMCL/src/main/resources/assets/svg/wrench-white.fxml
Normal file
3
HMCL/src/main/resources/assets/svg/wrench-white.fxml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
|
<javafx.scene.shape.SVGPath fill="white" content="M22.7,19L13.6,9.9C14.5,7.6 14,4.9 12.1,3C10.1,1 7.1,0.6 4.7,1.7L9,6L6,9L1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1C4.8,14 7.5,14.5 9.8,13.6L18.9,22.7C19.3,23.1 19.9,23.1 20.3,22.7L22.6,20.4C23.1,20 23.1,19.3 22.7,19Z" />
|
||||||
@@ -55,6 +55,11 @@ public class ImmediateBooleanProperty extends SimpleBooleanProperty {
|
|||||||
this.listener = Objects.requireNonNull(listener);
|
this.listener = Objects.requireNonNull(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setChangedListenerAndOperate(Consumer<Boolean> listener) {
|
||||||
|
this.listener = Objects.requireNonNull(listener);
|
||||||
|
listener.accept(get());
|
||||||
|
}
|
||||||
|
|
||||||
public ImmediateBooleanProperty(Object bean, String name, boolean initialValue) {
|
public ImmediateBooleanProperty(Object bean, String name, boolean initialValue) {
|
||||||
super(bean, name, initialValue);
|
super(bean, name, initialValue);
|
||||||
addListener(changeListener);
|
addListener(changeListener);
|
||||||
|
|||||||
@@ -190,6 +190,13 @@ public final class StringUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean containsOne(String pattern, String... targets) {
|
||||||
|
for (String target : targets)
|
||||||
|
if (pattern.toLowerCase().contains(target.toLowerCase()))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<String> tokenize(String str) {
|
public static List<String> tokenize(String str) {
|
||||||
if (str == null)
|
if (str == null)
|
||||||
return new LinkedList<>();
|
return new LinkedList<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user