1

In my vaadin application I have a Table with an additional column containing a print Button. The Button calls the following util method to create a pdf and open it in a new window (ui parameter is the button):

public static void printPDF(Offer offer, AbstractComponent ui) throws IOException, DocumentException, TemplateException {
    // ... create PDF 

    FileResource resource = new FileResource(pdfFile);

    BrowserWindowOpener opener = new BrowserWindowOpener(resource);
    opener.setFeatures("");
    opener.extend(ui);
}

Now clicking the button the first time does not work. Clicking it the second time works. Clicking it the third time, opens two windows. This increases on every further click.

I also want to open the pdf using the context menu e.g.

table.addActionHandler(new Handler()...

There I don't even have a button to extend. I would prefer to, not use the .extend() part and just open a new window. How can I do that?

EDIT: This blocks the button from opening mulitple instances, still not a nice solution and the first click does not work.

Collection<Extension> extensions = ui.getExtensions();
for (Extension e : extensions) {
    if (e instanceof BrowserWindowOpener) {
        ((BrowserWindowOpener) e).setResource(resource);
        return;
    }
}

I guess I would need to create a BrowserWindowOpener for every print Button in my Table.
Not a very clean solution, the table may contain lots of rows which would create a lot of BrowserWindowOpener instances which will never be used. The context menu problem would not be solved as well.

EDIT2: This is the other solution I tried:

ResourceReference rr = ResourceReference.create(resource, ui, "print");
Page.getCurrent().open(rr.getURL(), "blank_");

Here I get the following error:

Button (175) did not handle connector request for print/2016_9090_R_1634500091131558445.pdf

flavio.donze
  • 7,432
  • 9
  • 58
  • 91
  • You need to add the extension BrowserWindowOpener before the button is clicked the first time. It shouldn't be a problem with performance, since the buttons will be created anyway. I'm curious if someone knows the answer to your context menu action question part. – Steffen Harbich Sep 04 '16 at 11:59
  • Found an old [question](http://stackoverflow.com/questions/26211489/open-pdf-file-from-menubar-using-vaadin). Seems to be the solution to open a file in a new browser window in general. – Steffen Harbich Sep 04 '16 at 12:04
  • If I use the `ResourceReference` passing the button as second parameter I get the following error: `Button (175) did not handle connector request for print/2016_9090_R_1634500091131558445.pdf` – flavio.donze Sep 05 '16 at 16:25
  • Can you post that new code? – Steffen Harbich Sep 06 '16 at 06:51
  • I can see an error in Edit 2, you need to change "blank_" to "_blank". blank_ will create a new windowed called blank_ the second time it will try and open in the window it already created. _blank is the special html name for a new blank window every time. – Chris M Sep 12 '16 at 13:30
  • The underscore needs to go before the word blank not after it. This comments section won't show it when I put it before the word blank. – Chris M Sep 12 '16 at 13:33
  • I still get the same error if I change it to "_blank". I now implemented the deprecated Embedded.TYPE_BROWSER way. Got to say to be a little disappointed in vaadin, this is a simple task but no clean solution. – flavio.donze Sep 16 '16 at 05:35

2 Answers2

1

You can use the FileDownloader to achieve what you want.

FileResource resource = new FileResource(pdfFile);
FileDownloader downloader = new FileDownloader(resource);
Button pdf= new Button("Download PDF");
downloader.extend(pdf);
Chris M
  • 1,058
  • 1
  • 15
  • 26
  • If you need the code that creates the file to be called when the user clicks the button, you will need to create your own class that implements StreamSource instead of using a FileResource. This is how I've done it before. – Chris M Sep 08 '16 at 10:57
  • Same issue as with the `BrowserWindow`. I would prefer not to connect an open resource with an UI component. – flavio.donze Sep 08 '16 at 11:47
  • If you create a class that implements StreamSource, it doens't need to have any resources opened until it's getStream() method is invoked. This was the requirement I had. I wanted to download an XML document based on fields on the screen. – Chris M Sep 08 '16 at 15:56
1

Use this code

    Window window = new Window();
((VerticalLayout) window.getContent()).setSizeFull();
window.setResizable(true);
window.setCaption("Exemplo PDF");
window.setWidth("800");
window.setHeight("600");
window.center();
StreamSource s = new StreamResource.StreamSource() {

@Override
public InputStream getStream() {
try {
File f = new File("C:/themes/repy.pdf");
FileInputStream fis = new FileInputStream(f);
return fis;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};

StreamResource r = new StreamResource(s, "repy.pdf", mainLayout.getApplication());
Embedded e = new Embedded();
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);
r.setMIMEType("application/pdf");

e.setSource(r);
window.addComponent(e);
getMainWindow().addWindow(window);
Madhuka Dilhan
  • 1,396
  • 1
  • 14
  • 21
  • `Embedded.TYPE_BROWSER` is deprecated in vaadin 7.x "As of 7.0, use the {@link BrowserFrame} component instead." I would prefer a solution where a new window is opened, still it might be a solution in the end. – flavio.donze Sep 08 '16 at 11:46