我创建了一个类作为加载器,用于在后台Thread中加载图像,并将其添加到JavaFX Application中,
我的问题是,尽管该类可用作Task,但它会导致JavaFX Apllication在图像加载期间冻结,并在完成后再次正常工作,
加载程序类代码:
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class Loader{
private String type = "";
private String url = "";
private ImageView image = new ImageView();
private class LoaderService extends Service{
@Override
protected Task createTask() {
return new LoaderTask();
}
}
private class LoaderTask extends Task{
@Override
protected Object call() throws Exception {
new LoaderClass();
return null;
}
}
private String getType(){
return this.type;
}
private String getUrl(){
return this.url;
}
public Loader type(String type){
this.type = type;
return this;
}
public Loader url(String url){
this.url = url;
return this;
}
public ImageView getImage(){
return this.image;
}
public Loader build(){
new LoaderTask().run();
return this;
}
private class LoaderClass{
public LoaderClass(){
switch(getType()){
case "image":
this.loadImage(getUrl());
break;
}
}
private void loadImage(String url){
try{
getImage().setImage(new Image(url));
}catch(Exception ex){
System.out.println("Ex"+ex.getMessage());
}
}
}
}
调用加载程序以获取来自外部类的图像以将其添加到主JavaFX Window内的示例:
StackPane Pane = new StackPane();
ImageView Icon1 = new NinjaLoader()
.type("image")
.url("http://localhost/images/1.png")
.build()
.getImage();
ImageView Icon2 = new NinjaLoader()
.type("image")
.url("http://localhost/images/2.png")
.build()
.getImage();
ImageView Icon3 = new NinjaLoader()
.type("image")
.url("http://localhost/images/3.png")
.build()
.getImage();
ImageView Icon4 = new NinjaLoader()
.type("image")
.url("http://localhost/images/4.png")
.build()
.getImage();
Pane.getChildren().addAll(Icon1,Icon2,Icon3,Icon4);
那么,导致这些冻结的代码中有什么错误呢?
谢谢 ,
最佳答案
问题是您通过调用run
的Runnable
方法在同一线程中运行任务:
new LoaderTask().run();
通常的做法是在一个线程中运行它(简单):
Thread th = new Thread(new LoaderTask());
th.setDaemon(true);
th.start();
或将其发送到线程池(需要更多工作)。 More on this in the related Oracle docs...
更新
如果仍然冻结:
Platform.runLater
将场景中的部分/全部加载到场景中后立即更新场景图。