gpt4 book ai didi

java - 如何在 snapToTicks==true 时检索最终的 Slider 值?

转载 作者:行者123 更新时间:2023-11-30 10:50:19 25 4
gpt4 key购买 nike

我有以下 JavaFX 场景(注意 snapToTicks 的设置):

package com.example.javafx;

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

public class SliderExample extends Application {
public static void main(String[] args) { launch(args); }

@Override
public void start(Stage primaryStage) {
Slider slider = new Slider(0.25, 2.0, 1.0);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
slider.setMajorTickUnit(0.25);
slider.setMinorTickCount(0);

slider.setSnapToTicks(true); // !!!!!!!!!!

Scene scene = new Scene(slider, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
}

呈现如下 slider :

slider screenshot

由于 snapToTicks 设置为 true,一旦松开鼠标按钮, slider 最终将移动到最近的值。

如何检索最终值?

我试过了

slider.valueProperty().addListener( n -> {
if (!slider.isValueChanging()) {
System.err.println(n);
}
});

除了最小值和最大值之外效果很好 - 如果鼠标已经位于 slider 左侧或右侧的位置,则根本不会再调用监听器,因为最终值已经已设置。

我也尝试过使用 valueChangingProperty:

slider.valueChangingProperty().addListener( (prop, oldVal, newVal) -> {
// NOT the final value when newVal == false!!!!!!!
System.err.println(prop + "/" + oldVal + "/" + newVal);
});

但问题是 JavaFX 仍会将值更改为捕捉值 afternewVal 等于 false 调用监听器(我什至会认为这是一个错误,但可能我错过了一些东西)。因此无法在该方法中访问最终的捕捉值。

最佳答案

根据@ItachiUchiha 的建议,我最终想出了以下解决方案。本质上,该解决方案同时使用了 valuePropertyvalueChangingProperty 监听器,并使用一些标志来跟踪当前状态。最后,当 slider 移动完成且最终值可用时,perform() 方法只被调用一次。这在使用鼠标或通过键盘移动 slider 时有效。

作为 Slider 的子类实现的可重用类可在 https://github.com/afester/FranzXaver/blob/master/FranzXaver/src/main/java/afester/javafx/components/SnapSlider.java 获得。 .

package com.example.javafx;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.stage.Stage;

public class SliderExample extends Application {

public static void main(String[] args) { launch(args); }

private boolean isFinal = true; // assumption: no dragging - clicked value is the final one.
// variable changes to "false" once dragging starts.

private Double finalValue = null;

@Override
public void start(Stage primaryStage) {
final Slider slider = new Slider(0.25, 2.0, 1.0);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
slider.setMajorTickUnit(0.25);
slider.setMinorTickCount(0);
slider.setSnapToTicks(true);

slider.valueProperty().addListener(new ChangeListener<Number>() {

final double minCompare = slider.getMin() + Math.ulp(slider.getMin());
final double maxCompare = slider.getMax() - Math.ulp(slider.getMax());

@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue) {

if (isFinal) { // either dragging of knob has stopped or
// no dragging was done at all (direct click or
// keyboard navigation)
perform((Double) newValue);
finalValue = null;
} else { // dragging in progress

double val = (double) newValue;
if (val > maxCompare || val < minCompare) {
isFinal = true; // current value will be treated as final value
// once the valueChangingProperty goes to false
finalValue = (Double) newValue; // remember current value
} else {
isFinal = false; // no final value anymore - slider
finalValue = null; // has been dragged to a position within
// minimum and maximum
}

}
}
});

slider.valueChangingProperty().addListener(new ChangeListener<Boolean>() {

@Override
public void changed(ObservableValue<? extends Boolean> observable,
Boolean oldValue, Boolean newValue) {

if (newValue == true) { // dragging of knob started.
isFinal = false; // captured values are not the final ones.

} else { // dragging of knob stopped.

if (isFinal) { // captured value is already the final one
// since it is either the minimum or the maximum value
perform(finalValue);
finalValue = null;
} else {
isFinal = true; // next captured value will be the final one
}
}
}
});

Scene scene = new Scene(slider, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}

private void perform(double value) {
System.err.printf("FINAL: %s\n", value);
}
}

关于java - 如何在 snapToTicks==true 时检索最终的 Slider 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35129670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com