如何将滑块更改侦听器设置为仅在 JavaFX 中释放鼠标拖动时触发?

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

我在 JavaFX 中有一个用于滑块的工作代码,但每次滑块发生任何变化时它都会触发,我希望它仅在鼠标拖动事件被释放时触发变化。

代码如下:

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

    });

如何让它只在松开鼠标时改变我的图表?

使用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);
    }

}

可以使用valueChanging property。当用户拖动拇指时 属性 是 true 并且当他们释放它时 false

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

如果您还需要以前的值,那么当 valueChanging 属性 更改为 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
                }
            }
        });
    }

}

由于 valueChanging 属性 是可写的,您可以添加自己的逻辑来确定它是否也发生变化。

注意:但是有一个问题。当用户单击 Slider 上的某处更改其值(而不是拖动拇指)时,属性 不会更改。一个可能的解决方案是同时收听 value 属性 并且仅在 isValueChanging() returns false 时才采取行动。这个解决方案也有它的问题(点击 Slider 然后 拖动不会将 valueChanging 设置为 true)。

注意#2:在稍微弄乱这个之后,我发现了上述问题的解决方法。但是,正如该答案底部所述,最好使用 .

中的解决方案

结合聆听 valueChanging 属性.

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

如果您在 Slider 上的任意位置按下然后释放,即使 value 没有改变,这也会改变 属性。


另一个(可能更好)选项是使用 onMouseReleased property (see ).