【问题标题】:JTable cell renderer set backround using other cells backgroundJTable 单元格渲染器使用其他单元格背景设置背景
【发布时间】:2020-01-20 21:42:35
【问题描述】:

我有一个 JTable 和一个自定义的 cell renderer,如果在线上有新章节,则可以突出显示单元格。

DefaultTableCellRenderer :

static class CustomRenderer extends DefaultTableCellRenderer {

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        double valueAt = (double) table.getValueAt(row, column);
        double compareValue = (double) table.getValueAt(row, column - 1);
        if (compareValue < valueAt) {
            cellComponent.setBackground(Color.green);
        } else {
            Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
            // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
            // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
            Color background = tableCellRendererComponent.getBackground();
            cellComponent.setBackground(background);
        }

        return cellComponent;
    }
}

表模型:

private String[] columnsGetNewest = {"Current Chapter", "Chapter Online"};
private DefaultTableModel dataModelGetNewest = new DefaultTableModel(columnsGetNewest, 0);

它的应用:

tableGetNewest.setModel(dataModelGetNewest);
TableColumn column = tableGetNewest.getColumnModel().getColumn(1);
column.setCellRenderer(new CustomRenderer());

期望的结果:

但由于某种原因,它不能按预期工作:

代码在进入 else 分支时似乎可以工作。

如果我注释掉//cellComponent.setBackground(Color.green);,结果如下:

我的代码有什么问题?我怎样才能得到想要的结果?

【问题讨论】:

    标签: java swing jtable tablecellrenderer custom-renderer


    【解决方案1】:

    如果我理解正确,您正在尝试将右列中所有比左列中的单元格值更高的单元格转为Green。如果我错了,请纠正。

    问题出在您的TableCellRenderer 上。在以下部分:

    if (compareValue < valueAt) {
        cellComponent.setBackground(Color.green);
    } else {
        Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
        // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
        // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
        Color background = tableCellRendererComponent.getBackground();
        cellComponent.setBackground(background);
    }
    

    我认为向你解释你做错了什么的最好方法是举个例子。假设右侧的值高于左侧列中的左侧值,因此您的if 发生并且renderer 的背景变为green。现在,让我们渲染第 2 行。右边的值小于左边的值,所以 if 不会发生。你猜怎么了?您在前一行渲染中将其设为绿色,因此它仍然是 green。这就是为什么他们都保持绿色。如果你转动它一次并且你没有恢复它,它会一直存在。

    现在,在你尝试恢复你super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);的背景。这是错误的,因为此方法不是简单的 getter。它还对表(渲染器)进行更改。为其他行/列值调用此方法将不起作用。

    为了完成这项工作,您必须根据来自DefaultTableCellRenderer 的默认值来恢复它。一个完整的例子:

    public class Example extends JFrame {
        private static final long serialVersionUID = 811854316682851407L;
        private static final String[] COLUMNS = { "Current Chapter", "Chapter Online" };
    
        public Example() {
            super("test");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setLayout(new BorderLayout());
    
            JTable table = new JTable(data(), COLUMNS);
            table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
                @Override
                public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
                        int column) {
                    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                    if (c instanceof JLabel) {
                        JLabel renderer = (JLabel) c;
                        int valueAt = (int) table.getValueAt(row, column);
                        int compareValue = (int) table.getValueAt(row, column - 1);
                        if (compareValue < valueAt) {
                            renderer.setBackground(Color.GREEN);
                        } else {
                            if (isSelected)
                                renderer.setBackground(table.getSelectionBackground());
                            else {
                                renderer.setBackground(table.getBackground());
                            }
                        }
                    }
                    return c;
                }
            });
            JScrollPane sp = new JScrollPane(table);
            add(sp);
            pack();
            setLocationRelativeTo(null);
        }
    
        private Object[][] data() {
            Object[][] data = { { 113, 444 }, { 233, 555 }, { 110, 92 }, { 55, 66 }, { 123, 603 }, { 412, 120 }, };
            return data;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> new Example().setVisible(true));
        }
    }
    

    预览:

    【讨论】:

      猜你喜欢
      • 2013-01-11
      • 2015-11-29
      • 1970-01-01
      • 2011-09-24
      • 2011-09-29
      • 1970-01-01
      • 2012-09-07
      • 2010-11-21
      相关资源
      最近更新 更多