diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index 483107ec5..cb2b219d0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -46,7 +46,7 @@ import javafx.util.StringConverter; import org.jackhuang.hmcl.util.*; import org.jackhuang.hmcl.util.i18n.I18n; import org.jackhuang.hmcl.util.io.FileUtils; -import org.jackhuang.hmcl.util.javafx.SelectedItemProperties; +import org.jackhuang.hmcl.util.javafx.ExtendedProperties; import org.jackhuang.hmcl.util.platform.OperatingSystem; import java.io.File; @@ -352,7 +352,7 @@ public final class FXUtils { * @param comboBox the combo box being bound with {@code property}. * @param property the property being bound with {@code combo box}. * @see #unbindEnum(JFXComboBox) - * @deprecated Use {@link SelectedItemProperties#selectedItemPropertyFor(ComboBox)} + * @deprecated Use {@link ExtendedProperties#selectedItemPropertyFor(ComboBox)} */ @SuppressWarnings("unchecked") @Deprecated diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java index 072ae7a6e..1fcaa4bf7 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java @@ -47,7 +47,8 @@ import java.util.Optional; import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -import static org.jackhuang.hmcl.util.javafx.SelectedItemProperties.selectedItemPropertyFor; +import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.reservedSelectedPropertyFor; +import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor; public final class SettingsPage extends SettingsView implements DecoratorPage { private final ReadOnlyStringWrapper title = new ReadOnlyStringWrapper(this, "title", i18n("settings.launcher")); @@ -90,9 +91,7 @@ public final class SettingsPage extends SettingsView implements DecoratorPage { proxyPane.disableProperty().bind(chkDisableProxy.selectedProperty()); authPane.disableProperty().bind(chkProxyAuthentication.selectedProperty().not()); - chkDisableProxy.setSelected(!config().hasProxy()); - chkDisableProxy.selectedProperty().addListener(o -> config().setHasProxy(!chkDisableProxy.isSelected())); - config().hasProxyProperty().addListener(o -> chkDisableProxy.setSelected(!config().hasProxy())); + reservedSelectedPropertyFor(chkDisableProxy).bindBidirectional(config().hasProxyProperty()); chkProxyAuthentication.selectedProperty().bindBidirectional(config().hasProxyAuthProperty()); ToggleGroup proxyConfigurationGroup = new ToggleGroup(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountList.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountList.java index 5376e00a8..a2c6b6d77 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountList.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountList.java @@ -25,7 +25,7 @@ import org.jackhuang.hmcl.ui.ListPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.javafx.MappedObservableList; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -import static org.jackhuang.hmcl.util.javafx.SelectedItemProperties.createSelectedItemPropertyFor; +import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor; public class AccountList extends ListPage implements DecoratorPage { private final ReadOnlyStringWrapper title = new ReadOnlyStringWrapper(this, "title", i18n("account.manage")); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/profile/ProfileList.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/profile/ProfileList.java index a8809cdc6..87457ca9b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/profile/ProfileList.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/profile/ProfileList.java @@ -26,7 +26,7 @@ import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.javafx.MappedObservableList; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -import static org.jackhuang.hmcl.util.javafx.SelectedItemProperties.createSelectedItemPropertyFor; +import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor; public class ProfileList extends ListPage implements DecoratorPage { private final ReadOnlyStringWrapper title = new ReadOnlyStringWrapper(i18n("profile.manage")); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/SelectedItemProperties.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/ExtendedProperties.java similarity index 89% rename from HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/SelectedItemProperties.java rename to HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/ExtendedProperties.java index 3cc1392ff..6f0e06641 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/SelectedItemProperties.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/ExtendedProperties.java @@ -30,6 +30,7 @@ import javafx.beans.WeakInvalidationListener; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; import javafx.collections.ObservableList; +import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.SelectionModel; import javafx.scene.control.Toggle; @@ -38,9 +39,9 @@ import javafx.scene.control.ToggleGroup; /** * @author yushijinhun */ -public final class SelectedItemProperties { +public final class ExtendedProperties { - private static final String PROP_PREFIX = SelectedItemProperties.class.getName(); + private static final String PROP_PREFIX = ExtendedProperties.class.getName(); // ==== ComboBox ==== @SuppressWarnings("unchecked") @@ -123,6 +124,16 @@ public final class SelectedItemProperties { } // ==== - private SelectedItemProperties() { + // ==== CheckBox ==== + @SuppressWarnings("unchecked") + public static ObjectProperty reservedSelectedPropertyFor(CheckBox checkbox) { + return (ObjectProperty) checkbox.getProperties().computeIfAbsent( + PROP_PREFIX + ".checkbox.reservedSelected", + any -> new MappedProperty<>(checkbox, "ext.reservedSelected", + checkbox.selectedProperty(), it -> !it, it -> !it)); + } + // ==== + + private ExtendedProperties() { } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/MappedProperty.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/MappedProperty.java new file mode 100644 index 000000000..ccf70528e --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/javafx/MappedProperty.java @@ -0,0 +1,88 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2018 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.util.javafx; + +import java.util.function.Function; + +import javafx.beans.binding.Bindings; +import javafx.beans.binding.ObjectBinding; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; + +/** + * @author yushijinhun + */ +public class MappedProperty extends SimpleObjectProperty { + + private final Property predecessor; + private final Function reservedMapper; + + private final ObjectBinding binding; + + public MappedProperty(Property predecessor, Function mapper, Function reservedMapper) { + this(null, "", predecessor, mapper, reservedMapper); + } + + public MappedProperty(Object bean, String name, Property predecessor, Function mapper, Function reservedMapper) { + super(bean, name); + this.predecessor = predecessor; + this.reservedMapper = reservedMapper; + + binding = new ObjectBinding() { + { + bind(predecessor); + } + + @Override + protected U computeValue() { + return mapper.apply(predecessor.getValue()); + } + + @Override + protected void onInvalidating() { + MappedProperty.this.fireValueChangedEvent(); + } + }; + } + + @Override + public U get() { + return binding.get(); + } + + @Override + public void set(U value) { + predecessor.setValue(reservedMapper.apply(value)); + } + + @Override + public void bind(ObservableValue observable) { + predecessor.bind(Bindings.createObjectBinding(() -> reservedMapper.apply(observable.getValue()), observable)); + } + + @Override + public void unbind() { + predecessor.unbind(); + } + + @Override + public boolean isBound() { + return predecessor.isBound(); + } +}