问题
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
回答1:
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.
回答2:
Here is my work-around. It works like a charm for me. Hope it will help you.
Create a button and hide it by Css (NOT by code: button.setInvisible(false))
final Button downloadInvisibleButton = new Button(); downloadInvisibleButton.setId("DownloadButtonId"); downloadInvisibleButton.addStyleName("InvisibleButton");
In your theme, add this rule to hide the
downloadInvisibleButton
:.InvisibleButton { display: none; }
When the user clicks on menuItem: extend the
fileDownloader
to thedownloadInvisibleButton
, then simulate the click on thedownloadInvisibleButton
by JavaScript.menuBar.addItem("Download", new MenuBar.Command() { @Override public void menuSelected(MenuBar.MenuItem selectedItem) { FileDownloader fileDownloader = new FileDownloader(...); fileDownloader.extend(downloadInvisibleButton); //Simulate the click on downloadInvisibleButton by JavaScript Page.getCurrent().getJavaScript() .execute("document.getElementById('DownloadButtonId').click();"); } });
来源:https://stackoverflow.com/questions/20400017/how-to-start-a-file-download-in-vaadin-without-button