我正在尝试将 DefaultTableCellRenderer 与简单的 TableRowSorter 结合使用。
我的模型看起来不错,可以正常工作。我的渲染看起来不错并且适用于我的模型。甚至在我需要的单元格中绘制图标。
但是,当我尝试应用 TableRowSorter 时。它只有在我删除我的渲染器时才有效。 我是说。当我应用渲染器时。当用户单击时,表格不会排序。 如果我不使用渲染器。分拣机工作得很好。包括“整数”顺序。
基本上他们是为了工作而互相排斥。
5 天多来我一直在尝试不同的解决方案,但没有任何结果。我可能遗漏了一些我无法分辨的基本信息。
这是我的代码。
表格模型:
package model;
import control.PaisDAO;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;
/**
*
* @author X8
*/
public class PaisTableModel extends AbstractTableModel {
private List<Pais> elements;
private String[] columnNames = {"Pais", "Abrev", "Descrição", "Icone"};
/**
* Construtor recebe dados iniciais em formato de ArrayList Pais
*
* @param elements
*/
public PaisTableModel(List<Pais> elements) {
this.elements = elements;
}
/**
* numero de linhas de sua tabela. Metodo obrigatorio herdado e reescrito.
*
* @return
*/
@Override
public int getRowCount() {
//numero de linhas/elementos.
return elements.size();
}
/**
* Numero de colunas de nossa tabela. de 0 a 3 = 4 colunas.
*
* @return
*/
@Override
public int getColumnCount() {
return 4; //numero de colunas da tabela
}
/**
* Retorna o valor a ser preenchido na linha e coluna
*
* @param row
* @param col
* @return
*/
@Override
public Object getValueAt(int row, int col) {
//retornar os dados das linhas/celulas
Pais p = elements.get(row);
if (col == 0) {
return p.getPais();
}
if (col == 1) {
return p.getAbreviado();
}
if (col == 2) {
return p.getDescricao();
}
if (col == 3) {
return p.getIcone();
}
return null;
}
/**
* Define o nome de cabecalho da coluna
*
* @param col
* @return
*/
@Override
public String getColumnName(int col) {
return columnNames[col];
}
/**
* Apresenta a tabela qual tipo de dados ela deve desenhar
*
* @param col
* @return
*/
@Override
public Class<?> getColumnClass(int col) {
if (col == 0) {
return Integer.class;
}
if (col == 1 || col == 2) {
return String.class;
}
return super.getColumnClass(col);
}
/**
* Retorna o objeto inteiro para facilitar pegar uma linha inteira
*
* @param row
* @return
*/
public Pais get(int row) {
return elements.get(row);
}
/**
* Permitir adicionar uma linha unica
*
* @param p
*/
public void add(Pais p) {
elements.add(p);
this.fireTableDataChanged();
}
/**
* Adicionar colecao de itens ao final da lista.
*
* @param itens
*/
public void addAll(List<Pais> itens) {
elements.addAll(itens);
this.fireTableDataChanged();
}
/**
* Limpa a tabela toda.
*/
public void clear() {
elements.clear();
this.fireTableDataChanged();
}
} //EOF
表格渲染器:
package model;
import java.awt.Color;
import java.awt.Component;
import javax.swing.ImageIcon;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
/**
*
* @author X8
*/
public class PaisesTableRenderer extends DefaultTableCellRenderer {
public PaisesTableRenderer() {
this.setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable jtable, Object
item, boolean isSelected, boolean hasFocus, int row, int col) {
//usar get configurado no TableModel para pegar o objeto inteiro.
PaisTableModel modelo=(PaisTableModel) jtable.getModel();
Pais p=modelo.get(row);
//colore linhas espacadas e selecionada
if (isSelected ){
this.setForeground(Color.WHITE);
this.setBackground(Color.BLACK);
} else {
if (row % 2 == 0){
this.setForeground(Color.BLACK);
this.setBackground(Color.YELLOW);
} else {
this.setForeground(Color.WHITE);
this.setBackground(Color.BLUE);
}
}
//escreve texto, icone e define tamanho de cada coluna
if (col==0){
this.setText(Integer.toString(p.getPais()));
this.setIcon(null);
jtable.getColumnModel().getColumn(col).setPreferredWidth(100);
}
if (col==1){
this.setText(p.getDescricao());
this.setIcon(null);
jtable.getColumnModel().getColumn(col).setPreferredWidth(400);
}
if (col==2){
this.setText(p.getAbreviado());
this.setIcon(null);
jtable.getColumnModel().getColumn(col).setPreferredWidth(100);
}
if (col==3){
this.setIcon(new ImageIcon(p.getIcone()));
this.setText("");
jtable.getColumnModel().getColumn(col).setPreferredWidth(100);
//this.setText(p.getIcone());
}
return this;
}
@Override
public void updateUI() {
super.updateUI();
}
@Override
public void repaint() {
super.repaint();
}
}
将表行排序器、模型和渲染器添加到表中:
tbPaises.setModel(new PaisTableModel(dbPaises.asArrayList()));
//tbPaises.setDefaultRenderer(Object.class, new
PaisesTableCellRenderer2());
//tbPaises.setAutoCreateRowSorter(true);
TableRowSorter<TableModel> sorter = new TableRowSorter<>
(tbPaises.getModel());
//sorter.setRowFilter(null);
tbPaises.setRowSorter(sorter);
最佳答案
PaisTableModel modelo=(PaisTableModel) jtable.getModel();
Pais p=modelo.get(row);
排序器不会更改 TableModel 中数据的顺序。只有数据的 View 发生了变化。
渲染器处理表的索引,而不是 TableModel,因此如果您想从 TableModel 访问数据,您需要将“表行”转换为“模型行”:
int modelRow = convertRowIndexToModel(row)
PaisTableModel modelo = (PaisTableModel)jtable.getModel();
Pais p = modelo.get(modelRow);
另一种选择是使用 getValueAt(...)
方法从 JTable 获取数据。然后该表将自动为您进行索引转换。
实际上,您的渲染器甚至不应该拥有所有“if 条件”。 TableModel 的 getValueAt(...)
方法将返回适当的值以显示。 renederer 中的第一条语句应该是:
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
您还可以查看 Table Row Renderering一种更简单的方法来交替行颜色,因此您甚至不需要创建自定义渲染器。
此外,不要覆盖 updateUI() 或 repaint()。没有理由重写这些方法。
关于java - 带有彩色单元格的默认 CellTable 渲染器不适用于 TableRowSorter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32079051/