How to download a file from server filesystem in Vaadin 8

You’d think the demand would be such that this would be well documented and fairly straightforward in Vaadin 8. However, that’s definitely not the case.

It’s actually pretty simple…

class FileDownloadTab extends VerticalLayout {
private Button submitButton;
private File selectedFile;

FileDownloadTab(TabSheet tabSheet) {
    File rootFile = new File("/home/data");
    FilesystemData root = new FilesystemData(rootFile, false);
    FilesystemDataProvider fileSystem = new FilesystemDataProvider(root);
    Tree<File> fileTree = new Tree<>();
    fileTree.setDataProvider(fileSystem);
    fileTree.setItemIconGenerator(FileTypeResolver::getIcon);
    fileTree.addItemClickListener(this::handleFileTreeSelection);
    Panel panel = new Panel();
    panel.setSizeFull();
    panel.setContent(fileTree);
    submitButton = new Button("Submit");
    submitButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
    submitButton.setEnabled(false);
    submitButton.addClickListener(clickEvent -> handleButtonClick());
    addComponents(panel, submitButton);
    tabSheet.addTab(this, "File Download");
}

private void handleFileTreeSelection(Tree.ItemClick<File> event) {
    File file = event.getItem();
    if (!file.isDirectory()) {
        selectedFile = file;
        submitButton.setEnabled(true);
    }
}

private StreamResource createResource() {
    return new StreamResource((StreamResource.StreamSource) () -> {
        try {
            return new FileInputStream(selectedFile);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }, selectedFile.getName());
}

private void handleButtonClick() {
    FileDownloader fileDownloader = new FileDownloader(createResource());
    fileDownloader.extend(submitButton);
    submitButton.setEnabled(false);
}

}

Why do you have to make an entire tabsheet when you just want a button that saves a file to the user’s computer? Don’t need to “submit” anything. Then a Panel, three separate functions… this is not “actually pretty simple”. Here’s what simple would look like:

Button download=new Button("Download");
FileDownloader fld=new FileDownloader(new ClassResource("myfile"));
fld.extend(download);

And where is FilesystemDataProvider? It’s not a core Vaadin8 or JVM class… neither is FilesystemData.