My situation is a little unusual; I'll explain and then provide some code. We have an application that has multiple tabbed views of a document, and one of the tabs is meant to display the raw page images (jpg) of that document. In the case of all the tabs, content should be loaded after the document is explicitly loaded from a dropdown list. The problems we're having are with this particular tab.
For these raw page images, we opted to provide them from a servlet instead of as dynamic content. The reason is so we can take advantage of caching. I've tried this with dynamic content, and it was actually even more problematic (using f:param and DefaultStreamedContent). So for that reason and for caching purposes, we changed to this approach.
What we're seeing is strange. Network traffic shows that the images are indeed being loaded. However, the carousel is initially blank and empty. However, upon reloading the page, the carousel and its images now appear. As far as I can tell, I am properly updating components. When I turn off Ajax for the load button, this problem goes away.
However, there is yet another problem, even when the carousel appears. If the carousel tab itself was being displayed when the images are loaded, then its forward and back navigation buttons don't work. The first page shows fine, but clicking on the page link "circles" will only show the second and third page (we're only loading three test pages as of now), and the third slot for a page is completely blank.
I've tested this out simply by putting the graphicImage on its own, outside the carousel. We still encounter the issue that we need to refresh to display the image, even in such cases.
Anyway, here's code for the relevant parts:
Image servlet -
Code: Select all
private Pattern pageUrlPattern = Pattern.compile(".*-(\\d+)\\.jpg$");
@Inject
BackingBean backingBean;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestedUri = request.getRequestURI();
Matcher pageUrlMatcher = pageUrlPattern.matcher(requestedUri);
if (pageUrlMatcher.find()) {
// get page image object
String pageNumberText = pageUrlMatcher.group(1);
int pageNumber = Integer.parseInt(pageNumberText);
PageImage pageImage = backingBean.getPageNumberToImage().get(pageNumber);
// set content type
response.setContentType("image/jpeg");
// stuff page image bits into response
try (OutputStream outStream = response.getOutputStream(); InputStream inStream = pageImage.getPageStream()) {
int dataSize = inStream.available();
byte[] data = new byte [dataSize];
inStream.read(data);
outStream.write(data);
}
}
}
Code: Select all
public InputStream getPageStream() {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ImageIO.write(pageImage, "image/jpeg", byteOut);
return new ByteArrayInputStream(byteOut.toByteArray());
}
Code: Select all
<p:commandButton value="Load"
id="loadSpecificationButton"
actionListener="#{backingBean.loadSelectedSpecification()}"
update=":form:documentTabView:rawDocumentScrollPanel :form:documentTabView:rawPageImageCarousel :form:documentTabView:rawPageImageMissingMessage :form:documentTabView:pageImageTab :form:documentTabView:rawPageImageCarousel:pageImageDisplay"
disabled="#{! backingBean.isSpecificationSelected()}"
oncomplete="openSpecMenuDialog.hide();"
>
...
<p:tab id="pageImageTab" title="Raw Document">
<p:scrollPanel mode="native" style="height:292px;width:auto;overflow:auto" id="rawDocumentScrollPanel" rendered="#{backingBean.areTherePages()}">
<p:carousel id="rawPageImageCarousel" value="#{mbssMapper.pageImages}" var="pageImage" rows="1" rendered="#{mbssMapper.areTherePages()}">
<p:panelGrid columns="1" style="border:0px white none !important">
<h:outputText value="Page #{pageImage.pageNumber} of #{backingBean.pageImages.size()}"/>
<p:graphicImage id="pageImageDisplay" value="#{pageImage.url}" style="height:850px;min-width:1280px;">
<f:param name="pageNumber" value="#{pageImage.pageNumber}"/>
</p:graphicImage>
</p:panelGrid>
</p:carousel>
</p:scrollPanel>
<p:panel id="rawPageImageMissingMessage" style="border:0px white none" rendered="#{! backingBean.areTherePages()}">
<b>No document is loaded</b>
</p:panel>
</p:tab>