Ícone na JTable quase OK

7 respostas
U

Pessoal, tenho que exibir na minha JTable uma coluna com um ícone que representará o estado dos dados no sistema (0 = iconeCD, 1 = iconeBD).

a classe IMAGEM é descrita logo abaixo:
package com.sismed.tablemodel;

import java.awt.Component;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class Imagem extends JLabel implements TableCellRenderer{
	String codigo;
	public Imagem(int cod){
		    switch (cod){
		    case 0:
		    	codigo = "c:\\iconeCD.jpg";
		        break;
		    case 1:
		    	codigo = "c:\\iconeBD.jpg";
		        break;		    
		    }
	   	    setOpaque(true);
	   }
	   
	   public Component getTableCellRendererComponent(JTable table, 
	      Object value, boolean isSelected, boolean hasFocus, int row, 
	      int column){
	     
	      Icon imagem = new ImageIcon(codigo);
	      // certifique-se da existencia da imagem "icon.gif" antes de executar
	     
	      if(isSelected)
	        setBackground(table.getSelectionBackground());
	      else
	        setBackground(table.getBackground());		
	      
	      setIcon(imagem);
	      //setText(value.toString());
	      	
	      return this;   	
	   }
	   
	   public void validate() {}
	   public void revalidate() {}
	   protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
	   public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
}

 }

Após listar a tabela, executo o seguinte código:

TableCellRenderer tcr = new Imagem(1);
TableColumn column = tabelaArquivamento.getColumnModel().getColumn(1);		    
column.setCellRenderer(tcr);

o problema é que eu preciso setar cada celula(x,1) - onde x é o numero da linha e 1 é a coluna que contém o ícone - com o ícone correspondente ao dado representado (1 ou 2) e as instruções acima setam o ícone de todas as celulas (x,1).

Tentei criar o seguinte laço para alterar os ícones após preencher a tabela:
Iterator iterator = lista.iterator();
int posicao = 0;
Cliente cliente = new Cliente();
while (iterator.hasNext())
{				
   cliente = (Cliente)iterator.next();
   imagem = new Imagem(cliente.getEstado());
   tabelaArquivamento.setValueAt(imagem,posicao,1);
   posicao ++;				
}

Mas não obtive sucesso. Alguém sabe o que posso fazer para alterar os ícones de forma a representarem o estado do cliente de forma correta (1 ou 0 pra cada linha, e não para toda a coluna).

7 Respostas

F

Voce precisa entender melhor como funciona a JTable pra fazer isso…

Uma tabela, tem um model, esse model tem uma estrutura de dados(no defaultlistmodel é uma matriz eu acho) que pode representar os valores da tabela.

o renderer, é uma classe responsável por renderizar os elementos do model, ou seja, quando voce diz que vc tem um renderer que herda de jlabel, suas celulas sao jlabels.

o que voce pode fazer é no metodo public Component getTableCellRendererComponent pegar a linha (int row) buscar na lista de clientes o cliente, ver o estado dele e escolher o icone.

o seu erro é que seu icone está fixo no getTableCellRenderer(sempre retorna o mesmo icone). nesse metodo tem que ter algum processo de escolha do icone, como eu ja sugeri

esse metodo é chamado sempre que o swing precisar pintar a tabela ou quando o model for alterado…

espero que tenha ajudado hehe

U
Vou fazer diferente, adicionei no meu modelo o vetor de Imagem...
private         Imagem[] icones            = null;
e seto no construtor do TableModel:
for (int i=0; i<vetExames.length;i++){
			icones[i] = new Imagem (vetExames[i].getCodexa().intValue());
		}
Porém, no getValueAt do Modelo, tem-se:
case 1:				
				return icones[linha];

porém não exibe o ícone e sim todas as informações sobre o objeto, o que tenho q fazer?

F

vc nao retorna o icone e sim o Jlabel com o icone

this.setIcon(icone);
return this;
U

Como assim, não entendi, meu modelo possui um vetor de imagens que são os ícones de todas as linhas, num possui um Icon único.

F

cara… eu to falando do TableCellRenderer

no metodo dele q voce tem q escolher um icone e fazer oq eu te falei…

o modelo so deve ter os dados…

a parte grafica é montada no renderer… parecido como voce fez… so q dentro do metodo que retorna um Component, voce escolhe o icone desejado e seta o icone no jlabel e retorna ele proprio(this)

U

Pessoal, há alguns dias tive uma certa dificuldade em implementar uma JTable que exibisse na coluna 1 um ícone, de acordo com o status do Cliente no BD. Após muita luta consegui implementar e aqui estão todas as classes e implementações que tive que criar. Obrigado aos que me ajudaram e espero que esse “guia” lhes ajude.
Att Ulisses Nunes

Classe que implementa CellRender

package com.cliente.tablemodel;

import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;

public class ArquivamentoCellRenderer extends DefaultTableCellRenderer{
	protected void setValue(Object value) {
	    if (value instanceof DataWithIcon) {
	      if (value != null) {
		        DataWithIcon d = (DataWithIcon)value;
		        Object dataValue = d.getData();		
		        setText(dataValue == null ? "" : dataValue.toString());
		        setIcon(d.getIcon());		        
	      } else {
		        setText("");
		        setIcon(null);
	      }
	    } else {
	      super.setValue(value);
	    }
	 }
}

Classe DataWithIcon

package com.cliente.tablemodel;

import javax.swing.Icon;
import javax.swing.ImageIcon;

class DataWithIcon {
	  protected Icon   icon;	
	  protected Object data;
	  
	  public DataWithIcon(Object data, int estado) {
		  switch (estado){            
		    case 0:		    	                   
		    	this.icon = new ImageIcon("c:\\Icone1.png");
		        break;
		    case 1:
		    	this.icon = new ImageIcon("c:\\Icone2.png");
		        break;
		    case 2:
		    	this.icon = new ImageIcon("c:\\Icone3.png");
		        break;
		    case 3:
		    	this.icon = new ImageIcon("c:\\Icone4.png");
		        break;
		    }	
	    this.data = data;	    
	  }
	  public Icon getIcon() {
	    return icon;
	  }
	
	  public Object getData() {
	    return data;
	  }
	
	  public String toString() {
	    return data.toString();
	  }  
}

TableModel:

package com.cliente.tablemodel;

import com.cliente.persistencia.exame.Exame;

import java.awt.Component;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

public class ArquivamentoTableModel extends AbstractTableModel
{
	protected static final int COLUMN_COUNT = 5;
	private Exame[]  vetorExames = null;	
	private static 	String[] rotulosDasColunas = {"ID", "Status", "Nome", "Endereço", "Nascimento"};
		
	/** 
	 *  Uma instância dessa classe deve necessariamente estar ligada a um array de pacientes.
	 */
	public ArquivamentoTableModel(Exame[] vetExames)
	{
		vetorExames = vetExames;					
	}

	public String getColumnName(int column) {
		    return rotulosDasColunas[column];
	}
	 
	public Exame[] getVetorExames() {
		return vetorExames;
	}

	public void setVetorExames(Exame[] vetorExames) {
		this.vetorExames = vetorExames;
	}

	public boolean isCellEditable(int row, int col)
        { 
		return false; 
	}
	
	/** 
	 * Esse método retorna o valor que deve ser impresso
	 * em cada célula da tabela.
	 */
	public Object getValueAt(int linha, int coluna)
	{
		Date data = new Date();
		SimpleDateFormat  sdf   = new SimpleDateFormat("dd/mm/yyyy");
		
		switch(coluna)
		{
			case 0:
				return vetorExames[linha].getId();
			case 1:	
				return new DataWithIcon("", vetorExames[linha].getEstado();				   				
			case 2:				
				return vetorExames[linha].getNome();
			case 3:
				return vetorExames[linha].getEndereco();
			case 4:
			{
				data = vetorExames[linha].getNascimento();
				return sdf.format(data);
			}			
			default: return "-";
		}
	}

	
	public int getRowCount()
	{
		if (vetorExames == null)
			return 0;
		return vetorExames.length;
	}

	  public int getColumnCount() {
	    return COLUMN_COUNT;
	  }

	public Exame getExame(int indice)
	{
		Exame ret = null;
		if (indice < vetorExames.length)
			ret = vetorExames[indice];
		return ret;
	}
}

Arquivamento Helper:

package com.cliente.helper;

import com.cliente.persistencia.exame.Exame;
import com.cliente.tablemodel.ArquivamentoCellRenderer;
import com.cliente.tablemodel.ArquivamentoTableModel;

import java.awt.Component;
import java.awt.Container;
import java.awt.Image;
import java.util.List;

import javax.swing.DefaultCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import org.springframework.context.ApplicationContext;

public class ArquivamentoHelper {	
	
	public ArquivamentoHelper(ApplicationContext context)
	{
        }

	public void listarTodosExames(JTable tabelaExames,List v)
	{
		Exame[] vetExames = (Exame[]) v.toArray(new Exame[0]);
		ArquivamentoTableModel modelo = new ArquivamentoTableModel(vetExames);
		tabelaExames.setModel(modelo);		
		// Modificando o tamanho das colunas
		tabelaExames.getColumnModel().getColumn(0).setPreferredWidth(120);
		tabelaExames.getColumnModel().getColumn(1).setPreferredWidth(80);
		tabelaExames.getColumnModel().getColumn(2).setPreferredWidth(400);
		tabelaExames.getColumnModel().getColumn(3).setPreferredWidth(500);
		tabelaExames.getColumnModel().getColumn(4).setPreferredWidth(200);
		tabelaExames.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
		TableColumnModel         tcm      = tabelaExames.getColumnModel();		    
		ArquivamentoCellRenderer renderer = new ArquivamentoCellRenderer();
	    tcm.getColumn(1).setCellRenderer(renderer);
	}
}
fabim

tentei fazer isso e to com 2 problemas:

  • o ícoine .gif que eu adicionei nao fica animado
  • qqer coisa q acontece na table, tipo clicar na linha, rolar o scrollbar… os icones somem…

alguem da uma luz ae?

Criado 2 de janeiro de 2007
Ultima resposta 10 de mai. de 2007
Respostas 7
Participantes 3