优化游戏窗口大小选择功能 (#4234)
This commit is contained in:
@@ -25,10 +25,7 @@ import javafx.beans.Observable;
|
|||||||
import javafx.beans.WeakInvalidationListener;
|
import javafx.beans.WeakInvalidationListener;
|
||||||
import javafx.beans.WeakListener;
|
import javafx.beans.WeakListener;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.*;
|
||||||
import javafx.beans.property.Property;
|
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import javafx.beans.value.*;
|
import javafx.beans.value.*;
|
||||||
import javafx.collections.ObservableMap;
|
import javafx.collections.ObservableMap;
|
||||||
import javafx.event.Event;
|
import javafx.event.Event;
|
||||||
@@ -832,10 +829,144 @@ public final class FXUtils {
|
|||||||
property.addListener(binding);
|
property.addListener(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void unbindColorPicker(ColorPicker colorPicker, Property<Paint> property) {
|
private static final class WindowsSizeBidirectionalBinding implements InvalidationListener, WeakListener {
|
||||||
PaintBidirectionalBinding binding = new PaintBidirectionalBinding(colorPicker, property);
|
private final WeakReference<JFXComboBox<String>> comboBoxRef;
|
||||||
colorPicker.valueProperty().removeListener(binding);
|
private final WeakReference<IntegerProperty> widthPropertyRef;
|
||||||
property.removeListener(binding);
|
private final WeakReference<IntegerProperty> heightPropertyRef;
|
||||||
|
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
private boolean updating = false;
|
||||||
|
|
||||||
|
private WindowsSizeBidirectionalBinding(JFXComboBox<String> comboBox,
|
||||||
|
IntegerProperty widthProperty,
|
||||||
|
IntegerProperty heightProperty) {
|
||||||
|
this.comboBoxRef = new WeakReference<>(comboBox);
|
||||||
|
this.widthPropertyRef = new WeakReference<>(widthProperty);
|
||||||
|
this.heightPropertyRef = new WeakReference<>(heightProperty);
|
||||||
|
this.hashCode = System.identityHashCode(comboBox)
|
||||||
|
^ System.identityHashCode(widthProperty)
|
||||||
|
^ System.identityHashCode(heightProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidated(Observable observable) {
|
||||||
|
if (!updating) {
|
||||||
|
var comboBox = this.comboBoxRef.get();
|
||||||
|
var widthProperty = this.widthPropertyRef.get();
|
||||||
|
var heightProperty = this.heightPropertyRef.get();
|
||||||
|
|
||||||
|
if (comboBox == null || widthProperty == null || heightProperty == null) {
|
||||||
|
if (comboBox != null) {
|
||||||
|
comboBox.focusedProperty().removeListener(this);
|
||||||
|
comboBox.sceneProperty().removeListener(this);
|
||||||
|
}
|
||||||
|
if (widthProperty != null)
|
||||||
|
widthProperty.removeListener(this);
|
||||||
|
if (heightProperty != null)
|
||||||
|
heightProperty.removeListener(this);
|
||||||
|
} else {
|
||||||
|
updating = true;
|
||||||
|
try {
|
||||||
|
int width = widthProperty.get();
|
||||||
|
int height = heightProperty.get();
|
||||||
|
|
||||||
|
if (observable instanceof ReadOnlyProperty<?>
|
||||||
|
&& ((ReadOnlyProperty<?>) observable).getBean() == comboBox) {
|
||||||
|
String value = comboBox.valueProperty().get();
|
||||||
|
if (value == null)
|
||||||
|
value = "";
|
||||||
|
int idx = value.indexOf('x');
|
||||||
|
if (idx < 0)
|
||||||
|
idx = value.indexOf('*');
|
||||||
|
|
||||||
|
if (idx < 0) {
|
||||||
|
LOG.warning("Bad window size: " + value);
|
||||||
|
comboBox.setValue(width + "x" + height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String widthStr = value.substring(0, idx).trim();
|
||||||
|
String heightStr = value.substring(idx + 1).trim();
|
||||||
|
|
||||||
|
int newWidth;
|
||||||
|
int newHeight;
|
||||||
|
try {
|
||||||
|
newWidth = Integer.parseInt(widthStr);
|
||||||
|
newHeight = Integer.parseInt(heightStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
LOG.warning("Bad window size: " + value);
|
||||||
|
comboBox.setValue(width + "x" + height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
widthProperty.set(newWidth);
|
||||||
|
heightProperty.set(newHeight);
|
||||||
|
} else {
|
||||||
|
comboBox.setValue(width + "x" + height);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
updating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wasGarbageCollected() {
|
||||||
|
return this.comboBoxRef.get() == null
|
||||||
|
|| this.widthPropertyRef.get() == null
|
||||||
|
|| this.heightPropertyRef.get() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!(obj instanceof WindowsSizeBidirectionalBinding))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var that = (WindowsSizeBidirectionalBinding) obj;
|
||||||
|
|
||||||
|
var comboBox = this.comboBoxRef.get();
|
||||||
|
var widthProperty = this.widthPropertyRef.get();
|
||||||
|
var heightProperty = this.heightPropertyRef.get();
|
||||||
|
|
||||||
|
var thatComboBox = that.comboBoxRef.get();
|
||||||
|
var thatWidthProperty = that.widthPropertyRef.get();
|
||||||
|
var thatHeightProperty = that.heightPropertyRef.get();
|
||||||
|
|
||||||
|
if (comboBox == null || widthProperty == null || heightProperty == null
|
||||||
|
|| thatComboBox == null || thatWidthProperty == null || thatHeightProperty == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return comboBox == thatComboBox
|
||||||
|
&& widthProperty == thatWidthProperty
|
||||||
|
&& heightProperty == thatHeightProperty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindWindowsSize(JFXComboBox<String> comboBox, IntegerProperty widthProperty, IntegerProperty heightProperty) {
|
||||||
|
comboBox.setValue(widthProperty.get() + "x" + heightProperty.get());
|
||||||
|
var binding = new WindowsSizeBidirectionalBinding(comboBox, widthProperty, heightProperty);
|
||||||
|
comboBox.focusedProperty().addListener(binding);
|
||||||
|
comboBox.sceneProperty().addListener(binding);
|
||||||
|
widthProperty.addListener(binding);
|
||||||
|
heightProperty.addListener(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unbindWindowsSize(JFXComboBox<String> comboBox, IntegerProperty widthProperty, IntegerProperty heightProperty) {
|
||||||
|
var binding = new WindowsSizeBidirectionalBinding(comboBox, widthProperty, heightProperty);
|
||||||
|
comboBox.focusedProperty().removeListener(binding);
|
||||||
|
comboBox.sceneProperty().removeListener(binding);
|
||||||
|
widthProperty.removeListener(binding);
|
||||||
|
heightProperty.removeListener(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindAllEnabled(BooleanProperty allEnabled, BooleanProperty... children) {
|
public static void bindAllEnabled(BooleanProperty allEnabled, BooleanProperty... children) {
|
||||||
|
|||||||
@@ -93,8 +93,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
private String versionId;
|
private String versionId;
|
||||||
|
|
||||||
private final VBox rootPane;
|
private final VBox rootPane;
|
||||||
private final JFXTextField txtWidth;
|
private final JFXComboBox<String> cboWindowsSize;
|
||||||
private final JFXTextField txtHeight;
|
|
||||||
private final JFXTextField txtServerIP;
|
private final JFXTextField txtServerIP;
|
||||||
private final ComponentList componentList;
|
private final ComponentList componentList;
|
||||||
private final JFXComboBox<LauncherVisibility> cboLauncherVisibility;
|
private final JFXComboBox<LauncherVisibility> cboLauncherVisibility;
|
||||||
@@ -389,29 +388,20 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
BorderPane right = new BorderPane();
|
BorderPane right = new BorderPane();
|
||||||
dimensionPane.setRight(right);
|
dimensionPane.setRight(right);
|
||||||
{
|
{
|
||||||
HBox hbox = new HBox();
|
cboWindowsSize = new JFXComboBox<>();
|
||||||
right.setLeft(hbox);
|
cboWindowsSize.setPrefWidth(150);
|
||||||
hbox.setPrefWidth(210);
|
right.setLeft(cboWindowsSize);
|
||||||
hbox.setSpacing(3);
|
cboWindowsSize.setEditable(true);
|
||||||
hbox.setAlignment(Pos.CENTER);
|
cboWindowsSize.setStyle("-fx-padding: 4 4 4 16");
|
||||||
BorderPane.setAlignment(hbox, Pos.CENTER);
|
cboWindowsSize.setPromptText("854x480");
|
||||||
{
|
cboWindowsSize.getItems().addAll(
|
||||||
txtWidth = new JFXTextField();
|
"854x480",
|
||||||
txtWidth.setPromptText("800");
|
"1280x720",
|
||||||
txtWidth.setPrefWidth(100);
|
"1600x900",
|
||||||
FXUtils.setValidateWhileTextChanged(txtWidth, true);
|
"1920x1080",
|
||||||
txtWidth.getValidators().setAll(new NumberValidator(i18n("input.number"), false));
|
"2560x1440",
|
||||||
|
"3840x2160"
|
||||||
Label x = new Label("x");
|
);
|
||||||
|
|
||||||
txtHeight = new JFXTextField();
|
|
||||||
txtHeight.setPromptText("480");
|
|
||||||
txtHeight.setPrefWidth(100);
|
|
||||||
FXUtils.setValidateWhileTextChanged(txtHeight, true);
|
|
||||||
txtHeight.getValidators().setAll(new NumberValidator(i18n("input.number"), false));
|
|
||||||
|
|
||||||
hbox.getChildren().setAll(txtWidth, x, txtHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
chkFullscreen = new JFXCheckBox();
|
chkFullscreen = new JFXCheckBox();
|
||||||
right.setRight(chkFullscreen);
|
right.setRight(chkFullscreen);
|
||||||
@@ -419,6 +409,8 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
chkFullscreen.setAlignment(Pos.CENTER);
|
chkFullscreen.setAlignment(Pos.CENTER);
|
||||||
BorderPane.setAlignment(chkFullscreen, Pos.CENTER);
|
BorderPane.setAlignment(chkFullscreen, Pos.CENTER);
|
||||||
BorderPane.setMargin(chkFullscreen, new Insets(0, 0, 0, 7));
|
BorderPane.setMargin(chkFullscreen, new Insets(0, 0, 0, 7));
|
||||||
|
|
||||||
|
cboWindowsSize.disableProperty().bind(chkFullscreen.selectedProperty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,8 +551,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
|
|
||||||
// unbind data fields
|
// unbind data fields
|
||||||
if (lastVersionSetting != null) {
|
if (lastVersionSetting != null) {
|
||||||
FXUtils.unbind(txtWidth, lastVersionSetting.widthProperty());
|
FXUtils.unbindWindowsSize(cboWindowsSize, lastVersionSetting.widthProperty(), lastVersionSetting.heightProperty());
|
||||||
FXUtils.unbind(txtHeight, lastVersionSetting.heightProperty());
|
|
||||||
maxMemory.unbindBidirectional(lastVersionSetting.maxMemoryProperty());
|
maxMemory.unbindBidirectional(lastVersionSetting.maxMemoryProperty());
|
||||||
javaCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.javaDirProperty());
|
javaCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.javaDirProperty());
|
||||||
gameDirCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.gameDirProperty());
|
gameDirCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.gameDirProperty());
|
||||||
@@ -593,8 +584,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
javaVersionOption.valueProperty().unbind();
|
javaVersionOption.valueProperty().unbind();
|
||||||
|
|
||||||
// bind new data fields
|
// bind new data fields
|
||||||
FXUtils.bindInt(txtWidth, versionSetting.widthProperty());
|
FXUtils.bindWindowsSize(cboWindowsSize, versionSetting.widthProperty(), versionSetting.heightProperty());
|
||||||
FXUtils.bindInt(txtHeight, versionSetting.heightProperty());
|
|
||||||
maxMemory.bindBidirectional(versionSetting.maxMemoryProperty());
|
maxMemory.bindBidirectional(versionSetting.maxMemoryProperty());
|
||||||
|
|
||||||
javaCustomOption.bindBidirectional(versionSetting.javaDirProperty());
|
javaCustomOption.bindBidirectional(versionSetting.javaDirProperty());
|
||||||
|
|||||||
Reference in New Issue
Block a user