JavaFX 2.2: закрепление слайдера перетаскивания N событий
Я пытаюсь поймать события на JavaFX бегунок особенно тот, который указывает, что перетаскивание остановилось и было выпущено. Сначала я использовал valueProperty
с макетом кода, как это
slider.valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) {
log.fine(newValue.toString());
}
});
но с этим он обновляется слишком часто. Поэтому я искал в SceneBuilder и API и нашел некоторые интересные, как
slider.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
@Override
public void handle(MouseDragEvent event) {
System.out.println("setOnMouseDragReleased");
}
});
но их никогда не увольняют. Там только некоторые любят setOnMouseReleased
Я получаю некоторый вывод, но это, например, подсчет для весь узел, как метки и т. д.
Итак, мой вопрос, который является правильным крючком, чтобы знать, что значение больше не меняется (если это возможно после выпуска мыши, как жест drag'n'Drop) и, возможно, с небольшим примером, чтобы увидеть его интерфейсы работают.
2 ответов
добавьте прослушиватель изменений в valueChangingProperty чтобы узнать, когда значение ползунка меняется, и принять любые меры, которые вы хотите по изменению значения.
в приведенном ниже примере будет регистрироваться значение ползунка, когда он начнет меняться и снова, когда он завершит изменение.
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class SliderChangeLog extends Application {
private final ListView<String> startLog = new ListView<>();
private final ListView<String> endLog = new ListView<>();
@Override public void start(Stage stage) throws Exception {
Pane logsPane = createLogsPane();
Slider slider = createMonitoredSlider();
VBox layout = new VBox(10);
layout.setAlignment(Pos.CENTER);
layout.setPadding(new Insets(10));
layout.getChildren().setAll(
slider,
logsPane
);
VBox.setVgrow(logsPane, Priority.ALWAYS);
stage.setTitle("Slider Value Change Logger");
stage.setScene(new Scene(layout));
stage.show();
}
private Slider createMonitoredSlider() {
final Slider slider = new Slider(0, 1, 0.5);
slider.setMajorTickUnit(0.5);
slider.setMinorTickCount(0);
slider.setShowTickMarks(true);
slider.setShowTickLabels(true);
slider.setMinHeight(Slider.USE_PREF_SIZE);
slider.valueChangingProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(
ObservableValue<? extends Boolean> observableValue,
Boolean wasChanging,
Boolean changing) {
String valueString = String.format("%1$.3f", slider.getValue());
if (changing) {
startLog.getItems().add(
valueString
);
} else {
endLog.getItems().add(
valueString
);
}
}
});
return slider;
}
private HBox createLogsPane() {
HBox logs = new HBox(10);
logs.getChildren().addAll(
createLabeledLog("Start", startLog),
createLabeledLog("End", endLog)
);
return logs;
}
public Pane createLabeledLog(String logName, ListView<String> log) {
Label label = new Label(logName);
label.setLabelFor(log);
VBox logPane = new VBox(5);
logPane.getChildren().setAll(
label,
log
);
logPane.setAlignment(Pos.TOP_LEFT);
return logPane;
}
public static void main(String[] args) { launch(args); }
}
ответ jewelsea был очень полезен для установки меня на правильный путь, однако, если "snapToTicks" включен, нежелательные результаты поведения. "Конечное" значение, захваченное слушателем jewelsea, -до привязка происходит, и значение после привязки никогда не захватывается.
мое решение устанавливает слушателя на value
но использует valueChanging
как страж. Что-то вроде:
slider.valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(
ObservableValue<? extends Number> observableValue,
Number previous,
Number now) {
if (!slider.isValueChanging()
|| now.doubleValue() == slider.getMax()
|| now.doubleValue() == slider.getMin()) {
// This only fires when we're done
// or when the slider is dragged to its max/min.
}
}
});
я обнаружил, что проверка значения max и min была необходима, чтобы поймать угол случай, когда пользователь перетаскивает ползунок полностью за его левую или правую границы, прежде чем отпустить мышь. По какой-то причине это не запускает событие, как я ожидал, так что это похоже на нормальную работу.
Примечание: В отличие от jewelsea, я игнорирую начальное значение ради простоты.
примечание 2: я фактически использую ScalaFX 2, поэтому я не уверен, что этот перевод Java компилируется как написанный.