Estou com problema ao colorir uma linha na jTable. Quando usava DefaultTableModel ele coloria todas as células correspondentes ao critério, mas agora, com o meu TableModel implementado, a primeira e última célula não é colorida ou sublinhada, somente as intermediárias. Abaixo está o DefaultRenderer sobescrito.
jTable2.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
this.setHorizontalAlignment(CENTER);
Object ref = model.getValueAt(row, 3);
if (ref != null && ref.equals("DISPONÍVEL")) {
setBackground(Color.cyan);
setForeground(Color.black);
setFont(new Font("Tahoma", Font.BOLD, 12));
} else {
// setBackground(Color.cyan);
setForeground(Color.black);
setFont(new Font("Tahoma", 0, 12));
}
return this;
}
});
Agora o meu modelo logo abaixo.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package FormsConsulta;
import Classes2.Itens;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;
import login.Classes.DB;
import login.Classes.Query;
/**
*
* @author MARCOS
*/
public class TableModelConsulta extends AbstractTableModel {
private String[] columnNames = {"Código de Barras", "Descrição", "Disponibilidade", "Status"};
private ArrayList data = new ArrayList();
private Itens item;
public TableModelConsulta (String sql) {
super();
DB banco2 = new DB();
banco2.connect();
Query carregaArray = new Query(banco2.conn);
carregaArray.open(sql);
int codigo;
String codigodebarras;
String descricao;
String disponibilidade;
String status;
item = new Itens();
data = new ArrayList();
try {
while (carregaArray.next()) {
codigo = carregaArray.rs.getInt("codigo");
codigodebarras = carregaArray.rs.getString("codigodebarras");
descricao= carregaArray.rs.getString("descricao");
disponibilidade = carregaArray.rs.getString("disponibilidade");
status = carregaArray.rs.getString("status");
item.setCodigo(codigo);
item.setCodigodebarras(codigodebarras);
item.setDescricao(descricao);
item.setDisponibilidade(disponibilidade);
item.setStatus(status);
//Colocar os gets para poder funcionar corretamente
data.add(new Itens(item.getCodigo(),
item.getCodigodebarras(),
item.getDescricao(),
item.getDisponibilidade(),
item.getStatus()));
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
banco2.disconnect();
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
// return data.length;
//Alterado para ArrayList
return data.size();
}
public String getColumnName(int col) {
return columnNames[col];
}
//Aqui so vai aparecer 4 colunas, mas tem o codigo, que nao coloco para visualizar na tela
public Object getValueAt(int row, int col) {
//pega os nomes da linha
Itens item2 = (Itens) data.get(row);
data.get(row);
switch (col) {
case 0:
return item2.getCodigodebarras();
case 1:
return item2.getDescricao();
case 2:
return item2.getDisponibilidade();
case 3:
return item2.getStatus();
default:
return null; // isso nunca deve ocorrer
}
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
// if (col < 2) {
// return false;
// } else {
// return true;
// }
return false;
}
/*
* Don't need to implement this method unless your table's
* data can change.
* @param rowrow row number
* @param colcolumn column number
*/
public void setValueAt(Object value, int row, int col) {
//data[row][col] = value;
//Alterado para ArrayList
// ArrayList colArrayList = (ArrayList) data.get(row);
// colArrayList.set(col, value);
// fireTableCellUpdated(row, col);
}
/*Insere uma nova linha na tabela*/
public void insertRow(ArrayList newrow) {
data.add(newrow);
super.fireTableDataChanged();
}
/* Deleta a linha especificada da tabela.
*
* @param row number
*/
public void deleteRow(int row) {
data.remove(row);
super.fireTableDataChanged();
}
/* Delete all the rows existing after the selected row from the JTable
*
* @param row number
*/
public void deleteAfterSelectedRow(int row) {
// Get the initial size of the table before the deletion has started.
int size = this.getRowCount();
// The number of items to be deleted is got by subtracting the
// selected row + 1 from size. This is done because as each row is deleted
// the rows next to it are moved up by one space and the number of rows
// in the JTable decreases. So the technique used here is always deleting
// the row next to the selected row from the table n times so that all the
// rows after the selected row are deleted.
int n = size - (row + 1);
for (int i = 1; i <= n; i++) {
data.remove(row + 1);
}
super.fireTableDataChanged();
}
/**
* retorna o valor da linha(row) especificada como um ArrayList.
*
* @param row number
*
* @return ArrayList!
*/
public ArrayList getRow(int row) {
return (ArrayList) data.get(row);
}
/**
* Atualiza a linha especificada. Ele substitui a linha(row) no ArrayList
* na especificada linha(row) com o novo ArrayList.
*
* @param updatedRowArrayList row data
* @param rowrow row number
*/
public void updateRow(ArrayList updatedRow, int row) {
data.set(row, updatedRow);
super.fireTableDataChanged();
}
/**
* Limpa os dados da tabela.
*/
public void clearTable() {
data = new ArrayList();
super.fireTableDataChanged();
}
//
}
No meu form de Consulta coloco no botão para carregar todos os registros, para o filtro, no txtConsulta coloco o newFilter da SUN que é muito mais simples e sem problema algum e é só alterar o índice de acordo com a coluna que quer filtrar. Declaro Primeiro como privadas as variáveis:
private TableRowSorter<TableModelConsulta> sorter;
private TableModelConsulta model;
Esse é o filtro. Muito simples e pequeno.
/**
* Atualiza a expressão regular do filtro da linha da expressão
* na caixa de texto. Filtra na jTable quando digita.
*/
private void newFilter(int coluna) {
RowFilter<TableModelConsulta, Object> rf = null;
//If current expression doesn't parse, don't update.
try {
rf = RowFilter.regexFilter(txtConsulta.getText(), coluna);
} catch (java.util.regex.PatternSyntaxException e) {
return;
}
sorter.setRowFilter(rf);
}
código do botão que carrega todos os dados.
private void btnTodosActionPerformed(java.awt.event.ActionEvent evt) {
String sql="SELECT codigodebarras,descricao,disponibilidade,status FROM itens";
model = new TableModelConsulta(sql);
jTable2.setModel(model);
sorter = new TableRowSorter<TableModelConsulta>(model);
jTable2.setRowSorter(sorter);
}
Agora o código do txtConsulta, que ao digitar, será filtrado na jTable.
private void txtConsultaKeyReleased(java.awt.event.KeyEvent evt){
//Se for verdadeiro,então vai receber mais um criterio no sql
//por causa dos forms de empréstimos e reservas
// String campo = null;
switch (cbFiltro.getSelectedIndex()) {
case 0:
//Código de Barras
newFilter(0);
break;
case 1:
//Descricao
newFilter(1);
break;
}
}
Pronto. Preciso tambem que verifiquem o meu modelo, porque tem metodos que nao funcionam corretamente. Nao uso todos ainda e nao testei todos por enquanto. So estou usando esse modelo porque a consulta pode ser feita em tempo real depois de carregada no banco de dados e tem um filtro muito simples. Estou precisando tambem no modelo, que ainda nao consegui consertar, pegar o valor quando clicar na linha, mas esse valor seria de uma celula. O getValueAt so pega das colunas que estao na tabela e nao pega o codigo que esta no array e nao na tabela e consertar o problema que nao mostra a primeira e ultima celula colorida ou preenchida com a cor escolhida no DefaultRenderer, somente quando uso DefaulTableModel. Expliquei bem meu problema e espero que seja o suficiente. Com relacao ao modelo, se tiver que melhorar a implementacao, pode dar sugestoes com codigo, logico.