У меня есть проблема, как правильно обновить Java FX UI. Я впервые перехожу с Swing на FX, а также с ExecutorService. Проблема в том, что мне нужно показать gif-файл и обновить индикатор выполнения во время выполнения кода, но вместо этого я получаю белый экран со значком загрузки мыши. GIF и индикатор выполнения в конечном итоге отображаются, но после завершения цикла: for (int i = 0; i < futures.size(); i++)
Я подумал, что выполнение задач в ExecutorService
выполняется в отдельном потоке, и использование Platform.runLater
для индикатора прогресса отделит пользовательский интерфейс от долго выполняющегося кода. в ExecutorService
. Подскажите, пожалуйста, что происходит?
Контроллер. java:
public void initialize() {
ivGif.setImage(new Image(Main.class.getResourceAsStream("/test/loading.gif")));
}
public void synchronizeFiles() {
Platform.runLater(() -> pbDownloading.setVisible(true));
ExecutorService pool = Executors.newFixedThreadPool(1);
ArrayList<Future<Boolean>> futures = new ArrayList<>();
File localFile = new File(simplified code here);
Future<Boolean> f = pool.submit(new DownloadTask(new URL(simplified code here), localFile));
futures.add(f);
for (int i = 0; i < futures.size(); i++) {
final int position = i;
Platform.runLater(() -> {
pbDownloading.setProgress(position / (double) futures.size());
});
if (!futures.get(i).get(600, TimeUnit.SECONDS)) {
System.out.println("ShutdownNow");
pool.shutdownNow();
}
}
}
DownloadTask. java:
public class DownloadTask implements Callable<Boolean> {
protected Category cat = Category.getInstance(DownloadTask.class.getName());
private URL fileURL;
private File toPath;
public DownloadTask(URL fileURL, File toPath) {
this.fileURL = fileURL;
this.toPath = toPath;
}
private void downloadFile(URL fileURL, File toPath) throws IOException {
ReadableByteChannel readableByteChannel = Channels.newChannel(fileURL.openStream());
if (!toPath.getParentFile().exists()) {
if (!toPath.getParentFile().mkdirs()) throw new IOException("Unable to create parent dirs for file: "+toPath.getAbsolutePath());
}
FileOutputStream fileOutputStream = new FileOutputStream(toPath);
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
URLConnection urlConnection = fileURL.openConnection();
if (!toPath.setLastModified(urlConnection.getLastModified())) cat.error("Unable to write modified time stamp for file: "+toPath.getAbsolutePath());
}
@Override
public Boolean call() {
try {
downloadFile(fileURL, toPath);
} catch (IOException e){
System.out.println(e);
cat.error(e, e);
return false;
}
return true;
}
}
Спасибо
РЕДАКТИРОВАТЬ: Я не понял, что основной класс работает из потока приложений FX. Итак, у меня были обратные потоки, я просто применил new thread (() -> {...}).Start();
в основном классе в методе start, и все в порядке.