JSF jsf/sessionScoped Bean - Bilder (jpg) werden nicht richtig dargestellt

Hannana32

Neues Mitglied
Hallo!

Ich versuche derzeit ein Memory-Spiel zu programmieren. Momentan stecke ich an einer Stelle fest und auch google kann mir diesmal nicht weiterhelfen... würde mich sehr freuen, wenn es eine(r) von euch kann!

Also, das hier ist die JSF-Datei:

Code:
<?xml version="1.0" encoding = "UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.org/ui"  
	template="WEB-INF/templates/default.xhtml">
	<ui:define name = "header">
		Du gegen die Zeit
	</ui:define>
	<ui:define name = "content">
		<h:form acceptcharset="ISO-8859-1">

			<p:dataGrid id="cardGrid" value="#{gameController.cardList}" var="card" columns="3" >
				<p:column>
			  	  	<p:graphicImage value="#{imageService.image}" height="#{imgSizeCalculator.imgWidth}" width="#{imgSizeCalculator.imgWidth}">
				  		<f:param name="cardId" value="#{card.id}"/>
				  	</p:graphicImage>
				 </p:column>
			</p:dataGrid>
		
		</h:form> 
		
	</ui:define>
</ui:composition>

Und hier sind die zugehörigen Beans:

Java:
package de.hawi.gaming.memory.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import de.hawi.gaming.memory.model.Card;
import de.hawi.gaming.memory.model.DiffLevel;
import de.hawi.gaming.memory.model.Game;

@Named
@SessionScoped
public class GameController implements Serializable {

	private static final long serialVersionUID = -520941187189740659L;
	private Game game;
	
	@Inject
	private DiffLevelController dlc;
	@Inject
	private PlayerController pc;

	public GameController() {
		
	}
	
	@PostConstruct
	public ArrayList<Card> initCards() {

		game = new Game(pc.getPlayerList());
		game.setDiffLevel(dlc.getDiffLevel());
		
		if(game.getCards() != null && (!game.getCards().isEmpty())) 
			return game.getCards();
		
		game.setCards(new ArrayList<Card>());
		File imageDir = new File("D:/Programme/java_ee/workspace/memory/target/memory/resources/images/cards");
		File[] images = imageDir.listFiles();
		int id = 0;
			
		//Bilder in cardList speichern
		for (File image : images) {
			if(image.getName().endsWith(".jpg") || image.getName().endsWith(".JPG")) {
				try {
					
					InputStream is = new FileInputStream(image);
					StreamedContent sc = new DefaultStreamedContent(is);

					//zwei mal das gleiche Bild hinzufügen
					game.getCards().add(new Card(sc, sc));
					game.getCards().add(new Card(sc, sc));
				} catch (IOException e) {
					System.out.println("ERROR: could not load resources");
				}
			}
		}
		
		DiffLevel dl = dlc.getDiffLevel();
		
		int lastIndex = 8;
		if(dl.equals(DiffLevel.DIFF16))
			lastIndex = 16;
		if(dl.equals(DiffLevel.DIFF24))
			lastIndex = 24;
		
		game.setCards(new ArrayList<Card>(game.getCards().subList(0, lastIndex)));
		
		//cardList mischen
		Collections.shuffle(game.getCards());
		
		//id setzen
		for(Card c : game.getCards()) {
			c.setId(id);
			id++;
		}
		return game.getCards();
	}

	public Game getGame() {
		return game;
	}


}

und

Java:
package de.hawi.gaming.memory.service;

import java.io.Serializable;
import java.util.ArrayList;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import de.hawi.gaming.memory.controller.GameController;
import de.hawi.gaming.memory.model.Card;
import de.hawi.gaming.memory.model.DiffLevel;
import de.hawi.gaming.memory.model.Game;
import de.hawi.gaming.memory.model.Player;


@RequestScoped
@Named
public class ImageService implements Serializable {

	private static final long serialVersionUID = -7293644627867835209L;

	@Inject
	private GameController cs;
	
	
	public ImageService() {
	}

	public StreamedContent getImage() {
		
		FacesContext context = FacesContext.getCurrentInstance();
		StreamedContent image = null;  
	        
        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
            return new DefaultStreamedContent();
        }
        else {
            // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
            String cardId = context.getExternalContext().getRequestParameterMap().get("cardId");
         
            ArrayList<Card> cardList = cs.getGame().getCards();
            
            for(Card c : cardList) {
            	if(Integer.valueOf(cardId) == c.getId())
            		image = c.getFront();
            }
            		
        }
        return image;
        
        }
    	
}

Das ganze sieht dann folgendermaßen aus:

fehler1.jpg

Warum werden manche Bilder nicht richtig geladen/dargestellt?
Wenn ich den Scope der Klasse GameController von SessionScope in RequestScope ändere, werden die Bilder korrekt dargestellt. Allerdings stimmt dann die Logik nicht mehr, die Bilder sollen ja nur ein mal pro Spiel geladen werden, dann jedes Bild doppelt abgespeichert, gemischt etc.. Das geht mit RequestScope natürlich nicht, das ist mir klar. Aber ich verstehe nicht warum die Bilder einmal korrekt und einmal fehlerhaft dargestellt werden? Kann mir das jemand erklären?

Ich freue mich über konstruktive Kritik, mir ist bewusst das es bestimmt nicht der schönste Code ist.

LG
Hanna
 
Sorry, da hatte sich noch ein Fehler eingeschlichen..

Es muss natürlich
Code:
<p:dataGrid id="cardGrid" value="#{gameController.game.cards}" var="card" columns="3" >
heißen..


Noch mal eine Kurzzusammenfassung meines Problems:

In der Klasse GameController werden Bilder(jpg) aus einer Datei gelesen und in einer ArrayList als StreamedContent gespeichert. Diese sollen dann in onePlayerGame.jsf in einem dataGrid dargestellt werden. (Dabei habe ich mich an folgendem Beispiel orientiert www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CC8QFjAA&url=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F19732609%2Fgetting-pgraphicimage-from-byte-column-db&ei=oP4RU8WRGcSqtAbigIHgCg&usg=AFQjCNEtzWubsMPlvE_fjWiB6CX7RVoj0g&bvm=bv.62286460,d.Yms)
Wenn GameController requestScoped ist funktioniert das grundsätzlich (allerdings ist die Logik dann dahin), wenn GameController sessionScoped ist werden die Bilder fehlerhaft dargestellt. Ich verstehe nicht warum das so ist. Weiß es jemand?
 

Zurück
Oben