java - 带有彩色单元格的默认 CellTable 渲染器不适用于 TableRowSorter?

标签 java swing

我正在尝试将 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/

相关文章:

java - 更新时乘以联系人姓名 (ContentProviderOperation)

java - ArrayList 中 size() 方法的用途

java - 使用 GridLayout - 如何设置 JPanel 大小?

java - 在Java中,在哪里放置代码以在窗口关闭时可靠地触发?

java - JTable 为图形返回 null?

java - 如何访问列表中的对象方法?

java - 使用 JFileChooser 过滤文件类型

java - 为什么 GridBagLayout 会强制我的组件具有一定的高度?

java - JPanel 的扩展类不显示 JPanel 的属性

java - 如何使用返回对象的getter方法?