Vaadin - How to open BrowserWindowOpener from a SINGLE BUTTON

房东的猫 提交于 2019-12-06 15:52:33

Get rid of BrowserWindowOpener and use UI.getPage().open() to view your pdf file.

getUI().getPage().open(resource, "_blank", false);

Notice that this method is deprecated.

As of Vaadin 7.0.0, the functionality for opening a Resource in a Page has been replaced with similar methods based on a String URL. This is because the usage of Resource is problematic with memory management and with security features in some browsers. Is is recommended to instead use Link for starting downloads.

Don't think it is possible to use BrowserWindowOpener in one button only without hacking in JavaScript.

EDIT: I've achieved desired effect using BrowserWindowOpener. I've extended the class and added pdf generation every time when BrowserWindowOpenerState is requested. The thing is that I've searched for a method that is invoked after the click and before BrowserWindowOpener opens up new tab. The only method I could find is getState() - and only when the state of the component is dirty. I had to also add a flag in overriden getState method because:

  1. setResource method invoke getState() method too, so I had infinite loop

  2. to generate pdf only when its really needed

    public class BrowserWindowOpenerWithBeforeClick extends BrowserWindowOpener
    {
    
    private boolean pdfGenerated = false;
    
    public BrowserWindowOpenerWithBeforeClick(String url)
    {
        super(url);
    }
    
    @Override
    protected BrowserWindowOpenerState getState(boolean markAsDirty) {
        if(!pdfGenerated){
            StreamResource resource = ((RfgUI) UI.getCurrent()).getResource();
            pdfGenerated = true;
            this.setResource("url",resource);
        }
        return (BrowserWindowOpenerState) super.getState(markAsDirty);
    }
    
    public void setPdfGenerated(boolean generated){
        this.pdfGenerated = generated;
    }
    }
    

And pdf generation in your main UI class:

void pdfgeneration(final VerticalLayout layout)
{
    name.setValue("Slartibartfast");
    final Button ok = new Button("OK");
    ok.setId("ok-button");
    final BrowserWindowOpenerWithBeforeClick bwo = new BrowserWindowOpenerWithBeforeClick("");
    bwo.extend(ok);
    name.addValueChangeListener(new ValueChangeListener()
    {
        @Override
        public void valueChange(ValueChangeEvent event)
        {
            bwo.setPdfGenerated(false);
            bwo.markAsDirty();
        }
    });
    layout.addComponent(name);
    layout.addComponent(ok);
}

And getResource method:

public StreamResource getResource()
{
    StreamSource source = new MyPdfSource((String) name.getValue());
    String filename = new Random().nextInt() + "pdf_printing_example.pdf";
    StreamResource resource = new StreamResource(source, filename);
    resource.setMIMEType("application/pdf");
    resource.setCacheTime(0);
    resource.getStream().setParameter("Content-Disposition", "attachment; filename=" + filename);
    return resource;
}

Notice that I had to change the filename everytime I generate new pdf file to avoid caching problems.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!