Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a slider change listener to fire only when mouse drag is released in JavaFX?

I have a working code in JavaFX for sliders, but it fires everytime there is any change in the slider and I want it to only fire a change when the mouse drag event is released.

Below is the code:

sliderMarkerSize.valueProperty().addListener(new ChangeListener<Number>() {
        public void changed(ObservableValue<? extends Number> ov,
            Number old_val, Number new_val) {
                markerSize = new_val.intValue();
                communalWeb();
            }

    });

How to make it only change my graph when mouse is released?

like image 827
biocode Avatar asked Oct 15 '25 03:10

biocode


2 Answers

Use OnMouseReleased.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication231 extends Application
{

    @Override
    public void start(Stage primaryStage)
    {


        Slider slider = new Slider(0, 100, 0);
        slider.setOnMouseReleased(event -> {
            System.out.println(slider.getValue());
        });
        StackPane root = new StackPane(slider);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}
like image 115
Sedrick Avatar answered Oct 18 '25 01:10

Sedrick


You can use the valueChanging property. The property is true when the user is dragging the thumb and false once they release it.

slider.valueChangingProperty().addListener((obs, oldVal, newVal) -> {
    if (!newVal) {
        double value = slider.getValue();
        // call your method
    }
});

If you need the previous value as well then you'd want to store it somewhere when the valueChanging property changes to true.

import javafx.fxml.FXML;
import javafx.scene.control.Slider;

public class SliderTest {

    @FXML
    private Slider slider;
    private double oldSliderValue;

    @FXML
    private void initialize() {
        slider.valueChangingProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal) {
                oldSliderValue = slider.getValue();
            } else {
                double newSliderValue = slider.getValue();
                if (oldSliderValue != newSliderValue) {
                    // call your method
                }
            }
        });
    }

}

Since the valueChanging property is writable you can add your own logic that determines whether or not it is changing as well.

Note: There is one issue, however. The property is not changed when the user clicks somewhere on the Slider to change its value (rather than dragging the thumb). A possible solution to this would be to also listen to the value property and only act if isValueChanging() returns false. This solution also has its issues though (clicking somewhere on the Slider then dragging doesn't set valueChanging to true).

Note #2: After messing around with this for a little bit I found this workaround for the issue mentioned above. As mentioned at the bottom of this answer, however, it is probably better to use the solution in Sedrick's answer.

Combine this with listening to the valueChanging property.

slider.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> slider.setValueChanging(true));
slider.addEventFilter(MouseEvent.MOUSE_RELEASED, e -> slider.setValueChanging(false));

This will change the property if you press-then-release anywhere on the Slider even if the value doesn't change.


Another (probably better) option would be to use the onMouseReleased property (see this answer).

like image 37
Slaw Avatar answered Oct 18 '25 00:10

Slaw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!