Resolvi postar aqui uma classe que criei onde extendo tanto JList quanto JScrollPane pois um depende do outro no meu ponto de vista. Avaliem a Classe e deem sugestões de melhoria.
package acao;
import gen.MeuModelList;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public abstract class GeraJList extends JScrollPane {
private MeuJList lista;
protected MeuModelList modelList;
public GeraJList(int x, int y, int w, int h, List dados, String dica, int [] cor) {
super(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
this.setBounds(x,y,w,h);
this.setToolTipText(dica);
lista = new MeuJList(dados, dica, cor);
lista.addListSelectionListener(new ListSelectionListener() { // Ao navegar pela Lista
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting())
getValueChanged(); // Recupera Objeto ?.getJList().getSelectedValue().toString() ou ?.getText
}
});
lista.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
getDoubleClick();
}
}
});
lista.addKeyListener(new KeyListener() {
@Override // if (e.getKeyCode() == KeyEvent.VK_F9){}
public void keyPressed (KeyEvent e) {getKeyPressed(e);}
public void keyReleased(KeyEvent e) {}
public void keyTyped (KeyEvent e) {}
});
this.setViewportView(lista);
}
public GeraJList(int x, int y, int w, int h, List dados, String dica) {this(x, y, w, h, dados, dica, null);}
public GeraJList(int x, int y, int w, int h, List dados) {this(x, y, w, h, dados, null, null);}
public GeraJList(int x, int y, int w, int h) {this(x, y, w, h, new ArrayList(), null, null);}
public GeraJList(int x, int y, int w, int h, String dica) {this(x, y, w, h, new ArrayList(), dica, null);}
/**
* Retorna o Objeto
* @return
*/ public MeuJList getList() {
return lista;
}
/**
* Retorna toString do Objeto
* @return
*/ public String getText (){
return lista.getSelectedValue().toString();
}
/**
* Atualiza a lista
* @param list
*/ public void atualiza(List list) {
modelList = (MeuModelList) lista.getModel();
modelList.atualiza(list);
lista.repaint();
}
public void setEditable(boolean altera){
if (altera){
this.setBorder(javax.swing.BorderFactory.createEtchedBorder());
} else {
this.atualiza(new ArrayList());
this.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
}
}
/**
* Classe interna do jList
*/ class MeuJList extends javax.swing.JList {
private int [] cor;
public MeuJList(List lista, String dica, int [] cor) {
this.setToolTipText(dica);
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setLayoutOrientation(JList.VERTICAL);
this.cor = cor;
this.setModel(new MeuModelList(lista));
this.setSelectedIndex(0);
this.setCellRenderer(new MeuCellRenderer());
this.setFont(new Font("Sans Serif", Font.PLAIN, 12));
if (cor!=null && cor[0]!=0 && cor[1]!=0 && cor[2]!=0) {
this.setForeground(new java.awt.Color(cor[0], cor[1], cor[2]));
}
}
public class MeuCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
protected Color foreground;
protected Color background;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index,isSelected, cellHasFocus);
// Altera a Cor
if (cor!=null && cor.length>=6) {
if (isSelected) {
foreground = Color.getHSBColor(cor[0],cor[0],cor[0]);
background = Color.getHSBColor(cor[1],cor[1],cor[1]);
} else {
if (index % 2 == 0) {
foreground = Color.getHSBColor(cor[2],cor[2],cor[2]);
background = Color.getHSBColor(cor[3],cor[3],cor[3]);
} else {
foreground = Color.getHSBColor(cor[4],cor[4],cor[4]);
background = Color.getHSBColor(cor[5],cor[5],cor[5]);
}
}
renderer.setForeground(foreground);
renderer.setBackground(background);
}
return renderer;
}
}
}
// Métodos abstratos
public abstract void getValueChanged ();
public abstract void getDoubleClick ();
public abstract void getKeyPressed (KeyEvent e);
}
Alguns Métodos a serem comentado
- getList() - Retorna o JList já que a classe principal é o JScrollPane
- getText() - Retorna toString do Objeto. Geralmente eu reescrevo o toString das classes que vão me retornar um ArrayList
- atualiza(List list) - Passo um novo “List” para atualizar o JList. chamo este método quando faço CRUD.
AbstractListModel
package acao;
import java.util.List;
import javax.swing.AbstractListModel;
/**
* Model do meu JList
* @author vonquelbe.caldeira
*/
public class MeuModelList extends AbstractListModel {
private List lista;
// Construtor
public MeuModelList(List lista) {
this.lista = lista;
}
@Override
public int getSize() {return lista.size();}
@Override
public Object getElementAt(int index) {return lista.get(index);}
public void atualiza(List lista){
this.lista = lista;
this.fireContentsChanged(this, 0, lista.size());
}
// Outros --------------------------------------------------
public void addElement(Object obj) {
lista.add(obj);
this.fireIntervalAdded(obj, this.getSize() - 1, this.getSize() - 1);
}
public void removeElement(Object obj) {
this.fireIntervalRemoved(obj, lista.indexOf(obj), lista.indexOf(obj));
lista.remove(obj);
}
public void insertElementAt(Object obj, int index) {
lista.add(index, obj);
this.fireIntervalAdded(obj, index, index);
}
public void removeElementAt(int index) {
this.fireIntervalRemoved(lista.get(index), index, index);
lista.remove(index);
}
public void print() {
System.out.println("\nLista");
for (int i = 0; i < this.lista.size(); i++) {
System.out.println(this.lista.get(i));
}
}
}
Executando
package acao;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
public class Inicio {
private static javax.swing.JFrame tela;
private static GeraJList lista;
public static void main(String[] args) {
List <Object> obj = new ArrayList();
obj.add("Java");
obj.add("Oracle");
obj.add("Delphi");
obj.add("C#");
obj.add("C++");
obj.add("MySQL");
tela = new javax.swing.JFrame("Testando GeraJList");
tela.setSize(300,150);
tela.setResizable(false);
tela.setLocationRelativeTo(null);
tela.setDefaultCloseOperation(3);
tela.setLayout(null);
lista = new GeraJList(10,10,200,74, obj) {
@Override
public void getValueChanged() {
System.out.println("Selecionado: "+lista.getText());
}
@Override
public void getDoubleClick() {
System.out.println("Duplo Click");
}
@Override
public void getKeyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_F9){
System.out.println("Clicou no F9");
}
}
};
tela.add(lista);
tela.setVisible(true);
}
}
Neste exemplo usei o Object com String mas pode ser usado qualquer ArrayList. Eu geralmente uso de uma classe.
OBS: Coloquei três métodos Abstratos na classe que tem a função de facilitar a minha vida. Esses métodos são chamados quando a lista é percorrida, ao dar um duplo click na lista ou quando uma tecla for chamada (F1 a F12 por exemplo). Caso não interesse, basta comentar.
