Drag spinner from its textfield:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class DraggableSpinnerApp extends Application {
@Override
public void start(Stage primaryStage) {
Spinner<Integer> spinner = new Spinner<>();
SpinnerValueFactory<Integer> valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(Integer.MIN_VALUE, Integer.MAX_VALUE, 0);
spinner.setValueFactory(valueFactory);
// There will be a little conflict between text selection and dragging
spinner.setEditable(true);
final double[] mouseAnchorY = {0d};
final double[] spinnerValOnStartDrag = {0d};
spinner.getEditor().setOnMousePressed(event -> {
// Capture the starting Y position and spinner value
mouseAnchorY[0] = event.getSceneY();
spinnerValOnStartDrag[0] = spinner.getValue();
});
// Mouse dragged event to calculate new value
spinner.getEditor().setOnMouseDragged(event -> {
double deltaY = mouseAnchorY[0] - event.getSceneY(); // Calculate the delta
// Observe values in console
System.out.printf("%s %s %s delta=%s%n",mouseAnchorY[0],event.getSceneY(),event.getEventType(),deltaY);
// For bigger initial values we want proportionally big delta factor
var valAbs = Math.abs(spinnerValOnStartDrag[0]);
var factor = String.valueOf(valAbs).length();
int newValue = (int) (spinnerValOnStartDrag[0]+deltaY*factor);
spinner.getValueFactory().setValue(newValue);
});
VBox vbox = new VBox(spinner);
Scene scene = new Scene(vbox, 400, 200);
primaryStage.setScene(scene);
primaryStage.setTitle("Draggable Spinner Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Maybe it would be better to bind this listener to buttons instead.