В общем, вы можете создать отдельное свойство, которое представляет фактическое значение, которое вы хотите от ползунка, а затем зарегистрировать слушателя с этим свойством. Обратите внимание, что слушатели изменений получают уведомление только тогда, когда значение действительно изменяется, поэтому if (oldValue==newValue)
в вашем слушателе всегда будет ложным.
В этом случае, поскольку интересующее значение является просто результатом приведения значения ползунка к int
, вы можете просто привязать IntegerProperty
к значению ползунка:
IntegerProperty intValue = new SimpleIntegerProperty();
intValue.bind(sldFontSize.valueProperty());
intValue.addListener((ov, oldValue, newValue) -> btnApply.setDisable(false));
В общем, создайте настраиваемую привязку или зарегистрируйте прослушиватель с sldFontSize.valueProperty()
, который обновляет другое ваше свойство. Например, используя ваш FontSize
, который, я думаю, является enum
:
ObjectProperty<FontSize> fontSizeProperty = new SimpleObjectProperty<>();
fontSizeProperty.bind(Bindings.createObjectBinding(
() -> FontSize.value()[(int) sldFontSize.getValue()],
sldFontSize.valueProperty()));
fontSizeProperty.addListener((obs, oldFontSize, newFontSize) -> btnApply.setDisable(false));
Для большей точности вы можете реализовать округление вместо простого преобразования, et c. Вы также можете сохранить «последнее примененное значение» и сравнить с ним при принятии решения, следует ли отключать / включать кнопку, и т. Д. c.
Собрав все это вместе, вы получите что-то вроде:
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
VBox root = new VBox();
IntegerProperty lastSavedFontSize = new SimpleIntegerProperty(1);
IntegerProperty sldIntValue = new SimpleIntegerProperty();
Button btnApply = new Button("Apply");
btnApply.setOnAction(e -> lastSavedFontSize.set(sldIntValue.get()));
btnApply.disableProperty().bind(sldIntValue.isEqualTo(lastSavedFontSize));
Slider sldFontSize = new Slider();
sldFontSize.setMin(0);
sldFontSize.setMax(2);
sldFontSize.setValue(lastSavedFontSize.get());
sldFontSize.setMajorTickUnit(1);
sldFontSize.setMinorTickCount(0);
sldFontSize.setBlockIncrement(1);
sldFontSize.setSnapToTicks(true);
sldFontSize.setShowTickMarks(true);
sldFontSize.setShowTickLabels(true);
sldIntValue.bind(Bindings.createIntegerBinding(
() ->(int) Math.round(sldFontSize.getValue()),
sldFontSize.valueProperty()));
root.getChildren().addAll(sldFontSize, btnApply);
Scene scene = new Scene(root, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Другой подход - использовать valueChangingProperty()
ползунка. Это логическое свойство истинно тогда и только тогда, когда пользователь в настоящее время находится в процессе изменения значения. Обратите внимание, что в некоторых случаях valueChangingProperty()
может стать ложным до того, как будет установлено окончательное значение ползунка, поэтому безопаснее всего прослушивать оба свойства. Вот версия, использующая этот подход:
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
VBox root = new VBox();
IntegerProperty lastSavedFontSize = new SimpleIntegerProperty(1);
Button btnApply = new Button("Apply");
btnApply.setDisable(true);
Slider sldFontSize = new Slider();
sldFontSize.setMin(0);
sldFontSize.setMax(2);
sldFontSize.setValue(lastSavedFontSize.get());
sldFontSize.setMajorTickUnit(1);
sldFontSize.setMinorTickCount(0);
sldFontSize.setBlockIncrement(1);
sldFontSize.setSnapToTicks(true);
sldFontSize.setShowTickMarks(true);
sldFontSize.setShowTickLabels(true);
btnApply.setOnAction(e -> {
// apply change, and do
lastSavedFontSize.set((int) sldFontSize.getValue());
});
ChangeListener<Object> sliderListener = (obs, oldV, newV) -> {
if (!sldFontSize.isValueChanging()) {
btnApply.setDisable((int)sldFontSize.getValue() == lastSavedFontSize.get());
}
};
sldFontSize.valueProperty().addListener(sliderListener);
sldFontSize.valueChangingProperty().addListener(sliderListener);
lastSavedFontSize.addListener(sliderListener);
root.getChildren().addAll(sldFontSize, btnApply);
Scene scene = new Scene(root, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}