Search code examples
javavaadinmenubar

Open pdf file from menubar using Vaadin


I have a menubar in my vaadin application and want to add an item to open a pdf-file is a new tab of the browser. I found some solutions to open files with a button, but I have to use an MenuItem...

MenuBar.Command commandHandler = new MenuBar.Command() {

    @Override
    public void menuSelected(MenuItem selectedItem) {

        if (selectedItem.equals(menu_help)) {
            openHelp();
        }
    }
};

...

menu_help = menuBar
            .addItem("", WebImageList.getImage(ImageList.gc_helpIcon),
                    commandHandler);

...


private void openHelp() {
   // open pdf-file in new window
}

Thanks for help!

SOLUTION:

private void openHelp() {
    final String basepath = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath();

    Resource pdf = new FileResource(new File(basepath + "/WEB-INF/datafiles/help.pdf"));
    setResource("help", pdf);
    ResourceReference rr = ResourceReference.create(pdf, this, "help");
    Page.getCurrent().open(rr.getURL(), "blank_");
} 

Attention: This code works, but the the structure of code is not perfect ;-) Better is to store "basepath" and "pdf" as attribute...


Solution

  • There is a similar problem described here: How to specify a button to open an URL? One possible solution:

    public class MyMenuBar extends MenuBar {
    
        ResourceReference rr;
    
        public MyMenuBar() {
            Resource pdf = new FileResource(new File("C:/temp/temp.pdf"));
            setResource("help", pdf);
            rr = ResourceReference.create(pdf, this, "help");
        }
    
        private void openHelp() {
            Page.getCurrent().open(rr.getURL(), "blank_");
        }
    
        ...
    }
    

    The setResource method of AbstractClientConnector is protected, so this is you need to extend some Vaadin component to make it work. This is why Im creating the class MyMenuBar here. If you are using an external resource you don't need to attach it to any component with setResource and then this is not nessecary.