JavaFX 无法从非应用程序线程更改 UI
JavaFX Can not change UI from non-Application Thread
类似主题的文章我都看了,还是没弄明白我的问题。我这里用的是LineChart,滚动的时候想缩放in/out。代码如下:
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
DataModel dataModel = new DataModel();
dataModel.getData("value", "value_tbl"); // get data from specified file
IViewFactory viewFactory = new LineViewFactory();
view = viewFactory.create(); // create lineChart view
view.setData(dataModel.getData("value", "value_tbl")); // load data into LineChart, here should be XYChart.Series
this.getCanvas(root).getChildren().addAll(view.getView());
stage.setScene(scene);
curStage = stage;
view.getView().setOnScroll(this.scrollHandler); // set listener
stage.show();
}
这是听众:
EventHandler<ScrollEvent> scrollHandler = new EventHandler<ScrollEvent>(){
@Override
public void handle(ScrollEvent event) {
System.out.println("view scroll");
NumberAxis xAxis = ((LineChartView)view).getXAxis();
xAxis.setLowerBound(xAxis.getLowerBound() + 10);
xAxis.setUpperBound(xAxis.getUpperBound() - 10);
Platform.runLater(new Runnable(){
@Override
public void run() {
curStage.show();
}
});
}
};
日志说程序跑到了监听器,但是折线图上没有变化
Application中的start()方法和scrollHandler部分。但 LineChartView 程序在另一个包中。
那么,任何人都可以帮我指出它不起作用的原因吗?非常感谢!
我看过一些类似的代码可以运行,但有一个很大的不同,所有程序都在应用程序下。
事件处理程序由 JavaFX 系统在 JavaFX 应用程序线程上运行。所以你在 JavaFX 应用程序线程上并且(因为你提供的代码没有演示产生任何其他线程),你的所有逻辑都在 JavaFX 应用程序线程上 运行ning 并且你不需要使用并发实用程序将逻辑切换到 JavaFX 应用程序线程;即调用 Platform.runLater()
是不必要的。
如果您不确定自己在哪个线程上,您可以随时通过调用找出答案:
System.out.println("Current thread: " + Thread.currentThread().getName());
对于您的代码,这将始终打印 "Current thread: JavaFX Application Thread"。
至于为什么你的代码不起作用 - 这是一些与线程无关的原因,但要确定在你的(新)问题中包含一个 mcve 来复制问题是明智的,完成您获得的任何错误或堆栈跟踪的环境详细信息和全文。
类似主题的文章我都看了,还是没弄明白我的问题。我这里用的是LineChart,滚动的时候想缩放in/out。代码如下:
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
DataModel dataModel = new DataModel();
dataModel.getData("value", "value_tbl"); // get data from specified file
IViewFactory viewFactory = new LineViewFactory();
view = viewFactory.create(); // create lineChart view
view.setData(dataModel.getData("value", "value_tbl")); // load data into LineChart, here should be XYChart.Series
this.getCanvas(root).getChildren().addAll(view.getView());
stage.setScene(scene);
curStage = stage;
view.getView().setOnScroll(this.scrollHandler); // set listener
stage.show();
}
这是听众:
EventHandler<ScrollEvent> scrollHandler = new EventHandler<ScrollEvent>(){
@Override
public void handle(ScrollEvent event) {
System.out.println("view scroll");
NumberAxis xAxis = ((LineChartView)view).getXAxis();
xAxis.setLowerBound(xAxis.getLowerBound() + 10);
xAxis.setUpperBound(xAxis.getUpperBound() - 10);
Platform.runLater(new Runnable(){
@Override
public void run() {
curStage.show();
}
});
}
};
日志说程序跑到了监听器,但是折线图上没有变化
Application中的start()方法和scrollHandler部分。但 LineChartView 程序在另一个包中。 那么,任何人都可以帮我指出它不起作用的原因吗?非常感谢!
我看过一些类似的代码可以运行,但有一个很大的不同,所有程序都在应用程序下。
事件处理程序由 JavaFX 系统在 JavaFX 应用程序线程上运行。所以你在 JavaFX 应用程序线程上并且(因为你提供的代码没有演示产生任何其他线程),你的所有逻辑都在 JavaFX 应用程序线程上 运行ning 并且你不需要使用并发实用程序将逻辑切换到 JavaFX 应用程序线程;即调用 Platform.runLater()
是不必要的。
如果您不确定自己在哪个线程上,您可以随时通过调用找出答案:
System.out.println("Current thread: " + Thread.currentThread().getName());
对于您的代码,这将始终打印 "Current thread: JavaFX Application Thread"。
至于为什么你的代码不起作用 - 这是一些与线程无关的原因,但要确定在你的(新)问题中包含一个 mcve 来复制问题是明智的,完成您获得的任何错误或堆栈跟踪的环境详细信息和全文。