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

时间:2018-08-01 18:34:41

标签: javafx slider mouseevent

我在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();
            }

    });

如何使其仅在释放鼠标时才更改图形?

2 个答案:

答案 0 :(得分:3)

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

}

答案 1 :(得分:3)

您可以使用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()返回false时执行操作。不过,此解决方案也存在一些问题(单击Slider 然后拖动不会将valueChanging设置为true)。

注意#2:在解决了这一点之后,我发现了上述问题的解决方法。但是,如该答案底部所述,最好在Sedrick's answer中使用该解决方案。

通过收听valueChanging属性将其组合起来。

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

即使您{@ {1}}不变,也可以在Slider上的任意位置按下然后放开,从而更改属性。


另一个(可能更好)的选择是使用onMouseReleased property(请参阅this answer)。