Renderer customizado para JList com JLabels

Criei um Renderer customizado para utilizar JLabels como itens de uma JList, mas ao selecionar um deles, a cor de fundo não é modificada. Segue o código que criei (uma classe específica para tal Renderer):

import javax.swing.;
import java.awt.
;

public class XCellRenderer extends JLabel implements ListCellRenderer {
public XCellRenderer() {
setOpaque(true);
}

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {

  Component comp = (Component)value;
  comp.setForeground(isSelected ? Color.red : Color.black);
  comp.setBackground(isSelected ? Color.black : Color.white);
  return comp;

}

}

tenta:

return this;

Ja que vc ta estendendo o JLabel, retorna a propria classe que é um JLabel.

Muda seu codigo assim:


import javax.swing.*;
import java.awt.*;

public class XCellRenderer extends JLabel implements ListCellRenderer {
public XCellRenderer() {
setOpaque(true);
}

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
 
  // Component comp = (Component)value; // Seu value é um componente? Nao é uma String não?
  setText((String)value);
  setForeground(isSelected ? Color.red : Color.black);
  setBackground(isSelected ? Color.black : Color.white);
  return this;
 }

}

Acho que pode ser isso… :roll:

Eu to fazendo assim:

ProdutosListCellRenderer render = new ProdutosListCellRenderer( produtos ); jListProdutos.setRenderer( render );

mas ele reclama que render não é do tipo correto do parâmetro do método setRender.

public class ProdutosListCellRenderer extends JLabel implements ListCellRenderer { //... }

é setCellRenderer()

hehehehe… valeu

eu tenho que dar um newno JList novamente?
devo passar algo pro constutor?

Eu quero exibir um list de objetos Produtos…
eu passo esse list pro meu ListCellReenderer…e ele mantem uma ref pro java.util.List.

Ahmm…
Dá uma olhada em ListModel.
Cria um modelo para a lista, com métodos para inserir e remover.
Sete seu renderer normalmente, sem passar lista nenhuma pra ele. QUem deve cuidar dos dados que sua list exibe é o Model. O renderer cuida só de como mostrar na list.

JList lista = new JLista();
lista.setModel(new MyListModel());
lista.setCellRenderer(new MyCellRenderer());

class MyCellRenderer{}
class MyListModel extends DefaultListModel{}

Se já usou uma JTable, é semelhante a ela como o model trabalha.

Capiti ?..rss :smiley:

Ah sim! Agora eu entendí a separação.

Cispici? Si, è vero, io capisco tutte le cose che dice.

Bem, pra quem tá curioso, tem um exmeplo ai pra fazer funcionar uma JList com o modelo e o renderer customizados.

import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
 *
 * @author  Administrador
 */
public class JListExample {
    
    private JFrame frame = null;
    private JList lista = null;
    
    /** Creates a new instance of JListExample */
    public JListExample() {
        
        frame = new JFrame("JList Example;");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0,0,300,500);
        frame.setVisible(true);
        frame.show();
        
        lista = new JList();
        frame.getContentPane().add(lista, BorderLayout.CENTER);
        
        
        // Seta o modelo da us Jlist
        ArrayList array = new ArrayList();
        array.add("Linha 1");
        array.add("Linha 2");
        array.add("Linha 3");
        
        MyListModel modelo = new MyListModel(array);
        lista.setModel(modelo);
        
        
        // Seta o rdenerer
        MyListCellRenderer renderer = new MyListCellRenderer();
        lista.setCellRenderer(renderer);
        
        
        // Se quiser inserir Mais tira esse comentario:
        // modelo.addElement("Novo Elemento no Fim");
        
        
        // Dá um refresh na lista
        lista.revalidate();
        
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        JListExample example = new JListExample();
        
    }
    
}

/**
 * Monta o renderer
 */
class MyListCellRenderer extends DefaultListCellRenderer{
    /**
     * Método para retornar o componente renderer que vc irá exibir
     * O default é um JLabel
     */
    public Component getListCellRendererComponent(JList list, 
        Object value, 
        int index,
        boolean isSelected,
        boolean hasFocus)
    {
        // Chama o método super dele
        Component superC = super.getListCellRendererComponent(list, 
        value, 
        index,
        isSelected,
        hasFocus);
        
        // Aqui vc pode alterar qualquer propriedade antes de retornar o componente
        superC.setForeground(java.awt.Color.RED);
        return superC;
    }
}

/**
 * Monta o Model da List
 * Os métodos getSize() e getElementAt tem que ser implementados e sao obrigatorios
 */
class MyListModel extends DefaultListModel{
    
    private ArrayList minhaLista = null;
    
    /** Construtor recebendo a lista */
    public MyListModel(ArrayList lista){
        minhaLista = lista;
    }
    
  /** 
   * Returns the length of the list.
   * @return the length of the list
   */
  public int getSize(){
      // Aqui é so retornar o tamanha da sua lista
      return minhaLista.size();
  }

  /**
   * Returns the value at the specified index.  
   * @param index the requested index
   * @return the value at <code>index</code>
   */
  public Object getElementAt(int index){
      
      // Aqui vc tem que retornar uma string, que é o que será exibido
      // no seu renderer
      // Voce pode criar o seu objeto aqui e passar pra frente, mas
      // ai vc tem que tratar ele no renderer, ou seja, vc qtem que customizar
      // o renderer para esperar a propriedade value como seu objeto.      
      return minhaLista.get(index);
  }
  
  // Método criado pra mim
  public void addElement(String value){
      // Aqui vc insere um novo valor
      minhaLista.add(value);
      // Aqui vc dispara quie inseriu um valor no final do seu modelo
      fireIntervalAdded(this, (minhaLista.size()-1),(minhaLista.size()-1));
  }
  
  // Remove elementos
  public void removeElementAt(int index){
      // Remove o elemento
      minhaLista.remove(index);
      // Aqui vc dispara que removeu um certo elemento (index)
      fireIntervalRemoved(this, index,index);
  }
           
}

Perfeito… agora sim eu entendí e funcionou.
Abraços