我对 JSF 和 Primefaces 比较陌生。
我正在尝试构建一个显示 tiff、jpeg 和 pdf 的文档查看器。
我的 UI 有左右布局。左侧布局包含文档缩略图的垂直网格。用户单击缩略图,正确的布局显示文档(通过 ap:graphicImage 或通过 ap:documentViewer,取决于单击的缩略图)。
对于 tiff,我将图像转换为 PNG,然后显示(缩略图和主显示)。
对于多页 tiff 文件,我仅将第一页显示为左侧缩略图……而对于主显示,我提供 Next 和 Previous 按钮来浏览页面。用户界面是这样的:
问题:
当我单击缩略图时,支持方法被调用两次(第二次调用返回带有实际数据的 StreamedContent)。但是,当我单击 Prev 和 Next 按钮时,仅调用一次相同的支持方法——仅用于 phaseid=RENDER_RESPONSE。(最终,这会导致 bean 方法只返回一个空的 StreamedContent 而不是携带实际图像数据的......所以我看不到 tiff 的其他页面)
表格:
<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>
控制器类使用以下两个注释:
javax.annotation.ManagedBean
javax.enterprise.context.SessionScoped
控制器类中的支持方法,不会被调用两次:
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);
}
}
我在这个组合上:SpringBoot + JoinFaces + PF 6.2
任何人都可以告诉我我做错了什么吗?
为了达到目的,我正在考虑另一种方法: 可能是事先将 tiff 的页面转换为单独的 PNG,然后使用 Galleria ...但如果我能让 Galleria 与每个的 StreamedContent 一起工作会很好页面动态。