从场景中移除后,JavaFX Spinner继续前进

时间:2019-05-01 08:27:42

标签: java javafx

我似乎发现JavaFX JDK Linux 1.8.0_144中的JavaFX Spinner有问题。如果您在场景中移除了微调器的同时按下增量或减量按钮,则微调器会继续前进。

输出

Spinner update 501.0
Spinner update 502.0
Spinner update 503.0
Spinner update 504.0
Spinner update 505.0
Spinner update 506.0
Spinner removed from scene
Spinner update 507.0    <== unexpected
Spinner update 508.0
Spinner update 509.0
Spinner update 510.0
Spinner update 511.0
Spinner update 512.0

代码

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Spinner;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class SpinnerProblem extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Spinner<Double> spinner = new Spinner<>(0d, 1000d, 500d);
        spinner.valueProperty().addListener((obs, oldValue, newValue) -> {
            System.out.println("Spinner update " + newValue);
        });
        HBox container = new HBox(spinner);
        primaryStage.setScene(new Scene(container));
        primaryStage.show();

        // remove the spinner from scene after 5 seconds
        Timeline timeline = new Timeline();
        timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(5), event -> {
    System.out.println("Spinner removed from scene");
    container.getChildren().clear();
 }));
        timeline.play();
    }

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

}

分析

com.sun.javafx.scene.control.skin.SpinnerSkin<T>中,com.sun.javafx.scene.control.behavior.SpinnerBehavior.stopSpinning()仅在MOUSE_RELEASED事件中被调用。当从场景中删除微调框时会出现此事件,永远不会触发此事件,并且不存在其他代码来停止旋转。

删除微调框的事实是因为此示例实际上来自一个较大的动态应用程序,在该应用程序中,屏幕可以从外部触发器自动更新。

问题

这是已知错误还是我做错了什么?我该如何避免呢?

1 个答案:

答案 0 :(得分:0)

这仍然是一个未解决的错误(我已经对JavaFX 14.0.1进行了测试)。我报告为JDK-8252863

我已经开发出以下变通办法,可以在场景更改为null的情况下模拟鼠标的释放。

public static void monkeyPatchSpinnerBug(Spinner<?> spinner) {
    spinner.sceneProperty().addListener((obs, oldValue, newValue) -> {
        Node increment = spinner.lookup(".increment-arrow-button");
        if (increment != null) {
            increment.getOnMouseReleased().handle(null);
        }
        Node decrement = spinner.lookup(".decrement-arrow-button");
        if (decrement != null) {
            decrement.getOnMouseReleased().handle(null);
        }
    });
}