[RESOLVIDO] mudar imagem dinamicamente com <h:selectItem>

10 respostas
robertoJames

ola pessoal,

sera que vocês vao poder me ajudar. Eu tenho o seguinte cenario:

tenho um selectItem que vai trazer o nome de 3 imagens: cachorro, gato e cavalo. Dentro do banco, eu inseri o caminho de onde estao as imagens, ou seja, cachorro está em: c:/img/cachorro, gato c:/img/gato e cavalo c:/img/cavalo. Eu queria saber como eu faço para mostrar a imagem na tela conforme seja escolhido dentro do selectItem.

Como faço isso? a4j ?

10 Respostas

Ygor

Sim, vai ser utilizando ajax.

Tu pode criar uma graphicImage que tenha como value um atributo de um manegedBean que vai retornar o link da img a ser exibida.
Quando tu modificar o selectItem ira chamar uma função que ira modificar esse atributo do manegedBean e depois dar um reRender/upDate na tag graphicImage, ou no container dela.

robertoJames

e então,

você não teria nenhum exemplo pequeno para eu testar ? pois tentei utilizar o seguinte:

MBean

public class FiguraMBean {

	
	 public void paint(OutputStream out, Object data) throws IOException{
	        if (data instanceof FiguraData) {

	            FiguraData paintData = (FiguraData) data;
	            BufferedImage img = new BufferedImage(paintData.getWidth(),paintData.getHeight(),BufferedImage.TYPE_INT_RGB);
	            Graphics2D graphics2D = img.createGraphics();
	            graphics2D.setBackground(paintData.getBackground());
	            graphics2D.setColor(paintData.getDrawColor());
	            graphics2D.clearRect(0,0,paintData.getWidth(),paintData.getHeight());
	            graphics2D.drawLine(5,5,paintData.getWidth()-5,paintData.getHeight()-5);
	            graphics2D.drawChars(new String("RichFaces").toCharArray(),0,9,40,15);
	            graphics2D.drawChars(new String("mediaOutput").toCharArray(),0,11,5,45);

	            ImageIO.write(img,"jpeg",out);

	        }
	    }

	    private void copy(InputStream in, OutputStream out) throws IOException {
	        byte[] buffer = new byte[2048];
	        int read;
	        
	        while ((read = in.read(buffer)) != -1) {
	            out.write(buffer, 0, read);
	        }
	    }
	    
	    public void paintFlash(OutputStream out, Object data) throws IOException {
	        ClassLoader loader = Thread.currentThread().getContextClassLoader();
	        if (loader == null) {
	            loader = getClass().getClassLoader();
	        }
	        
	        InputStream stream = loader.getResourceAsStream("c:/img/cachorro.jpg");
	        if (stream != null) {
	            try {
	                copy(stream, out);
	            } finally {
	                stream.close();
	            }
	        }
	    }

*.jsp

<a4j:region>	
<a4j:mediaOutput element="img" cacheable="false" session="true"
        createContent="#{figuraMBean.paintFlash}" value="#{figuraData}" mimeType="image/jpg" />
    <br/><br/>
    
</a4j:region>

entidade

public class FiguraData implements Serializable{

    private static final long serialVersionUID = 1L;
    Integer Width=250;
    Integer Height=250;
    Color Background=new Color(0,0,0);
    Color DrawColor=new Color(255,255,255);
    public FiguraData() {
    }
    public Color getBackground() {
        return Background;
    }
    public void setBackground(Color background) {
        Background = background;
    }
    public Color getDrawColor() {
        return DrawColor;
    }
    public void setDrawColor(Color drawColor) {
        DrawColor = drawColor;
    }
    public Integer getHeight() {
        return Height;
    }
    public void setHeight(Integer height) {
        Height = height;
    }
    public Integer getWidth() {
        return Width;
    }
    public void setWidth(Integer width) {
        Width = width;
    }
}

tentei e não deu certo.

robertoJames

bom dia pessoal,

ninguém para me dar uma idéia legal ?

robertoJames

Bem, como eu estou aprendendo a utilizar o a4j:outMedia,

eu fiz o seguinte,

public class MediaBean {

		private MediaData mediaData = new MediaData();
		
		
		public void paint(OutputStream stream, Object object) throws IOException {
	        MediaData img = (MediaData) object;
	        stream.write(img.getData());

	}

		public void setMediaData(MediaData mediaData) {
			this.mediaData = mediaData;
		}

		public MediaData getMediaData() {
			return mediaData;
		}
	}
public class MediaData implements Serializable{

    private static final long serialVersionUID = 1L;
    Integer Width=110;
    Integer Height=50;
    Color Background=new Color(0,0,0);
    Color DrawColor=new Color(255,255,255);
    
    File teste = new File("c:\\img\\cachorro.jpg");
    
    //private File tempFile; //Arquivo que vêm do upload
    
  
    
    public byte[] getData() throws FileNotFoundException {
            byte[] buffer = null;
            try {
                InputStream is = new FileInputStream(teste);
                buffer = new byte[is.available()];
                is.read(buffer);
                is.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return buffer;

    }
<a4j:region>
	<a4j:mediaOutput   element="img" 

mimeType="image/jpeg"
                    createContent="#{mediaBean.paint}"
value="#{mediaBean.mediaData}"
                    cacheable="false" session="false"/> 
	</a4j:region>

E isso já está funcionando,

agora eu quero saber como eu vou colocar um h:selectItem, e ele reRendered esse mediaOutput dinamicamente ?

robertoJames

Boa tarde pessoal,

estou aqui tentando reformular meu código para oq eu realmente preciso. E no momento eu estou tentando fazer o codigo abaixo, porém não está funcionando

jsp

<h:panelGroup id="painel_img_pai" >
		 
		 <h:selectOneMenu value="#{mediaBean.municipio.codigo}" id="codOrgao" >   
                        <f:selectItems value="#{mediaBean.listaDeMunicipios}" />  
                        <a4j:support  reRender="painel_orgao_externo" event="onchange"   
                action="#{mediaBean.mudarUrl}"/> 
                    </h:selectOneMenu>   
		
		<h:panelGroup id="painel_orgao_externo"   rendered="true">
		
		<a4j:region>
		<a4j:mediaOutput   element="img" 
			mimeType="image/jpeg"
                    createContent="#{mediaBean.paint}"
value="#{mediaBean.mediaData}"
                    cacheable="false" session="false"/> 
	</a4j:region>
		
		
		</h:panelGroup>
		
	</h:panelGroup>

MB

public class MediaBean {

		private MediaData mediaData = new MediaData();
		private Municipio municipio = new Municipio();
		private MunicipioDAO municipioDao = new MunicipioDAO();
	    private List<Municipio> listaTdsMunicipios = new ArrayList<Municipio>();
		private List<SelectItem> listaDeMunicipios = new ArrayList<SelectItem>();
		
		
		public void mudarUrl(){
			
			
			
			mediaData.setCaminhoImagem(this.municipio.getUrl());
			
		}
		
		
		
		public void paint(OutputStream stream, Object object) throws IOException {
	        MediaData img = (MediaData) object;
	        if(img.getData() != null){
	        
	        stream.write(img.getData());
	        }
	}
		
		public List<SelectItem> listarMunicipios(){
			
			List<SelectItem> listaMunicipios = new ArrayList<SelectItem>();
		
			List<Municipio> listaObjetos = new ArrayList<Municipio>();
			
			listaObjetos = municipioDao.listarTdsMunicipios();
			
			//this.listaTdsMunicipios = municipioDao.listarTdsMunicipios();
			
			for (Municipio municipio : listaObjetos) {
				
				listaMunicipios.add(new SelectItem(municipio.getCodigo(),
						 municipio.getNome()));
			}
			
			return listaMunicipios;
			
		}

MediaData

public class MediaData implements Serializable{

    private static final long serialVersionUID = 1L;
    Integer Width=110;
    Integer Height=50;
    Color Background=new Color(0,0,0);
    Color DrawColor=new Color(255,255,255);
    private String caminhoImagem;
    private String imagem = "";
    
    //File teste = new File("c:\\img\\cachorro.jpg");
    
    
    
    
    
    public byte[] getData() throws FileNotFoundException {
    		String imagem = this.getCaminhoImagem();
    		byte[] buffer = null;
    		
    		if(imagem != null){
    		
            try {
            	
                InputStream is = new FileInputStream(imagem);
                buffer = new byte[is.available()];
                is.read(buffer);
                is.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
    		}
            return buffer;
    		
    }

Alguem poderia me ajudar?

O que eu estou tentando fazer é o seguinte: quando a pessoa selecionar um selectItem da lista, ele mostrar a imagem referente aquele selectItem.

R

Você esta no caminho certo, usando a4j:support

Não olhei o código com calma, vi só o xhtml porque não estou com muito tempo... Mas um bom exemplo de utilização do a4j:support para esse tipo de coisa, tem aqui:
http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/a4j_support.html

O pouco que eu vi está correto, mas faz um teste primeiro, troque os valores da imagem utilizando um h:commandButton

Eu tive problemas com o mediaOutput, porque ele sempre carregava a primeira imagem e não mudava mais usando a4j:commandButton/support.. mas quando eu mudava a imagem com uso de h:commandButton, funcionava normal

A solução pra mim foi colocar o mediaOutput dentro de um a4j:outputPanel e associar o "value" direto com a URL da imagem, mais ou menos assim:

<a4j:outputPanel>
      <a4j:mediaOutput element="img" cacheable="false" session="true" value="#{controller.usuario.foto}" createContent="#{controller.paint}"
                                 mimeType="image/jpg" style="width: 105px; height: 120px;"/>
</a4j:outputPanel>

Onde controller.usuario.foto = algo como \\192.168.0.1\...\Fotos\xxx.jpg

E esse é meu método paint(). Nesse método tem 3 maneiras (ou 2, não li pra lembrar) de fazer aparecer a imagem...

public void paint(OutputStream out, Object data) throws IOException {        
        try {
            File file = null;

            //Pega a foto associada ao usuário
            if (usuario.getFoto() != null && !usuario.getFoto().equals(""))
                file = new File(usuario.getFoto());
            //Caso a foto não exista, é exibida a imagem de "FOTO NÃO ECONTRADA"
            else if (!file.exists())
                file = new File("/images/PhotoNotFound.jpg");
            //Caso não possua, é exibia a imagem de "SEM FOTO DEFINIDA"
            else
                file = new File("/images/NoPhoto.jpg");

            //Responsáveis por "escrever" a foto no a4j:mediaOutput.
            BufferedImage image = ImageIO.read(file);
            ImageIO.write(image, "jpg", out);

            //Isso tambem funciona, mas pelo jeito virará deprecated logo...
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//            encoder.encode(ImageIO.read(file));

            //Outra maneira que tambem funciona...
//            byte[] buffer = null;
//            InputStream is = new FileInputStream(file);
//            buffer = new byte[is.available()];
//            is.read(buffer);
//            is.close();
//            out.write(buffer);
        } catch(Exception e) {
            Recursos.getStackTraceToFile(e, "controller.paint()");
            Recursos.setMessage("error", "Não foi possível carregar a foto.");
        }
    }

Lembre-se que o reRender é no a4j:outputPanel
Espero que essa lenda toda te ajude em algo... Boa sorte

robertoJames

Antes de testar oq o amigo acima falou,

eu tentei simplificar fazendo da seguinte forma:

<f:view>

		<a4j:form id="form_ajax">
		
		<h:panelGroup id="painel_img_pai" >
		 
		 <h:selectOneMenu value="#{mediaBean.municipio.codigo}" id="codOrgao" >   
                        <f:selectItems value="#{mediaBean.listaDeMunicipios}" />  
                        <a4j:support event="onchange"  ajaxSingle="true" action="#{mediaBean.mudarUrl}"

                reRender="painel_orgao_externo"/>
                       
                    </h:selectOneMenu>   
		
		<h:panelGroup id="painel_orgao_externo" >
		
	
		<h:graphicImage value="#{mediaBean.municipio.url}"/>

		
		
		</h:panelGroup>
		
	</h:panelGroup>
		
		

		
		
		
		
		</a4j:form>
		
</f:view>

mas da o erro do tipo:

28/09/2010 15:29:53 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.ClassNotFoundException: org.apache.xerces.xni.parser.XMLConfigurationException
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
	at org.ajax4jsf.webapp.ConfigurableXMLFilter$NekoParserConfig.createParser(ConfigurableXMLFilter.java:162)
	at org.ajax4jsf.webapp.ParserConfig.getParser(ParserConfig.java:49)
	at org.ajax4jsf.webapp.ConfigurableXMLFilter.getParser(ConfigurableXMLFilter.java:130)
	at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:271)
	at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
	at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
	at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
	at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:574)
	at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1527)
	at java.lang.Thread.run(Unknown Source)

Qual melhor jeito de tentar fazer ?

robertoJames

mudei para o seguinte código:

<f:view>

		<a4j:form id="form_ajax">
		
		<h:panelGroup id="painel_img_pai" >
		 
		 <h:selectOneMenu value="#{mediaBean.municipio.codigo}" id="codOrgao" >   
                        <f:selectItems value="#{mediaBean.listaDeMunicipios}" />  
                        <a4j:support  reRender="painel_orgao_externo" event="onchange"   
                action="#{mediaBean.mudarUrl}"/> 
                    </h:selectOneMenu>   
		
		<h:panelGroup id="painel_orgao_externo"   rendered="true">
		
		<a4j:outputPanel>
		<a4j:mediaOutput   element="img" 
			mimeType="image/jpeg"
                    createContent="#{mediaBean.paint}"
value="#{mediaBean.mediaData.caminhoImagem}"
                    cacheable="false" session="false" style="width: 105px; height: 120px;"/> 
	
		
		</a4j:outputPanel>
		</h:panelGroup>
		
	</h:panelGroup>

e continua dando o mesmo erro.

28/09/2010 16:21:14 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.ClassNotFoundException: org.apache.xerces.xni.parser.XMLConfigurationException
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
	at org.ajax4jsf.webapp.ConfigurableXMLFilter$NekoParserConfig.createParser(ConfigurableXMLFilter.java:162)
	at org.ajax4jsf.webapp.ParserConfig.getParser(ParserConfig.java:49)
	at org.ajax4jsf.webapp.ConfigurableXMLFilter.getParser(ConfigurableXMLFilter.java:130)
	at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:271)
	at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
	at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
	at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
	at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:574)
	at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1527)
	at java.lang.Thread.run(Unknown Source)

Alguém saberia me explicar ?

robertoJames

ninguem ?

robertoJames

Problema resolvido.

Aqui ficou o código:

<h:form id="form_ajax">
		
		<a4j:region id="teste">
		
		<a4j:outputPanel id="painel_img_padrao">
		
		 <h:selectOneMenu value="#{mediaBean.municipio.codigo}" id="codOrgao" >   
                        <f:selectItems value="#{mediaBean.listaDeMunicipios}" />  
                        <a4j:support  reRender="painel_img_secundario" event="onchange"  ajaxSingle="true" 
                action="#{mediaBean.mudarUrl}"/> 
                    </h:selectOneMenu> 
           
        </a4j:outputPanel>
                    
                    
			<a4j:outputPanel id="painel_img_secundario" ajaxRendered="true">
		
		<h:graphicImage url="#{mediaBean.mediaData.caminhoImagem}"/>
		</a4j:outputPanel>
		
	
		</a4j:region>
		
		
		</h:form>

aqui ficou meu MB

public void paint(OutputStream stream, Object object) throws IOException {
			
			try{
			 File file = null;  
			  
			 
	            //Pega a foto associada ao usuário  
	            if (mediaData.getCaminhoImagem() != null && !mediaData.getCaminhoImagem().equals("")){ 
	                file = new File(mediaData.getCaminhoImagem());  
	            //Caso a foto não exista, é exibida a imagem de "FOTO NÃO ECONTRADA"  
	          
	            //Responsáveis por "escrever" a foto no a4j:mediaOutput.  
	            BufferedImage image = ImageIO.read(file);  
	            ImageIO.write(image, "jpg", stream);  
	            }
	            //Isso tambem funciona, mas pelo jeito virará deprecated logo...  
//	            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
//	            encoder.encode(ImageIO.read(file));  
	  
	            //Outra maneira que tambem funciona...  
//	            byte[] buffer = null;  
//	            InputStream is = new FileInputStream(file);  
//	            buffer = new byte[is.available()];  
//	            is.read(buffer);  
//	            is.close();  
//	            out.write(buffer);  
	        } catch(Exception e) {  
	           e.printStackTrace();
	        }
			
	}

agradeço a todos.

Criado 21 de setembro de 2010
Ultima resposta 29 de set. de 2010
Respostas 10
Participantes 3