Search code examples
javaswingreflectionjasper-reports

How can I get JasperViewer to prioritize save option to PDF


I have an implementation where JasperViewer is used to preview and save reports. The first saving format offered by the viewer is .jrprint and I'm trying to change that to pdf. I'm employing the following method to help me with that

private static void promotePdfSaveFormat(JasperViewer jasperViewer) {
    /* get via reflection (with jOOR) the parameter JasperViewer object's member viewer (of type JRViewer) */
    JRViewer viewer = on(jasperViewer).call("viewer").get();
    /* get via reflection JRViewer object's member tlbToolBar (of type JRViewerToolbar) */
    JRViewerToolbar tlbToolBar = on(viewer).call("tlbToolBar").get();
    /* call tlbToolBar's getSaveContributors() */
    Arrays.stream(tlbToolBar.getSaveContributors()).forEach(
        e -> {
            /* Find the one that is of type JRPdfSaveContributor (using instanceof) */
            if (e instanceof JRPdfSaveContributor){
                /* set JRViewerToolbar object member lastSaveContributor value to the instance of JRPdfSaveContributor */
                on(tlbToolBar).call("lastSaveContributor").get();
            }
        }
    );
}

Everytime a new Object is created inside the class like JasperViewer viewer = new JasperViewer(...), I'm adding promotePdfSaveFormat(viewer) immediately after it. When I run the app, I get an error at JRViewer viewer = on(jasperViewer).call("viewer").get();

The error is as follows

org.joor.ReflectException: java.lang.NoSuchMethodException: No similar method viewer with params [] could be found on type class net.sf.jasperreports.view.JasperViewer.

Solution

  • After a thorough inspection, I realized that I was making a really stupid mistake. It was bound to throw NoSuchMethodException because the following lines are trying to access a method and not a field.

    JRViewer viewer = on(jasperViewer).call("viewer").get();
    JRViewerToolbar tlbToolBar = on(viewer).call("tlbToolBar").get();
    

    Then, I modified my method, to access field. The entire method looks like this now:

    private static void promotePdfSaveFormat(JasperViewer jasperViewer) {
        /* get via reflection the parameter JasperViewer object's member viewer (of type JRViewer) */
        JRViewer viewer = on(jasperViewer).field("viewer").get();
        /* get via reflection JRViewer object's member tlbToolBar (of type JRViewerToolbar) */
        JRViewerToolbar tlbToolBar = on(viewer).field("tlbToolBar").get();
        /* call tlbToolBar's getSaveContributors() */
        Arrays.stream(tlbToolBar.getSaveContributors())
            /* filter instance of type JRPdfSaveContributor */
            .filter(e -> e instanceof JRPdfSaveContributor)
            /* set JRViewerToolbar object member lastSaveContributor value to the instance of JRPdfSaveContributor */
            .forEach(e -> on(tlbToolBar).set("lastSaveContributor", e));
    }
    

    Now, JasperViewer shows PDF as the first saving option. enter image description here