mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-14 14:26:43 -04:00
Fix value in text field might not be saved when pressing ESC
https://github.com/HMCL-dev/HMCL/pull/1869#issuecomment-2335027530
This commit is contained in:
parent
c5b8aabc57
commit
81b3911dc9
@ -337,6 +337,8 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
if (!FileUtils.makeDirectory(file.getAbsoluteFile().getParentFile()))
|
if (!FileUtils.makeDirectory(file.getAbsoluteFile().getParentFile()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
LOG.info("Saving version setting: " + id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileUtils.writeText(file, GSON.toJson(localVersionSettings.get(id)));
|
FileUtils.writeText(file, GSON.toJson(localVersionSettings.get(id)));
|
||||||
return true;
|
return true;
|
||||||
|
@ -31,6 +31,7 @@ import javafx.geometry.Insets;
|
|||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Cursor;
|
import javafx.scene.Cursor;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
@ -521,10 +522,12 @@ public final class FXUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void bind(JFXTextField textField, Property<T> property, StringConverter<T> converter) {
|
public static <T> void bind(JFXTextField textField, Property<T> property, StringConverter<T> converter) {
|
||||||
textField.setText(converter == null ? (String) property.getValue() : converter.toString(property.getValue()));
|
TextFieldBinding<T> binding = new TextFieldBinding<>(textField, property, converter);
|
||||||
TextFieldBindingListener<T> listener = new TextFieldBindingListener<>(textField, property, converter);
|
binding.updateTextField();
|
||||||
textField.focusedProperty().addListener((ChangeListener<Boolean>) listener);
|
textField.getProperties().put("FXUtils.bind.binding", binding);
|
||||||
property.addListener(listener);
|
textField.focusedProperty().addListener(binding.focusedListener);
|
||||||
|
textField.sceneProperty().addListener(binding.sceneListener);
|
||||||
|
property.addListener(binding.propertyListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindInt(JFXTextField textField, Property<Number> property) {
|
public static void bindInt(JFXTextField textField, Property<Number> property) {
|
||||||
@ -536,71 +539,69 @@ public final class FXUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void unbind(JFXTextField textField, Property<?> property) {
|
public static void unbind(JFXTextField textField, Property<?> property) {
|
||||||
TextFieldBindingListener<?> listener = new TextFieldBindingListener<>(textField, property, null);
|
TextFieldBinding<?> binding = (TextFieldBinding<?>) textField.getProperties().remove("FXUtils.bind.binding");
|
||||||
textField.focusedProperty().removeListener((ChangeListener<Boolean>) listener);
|
if (binding != null) {
|
||||||
property.removeListener(listener);
|
textField.focusedProperty().removeListener(binding.focusedListener);
|
||||||
|
textField.sceneProperty().removeListener(binding.sceneListener);
|
||||||
|
property.removeListener(binding.propertyListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class TextFieldBindingListener<T> implements ChangeListener<Boolean>, InvalidationListener {
|
private static final class TextFieldBinding<T> {
|
||||||
private final int hashCode;
|
private final JFXTextField textField;
|
||||||
private final WeakReference<JFXTextField> textFieldRef;
|
private final Property<T> property;
|
||||||
private final WeakReference<Property<T>> propertyRef;
|
|
||||||
private final StringConverter<T> converter;
|
private final StringConverter<T> converter;
|
||||||
|
|
||||||
TextFieldBindingListener(JFXTextField textField, Property<T> property, StringConverter<T> converter) {
|
public final ChangeListener<Boolean> focusedListener;
|
||||||
this.textFieldRef = new WeakReference<>(textField);
|
public final ChangeListener<Scene> sceneListener;
|
||||||
this.propertyRef = new WeakReference<>(property);
|
public final InvalidationListener propertyListener;
|
||||||
|
|
||||||
|
public TextFieldBinding(JFXTextField textField, Property<T> property, StringConverter<T> converter) {
|
||||||
|
this.textField = textField;
|
||||||
|
this.property = property;
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
this.hashCode = System.identityHashCode(textField) ^ System.identityHashCode(property);
|
|
||||||
|
focusedListener = (observable, oldFocused, newFocused) -> {
|
||||||
|
if (oldFocused && !newFocused) {
|
||||||
|
if (textField.validate()) {
|
||||||
|
uppdateProperty();
|
||||||
|
} else {
|
||||||
|
// Rollback to old value
|
||||||
|
updateTextField();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sceneListener = (observable, oldScene, newScene) -> {
|
||||||
|
if (oldScene != null && newScene == null) {
|
||||||
|
// Component is being removed from scene
|
||||||
|
if (textField.validate()) {
|
||||||
|
uppdateProperty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
propertyListener = observable -> {
|
||||||
|
updateTextField();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void uppdateProperty() {
|
||||||
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean focused) { // On TextField changed
|
|
||||||
JFXTextField textField = textFieldRef.get();
|
|
||||||
Property<T> property = this.propertyRef.get();
|
|
||||||
|
|
||||||
if (textField != null && property != null && oldValue == Boolean.TRUE && focused == Boolean.FALSE) {
|
|
||||||
if (textField.validate()) {
|
|
||||||
String newText = textField.getText();
|
String newText = textField.getText();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T newValue = converter == null ? (T) newText : converter.fromString(newText);
|
T newValue = converter == null ? (T) newText : converter.fromString(newText);
|
||||||
|
|
||||||
if (!Objects.equals(newValue, property.getValue()))
|
if (!Objects.equals(newValue, property.getValue())) {
|
||||||
property.setValue(newValue);
|
property.setValue(newValue);
|
||||||
} else {
|
|
||||||
// Rollback to old value
|
|
||||||
invalidated(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void updateTextField() {
|
||||||
public void invalidated(Observable observable) { // On property change
|
|
||||||
JFXTextField textField = textFieldRef.get();
|
|
||||||
Property<T> property = this.propertyRef.get();
|
|
||||||
|
|
||||||
if (textField != null && property != null) {
|
|
||||||
T value = property.getValue();
|
T value = property.getValue();
|
||||||
textField.setText(converter == null ? (String) value : converter.toString(value));
|
textField.setText(converter == null ? (String) value : converter.toString(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (!(obj instanceof TextFieldBindingListener))
|
|
||||||
return false;
|
|
||||||
TextFieldBindingListener<?> other = (TextFieldBindingListener<?>) obj;
|
|
||||||
return this.hashCode == other.hashCode
|
|
||||||
&& this.textFieldRef.get() == other.textFieldRef.get()
|
|
||||||
&& this.propertyRef.get() == other.propertyRef.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void bindBoolean(JFXToggleButton toggleButton, Property<Boolean> property) {
|
public static void bindBoolean(JFXToggleButton toggleButton, Property<Boolean> property) {
|
||||||
toggleButton.selectedProperty().bindBidirectional(property);
|
toggleButton.selectedProperty().bindBidirectional(property);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user