How to start a file download in vaadin without button?

raffael picture raffael · Dec 5, 2013 · Viewed 12.6k times · Source

I know that it is really easy to create a FileDownloader and call extend with a Button. But how do I start a download without the Button?
In my specific situation right now I have a ComboBox and the file I'd like to send to the user is generated after changing its value, based on the input. The file should be sent immediately without waiting for another click. Is that easily possible?

Thanks raffael

Answer

raffael picture raffael · Dec 5, 2013

I found a solution myself. Actually two. The first one uses the deprecated method Page.open()

public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();

public DownloadComponent() {
    cb.addValueChangeListener(this);
    cb.setNewItemsAllowed(true);
    cb.setImmediate(true);
    cb.setNullSelectionAllowed(false);
    setCompositionRoot(cb);
}

@Override
public void valueChange(ValueChangeEvent event) {
    String val = (String) event.getProperty().getValue();
    FileResource res = new FileResource(new File(val));
    Page.getCurrent().open(res, null, false);
}
}

The javadoc here mentions some memory and security problems as reason for marking it deprecated


In the second I try to go around this deprecated method by registering the resource in the DownloadComponent. I'd be glad if a vaadin expert comments this solution.

public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
private static final String MYKEY = "download";

public DownloadComponent() {
    cb.addValueChangeListener(this);
    cb.setNewItemsAllowed(true);
    cb.setImmediate(true);
    cb.setNullSelectionAllowed(false);
    setCompositionRoot(cb);
}

@Override
public void valueChange(ValueChangeEvent event) {
    String val = (String) event.getProperty().getValue();
    FileResource res = new FileResource(new File(val));
    setResource(MYKEY, res);
    ResourceReference rr = ResourceReference.create(res, this, MYKEY);
    Page.getCurrent().open(rr.getURL(), null);
}
}

Note: I do not really allow the user to open all my files on the server and you should not do that either. It is just for demonstration.