JavaFX Slider:如何仅在拖动完成时更改值,同时保持键盘/触摸支持

JavaFX Slider: How to only change value when dragging is done while also maintaining keyboard / touch support

我怎样才能使应用程序仅在放开滑块时才更新图表,同时仍保持键盘/触摸屏支持?

将 valueProperty().addListener() 替换为 setOnMouseReleased() 将不再允许通过键盘或触摸屏更改值。

package application;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;

import javafx.scene.layout.VBox;
import javafx.scene.control.Slider;

import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;

import javafx.geometry.Insets;

public class SavingsCalculatorApplication extends Application {
    @Override
    public void start(Stage stage) {
        NumberAxis xAxis = new NumberAxis();
        NumberAxis yAxis = new NumberAxis();
        
        LineChart chart = new LineChart(xAxis, yAxis);
        chart.setLegendVisible(false);
        chart.setCreateSymbols(false);
        Slider slider = new Slider(0, 100, 10);
        slider.setShowTickLabels(true);
        slider.setShowTickMarks(true);
        slider.setPadding(new Insets(20, 40, 0, 40));
        
        XYChart.Series data = new XYChart.Series();
        chart.getData().add(data);
        
        slider.valueProperty().addListener(event -> {
            data.getData().clear();
            for(int counter = 0; counter < 100; counter++) {
                data.getData().add(new XYChart.Data(counter, counter * slider.getValue()));
            }
        });
        
        VBox layout = new VBox();
        layout.getChildren().add(slider);
        layout.getChildren().add(chart);
        
        Scene scene = new Scene(layout);
        stage.setScene(scene);
        stage.show();
    }
    
    public static void main(String[] args) {
        launch(SavingsCalculatorApplication.class);
    }
}

使用valueChanging属性。您可以在值更改且 valueChanging 为 false 时响应,如果滑块通过键盘(或以编程方式)更改,或者当 valueChangingtrue 更改为 [=16 时,就会发生这种情况=](当鼠标改变完成时会发生):

    slider.valueProperty().addListener((obs, oldValue, newValue) -> {
        if ( !slider.isValueChanging()) {
            updateChart(newValue.doubleValue(), data);
        }
    });
    
    slider.valueChangingProperty().addListener((obs, wasChanging, isNowChanging) -> {
        if (! isNowChanging) {
            updateChart(slider.getValue(), data);
        }
    });

private void updateChart(double value, XYChart.Series data) {
    data.getData().clear();
    for(int counter = 0; counter < 100; counter++) {
        data.getData().add(new XYChart.Data(counter, counter * value));
    }
}

切勿将低级输入事件(鼠标事件、按键事件等)用于控件中的语义更改。始终在控件的属性上注册侦听器。