Tatha
Tatha

Reputation: 161

StreamedContent not getting populated beyond RENDER_RESPONSE

I'm relatively new to JSF and Primefaces.
I'm trying to build a document viewer that would display tiff, jpeg and pdf.
My UI has a left and a right layout. Left layout contains a vertical grid of thumbnails of the docs. User clicks on a thumbnail, and the right layout displays the doc (either via a p:graphicImage or via a p:documentViewer, depending on the thumbnail clicked).
For tiffs, I'm converting the image into PNG and then displaying (both, for the thumbnail and the main display).
For multi-page tiff files, I show only the first page as the left side thumbnail...and for the main display, I give Next and Previous buttons to navigate through the pages. The UI is something like this: enter image description here

The problem:
When I click on the thumbnails, the backing method gets invoked twice as expected (the second call returning the StreamedContent with the actual data). However, when I click the Prev and Next buttons, the same backing method is getting called only once -- just for phaseid=RENDER_RESPONSE. (eventually, this causes the bean method to return only an empty StreamedContent and not one carrying the actual image data...so I don't get to see the other pages of the tiff)

The form:

<h:form id="mainform">
        <p:layout fullPage="true" style="width:100%;height:100%">
            <p:layoutUnit position="west" style="width:15%;overflow:scroll;" resizable="true">
                <p:panelGrid header="Thumbnails" columns="1" class="thumbcell" >

                    <p:repeat value="#{viewerController.docIds}" var="docId">


                                <p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('img')}" >

                                    <p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
                                        <p:graphicImage value="#{viewerController.imageDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;" 
                                        alt="#{viewerController.getDocumentName(docId)}">
                                            <f:param name="id" value="#{docId}" />
                                        </p:graphicImage>
                                    </p:commandLink>
                                    <p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>

                                </p:panelGrid>


                                <p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('tif')}">

                                    <p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
                                        <p:graphicImage value="#{viewerController.tifDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;" 
                                        alt="#{viewerController.getDocumentName(docId)}">
                                            <f:param name="id" value="#{docId}" />
                                            <f:param name="forThumbnail" value="true" />
                                        </p:graphicImage>
                                    </p:commandLink>
                                    <p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>

                                </p:panelGrid>


                                 <p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('pdf')}">

                                    <p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
                                        <p:graphicImage value="#{viewerController.pdfFirstPageDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;" 
                                        alt="#{viewerController.getDocumentName(docId)}">
                                            <f:param name="id" value="#{docId}" />
                                        </p:graphicImage>
                                    </p:commandLink>
                                    <p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>


                                </p:panelGrid>



                    </p:repeat>


                </p:panelGrid>
            </p:layoutUnit>

            <p:layoutUnit position="center" style="width:85%;">

                <p:panel id="renderpanel">


                    <p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('tif')}">
                        <p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/> 
                        <p:panelGrid style="padding:0px !important;" columns="3" id="tifPanelGrid">

                            <p:commandButton update=":mainform:renderpanel" action="#{viewerController.navigateTif('prev', viewerController.currentDocId)}" 
                            id="prevButton" value="Prev" title="Previous page" disabled="#{viewerController.prevButtonDisable}"/>

                                <p:graphicImage rendered="#{viewerController.render}" id="tifPanel" value="#{viewerController.tifDocumentStream}" style="height: 600px; width: 800px; border: none !important; padding:0px;background: lightgrey;" 
                                alt="#{viewerController.getDocumentName(viewerController.currentDocId)}">
                                    <f:param name="id" value="#{viewerController.currentDocId}" />
                                    <f:param name="forThumbnail" value="false" />
                                </p:graphicImage>

                            <p:commandButton update=":mainform:renderpanel" action="#{viewerController.navigateTif('next', viewerController.currentDocId)}" 
                            id="nextButton" value="Next" title="Next page" disabled="#{viewerController.nextButtonDisable}"/>

                        </p:panelGrid>  
                    </p:panelGrid>


                    <p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('img')}">  
                        <p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
                        <p:graphicImage value="#{viewerController.imageDocumentStream}" style="height: 600px; width: 800px; border: none !important; padding:0px;background: lightgrey;" 
                                            alt="#{viewerController.getDocumentName(viewerController.currentDocId)}">
                            <f:param name="id" value="#{viewerController.currentDocId}" />
                        </p:graphicImage>
                   </p:panelGrid>

                   <p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('pdf')}">  
                        <p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
                        <pe:documentViewer height="600" width="800" value="#{viewerController.pdfDocumentStream}" > 
                            <f:param name="id" value="#{viewerController.currentDocId}" /> 
                         </pe:documentViewer>

                   </p:panelGrid>

               </p:panel>

            </p:layoutUnit>
        </p:layout>

    </h:form>

The controller class is annotated with these two:

javax.annotation.ManagedBean
javax.enterprise.context.SessionScoped

The backing method in the controller class, that is not getting invoked twice:

public StreamedContent getTifDocumentStream() throws IOException {
    FacesContext context = FacesContext.getCurrentInstance();

    if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE ) {
        return new DefaultStreamedContent();
    } else {
        String id = context.getExternalContext().getRequestParameterMap().get("id");
        String forThumbnail = context.getExternalContext().getRequestParameterMap().get("forThumbnail");

        Doc doc = tifDocMap.get(id);

        InputStream is = this.convertTiffToPng(doc, forThumbnail);
        return new DefaultStreamedContent(is);

    }
}

I'm on this combination: SpringBoot + JoinFaces + PF 6.2

Can any body please advise what I'm doing wrong?

An alternate way I'm considering, to achieve the purpose: May be, turn the pages of the tiff to individual PNGs beforehand, and then use galleria ...but it would be nice if I could get galleria to work with StreamedContent of each page dynamically.

Upvotes: 0

Views: 360

Answers (0)

Related Questions