Java FX пользовательский интерфейс заблокирован ExecutorService - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть проблема, как правильно обновить 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, и все в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...