Как я могу использовать JXBrowser для загрузки всего каталога, а не только нескольких файлов

Chrome поддерживает нестандартное свойство webkitdirectory для html-элемента input с 2011 года и отлично работает. образец кода

Я хочу запустить jxbrower. Его последняя версия по состоянию на понедельник 21 мая 2018 г. основана на Chromium 64.0.3282.24 (12 декабря 2017 г.), но не поддерживает это свойство.

Что мне не хватает? Любые предложения будут ценны.

<html>
      <div>
        <label for="uploaddir" style="width: 600px; background: #ccc;border: 1px solid black;">Choose directory to upload</label>
        <input type="file" id="uploaddir" webkitdirectory onchange="updateImageDisplay()" style="opacity:0;">
      </div>
      <div>
        <ul id="listing"></ul>
      </div>
</html>

<script>
    var input = document.getElementById('uploaddir');
    var output = document.getElementById('listing');

    function updateImageDisplay() {
      while (output.firstChild) {
        output.removeChild(output.firstChild);
      }
      var curFiles = input.files;
      for (let i = 0; i < curFiles.length; i++) {
        const item = document.createElement('li');
        item.innerHTML = `${curFiles[i].webkitRelativePath} (${curFiles[i].size} bytes)`;
        output.appendChild(item);
      }
    }
</script>

person JoeGlide    schedule 06.06.2018    source источник


Ответы (2)


JxBrowser может загрузить весь каталог. Что может быть неправильным в вашем случае, так это диалог выбора файлов, который не настроен на выбор каталогов.

Я привожу простой пример, чтобы продемонстрировать, как можно настроить диалоговое окно выбора файлов на ходу:

browser.setDialogHandler(new DefaultDialogHandler(view) {
    @Override
    public CloseStatus onFileChooser(FileChooserParams params) {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        if (fileChooser.showOpenDialog(view) == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            params.setSelectedFiles(selectedFile.getAbsolutePath());
            return CloseStatus.OK;
        }
        return CloseStatus.CANCEL;
    }
});
person Dmitry Khovyakov    schedule 07.06.2018
comment
Спасибо, Дмитрий. Мы используем javafx вместо Swing. Так будет ли эквивалент JFileChooser DirectoryChooser? - person JoeGlide; 07.06.2018
comment
Насколько мне известно, JavaFX DirectoryChooser не имеет возможности выбирать файлы и каталоги. - person Dmitry Khovyakov; 11.06.2018

@ Дмитрий. Это реализация javafx, аналогичная этому примеру swing. . Обратите внимание на следующие два важных наблюдения.

  1. Требуется «Runnable runnable», иначе возникает следующая ошибка: «SEVERE: метод DialogHandler.onFileChooser () вызвал исключение: java.lang.IllegalStateException: эта операция разрешена только в потоке событий; currentThread = Тема событий браузера '.

  2. Требуется «FutureTask», чтобы ЗАБЛОКИРОВАТЬ поток событий (?), Пока пользователь не нажмет кнопку «ОК» в обозревателе каталогов. В противном случае onFileChooser немедленно вернет CloseStatus.CANCEL. К моменту вызова params.setSelectedFiles уже слишком поздно, и никакие загруженные файлы не будут получены контроллером angular.

private String path = "C:\\Users\\user\\Desktop\\temp\\foo";

private void setDirectoryListener(Stage primaryStage) {

    browser.setDialogHandler(new DefaultDialogHandler(view) {
        @Override
        public CloseStatus onFileChooser(FileChooserParams params) {
            final AtomicReference<CloseStatus> status = new AtomicReference<>(
                CloseStatus.CANCEL);

            Runnable runnable = () -> {
                if (params.getMode() == FileChooserMode.OpenFolder) {
                    DirectoryChooser directoryChooser = new DirectoryChooser();
                    directoryChooser.setTitle("Open Resource Folder");
                    directoryChooser.setInitialDirectory(new File(path));
                    File selectedDirectory = directoryChooser.showDialog(primaryStage);
                    if (selectedDirectory != null) { // in case of CANCEL
                        List<File> allFiles = new ArrayList<>();
                        getOnlyFiles(selectedDirectory, allFiles);

                   params.setSelectedFiles(allFiles.toArray(new File[0]));
                        status.set(CloseStatus.OK);
                    }
                }
            };

            FutureTask<Void> task = new FutureTask<>(runnable, null);
            Platform.runLater(task);

            try {
                task.get();
            }
            catch (InterruptedException interrupt) {
                throw new Error("Unexpected interruption");
            }
            catch (ExecutionException exc) {
                throw new RuntimeException(exc);
            }

            return status.get();
        }
    });
}

private static void getOnlyFiles(File file, List<File> files {
    if (file.isFile()) {
        System.out.println(file.getAbsolutePath());
        files.add(file);
    }
    File[] children = file.listFiles();
    if (children == null)
        return;
    for (File child : children) {
        getOnlyFiles(child, files);
    }

}
INPUT:    
`<input id="dirinput1" type="file" webkitdirectory ngf-select="uploadDir($files)/>`

OUTPUT:

C:\Users\user\Desktop\temp\foo\bar\csv.png
C:\Users\user\Desktop\temp\foo\bar\import_OQ_Manual.txt
C:\Users\user\Desktop\temp\foo\mz.PNG
C:\Users\user\Desktop\temp\foo\test.txt
person JoeGlide    schedule 11.06.2018