How to use <p:graphicImage> with DefaultStreamedContent in an ui:repeat?
It is not possible to use <p:graphicImage>
this way. You should rather iterate over a collection of unique image identifiers, not over a collection of StreamedContent
. Those unique image identifiers have then to be passed as a <f:param>
to <p:graphicImage>
which in turn will generate the right URLs for the browser.
<ui:repeat value="#{data.imageIds}" var="imageId">
<p:graphicImage value="#{imageStreamer.image}">
<f:param name="id" value="#{imageId}" />
</p:graphicImage>
</ui:repeat>
Your #{data}
managed bean must just have a:
private List<Long> imageIds; // +getter
The #{imageStreamer}
should be a separate application scoped managed bean which look basically like this:
@ManagedBean
@ApplicationScoped
public class ImageStreamer {
@EJB
private ImageService service;
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Get ID value from actual request param.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}
Related videos on Youtube
user1433804
Updated on September 10, 2022Comments
-
user1433804 over 1 year
I was trying to display a panel where user can see a list of items category(displayed as images) and on clicking they can view products within the category(images will be displayed)
For displaying the item category, i used the ui:repeat nad the supporting bean calss Below is my xhtml code
<ui:repeat id="repeat" value="#{getData.images}" var="img" varStatus="loop"> <h:panelGroup> <p:graphicImage id="img1" value="#{img}" alt="image not available" > </p:graphicImage> </h:panelGroup> </ui:repeat>
And the Managed Bean Code parts
private ByteArrayOutputStream baos = new ByteArrayOutputStream(); private List<StreamedContent> imageList = new ArrayList<StreamedContent>(); public List<StreamedContent> getImages(){ for (int i = 0; i < sdh.getNumOfImages(); i++) { imageID = imageIDArray.get(i); ImageService imgSer = new ImageService(); imgList.add(imageID); imgSer.setData(imageID); baos = imgSer.getImage(); try { imageList.add(new DefaultStreamedContent(new ByteArrayInputStream(baos.toByteArray()))); } catch (Exception ex) { ex.printStackTrace(); } } imageNum = 0; return imageList; } public StreamedContent getData() { baos = imageList.get(imageNum); //imageList.add(baos); imageNum++; return new DefaultStreamedContent(new ByteArrayInputStream(baos.toByteArray())); }
Now my problem if i don't uncomment the 'imageList.add(baos)' in 'getData', the images are not displayed. Now i really wants to know how the 'ui:repeat' works, since the 'imageList' contains the images and i can save the same if required in either of the method. If i specify a fixed number (ex:'imageList.get(0)') in the 'getData' method then the same image is show multiple times. Where as if i put the 'imageNum' without the 'imageList.add(baos)' it throw error 'Error in streaming dynamic resource'
I tired Bjorn Pollex's suggestion and made the necessary changes but now images don't appear
-
Björn Pollex almost 12 yearsYou are not referencing the loop-variable (
img
in your case) inside your<ui:repeat>
. YourgetImages
should return aList<StreamedContent>
, and your<p:graphicImage>
should havevalue="#{img}"
.
-