java - JavaFX Spinner 从场景中移除后继续运行
问题描述
我似乎在 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);
}
}
分析
Incom.sun.javafx.scene.control.skin.SpinnerSkin<T>
com.sun.javafx.scene.control.behavior.SpinnerBehavior.stopSpinning()
只在MOUSE_RELEASED
事件中被调用。当微调器从场景中移除时,它会出现,此事件永远不会触发,并且不存在其他代码来停止旋转。
微调器被移除的事实是因为这个例子实际上来自一个更大的动态应用程序,其中屏幕可以从外部触发器自动更新。
问题
这是一个已知的错误还是我做错了什么?我怎样才能避免它?
解决方案
这仍然是一个未解决的错误(我已经测试了 JavaFX 14.0.1)。我报告为JDK-8252863
我开发了以下解决方法,在场景更改为空时模拟鼠标释放。
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);
}
});
}
推荐阅读
- pointers - 进行迭代中序树遍历时出现分段错误
- c - 使应用程序通过 UDP 发现彼此
- css - 我可以结合位置:粘性和浮动:左吗?
- android - 如何解决错误依赖无法添加 Firebase 库
- spring-boot - 如何在spring boot中加载与外键链接的多个表的插入脚本
- google-cloud-platform - 如何在现有 GKE 集群上启用 Istio SDS
- r - 如何让 ggplot2 在同一个图中绘制多个模拟轨迹?
- apache-kafka - Kafka分区消费顺序
- postgresql - 从文件执行 postgresql 查询并将输出写入另一个 csv 文件
- c# - 尽管在本地主机上工作,但 Azure Active Directory 在部署到 Azure 时始终重定向到“~/.auth/login/done”