Похоже, что уже опубликовано решение здесь . В основном все сводится к добавлению явных проверок для крайностей, чтобы ChangeListener выглядел так:
ChangeListener<? super Number> valueListener = (observable, oldValue, newValue) -> {
boolean isOnMin = newValue.doubleValue() == slider.getMin();
boolean isOnMax = newValue.doubleValue() == slider.getMax();
if (!slider.isValueChanging() || isOnMin || isOnMax) {
System.out.println("Value changed");
}
};
Однако недостатком этого решения является то, что оно немедленно вызывает System.out.println
всякий раз, когда ползунок касается любого из краев, даже если кнопка мыши еще не отпущена.
Альтернативное решение, которое я нашел, состояло в том, чтобы сохранить оригинальный ChangeListener, который только проверяет значение isValueChanging, но добавить следующий ChangeListener в valueChangingProperty:
ChangeListener<? super Boolean> valueChangingListener = (observable, oldUpdating, newUpdating) -> {
double value = slider.getValue();
boolean notUpdatingAnymore = oldUpdating && !newUpdating;
boolean isOnExtreme = value == slider.getMin() || value == slider.getMax();
if (notUpdatingAnymore && isOnExtreme) {
System.out.println("Value changed");
}
};
slider.valueChangingProperty().addListener(valueChangingListener);
Это ужасно, но работает. Я не знаю, есть ли более чистый способ достижения желаемого поведения.