繁体   English   中英

在动态JTable上更改单元格的背景颜色

[英]Change Cell's Background color on dynamic JTable

我有一个Java表,其中包含目录中的内容。 我创建了5个comboBoxes,它们将用户导航到文件夹中,然后创建一个JTable,其中包含所选文件夹的内容,例如文件名,日期,创建者等。在表的第6列中,我有一些字符串值,具体取决于每个字符串值我想更改此单元格的背景色的值。 这是我启动JTable的最后一个comboBox。

抱歉,直截了当,但是您尝试捕获NPE catch(NullPointerException n){}方法非常错误,请不要这样做,而要修复可能导致NPE发生的错误。

至于您的问题,您不会重载实际的方法。 您的方法签名:

public Component prepareRenderer(TableCellRenderer renderer, int rowIndex)

与实际的方法签名不匹配:

public Component prepareRenderer(TableCellRenderer renderer,
                             int row,
                             int column) 

根据JTable API ,您缺少第三个参数,即列int参数。

这就是为什么您应该始终@Override批注之前添加覆盖的方法的原因。 你做了这个吗?

@Override   // this will cause the compiler to complain that this isn't an override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex)

而且您在此方法中的for循环看起来很可疑。 我会摆脱它,因为渲染器应该只渲染由行和列索引指定的单元格。

例如,

DefaultTableModel listModel = new DefaultTableModel();
JTable table1 = new JTable(listModel){

    @Override // don't forget this!
    public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int columnIndex) {
        JComponent component = (JComponent) super.prepareRenderer(renderer, i, columnIndex);
        int lastRow = listModel.getRowCount();
        // this will likely set the whole row. If you only want to set only a specific cell, then 
        // you'll need to first check the columnIndex.
        if (getValueAt(rowIndex, 6).toString().contains("yellow")) {
            component.setBackground(Color.RED);
        } else {
            component.setBackground(null);  // turn color back to default
        }
        return component;
    }
}; 

您不应该扩展JTable而是DefaultTableCellRenderer并将其设置为Table中的默认渲染器:

public class TableRendererExample {
    public static void main(String[] args) {
        TableCellRenderer renderer = new DefaultTableCellRenderer(){
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                    boolean hasFocus, int row, int column) {
                Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                rendererComponent.setBackground("value2".equals(value)?Color.RED:Color.WHITE);
                return rendererComponent;
            }
        };
        TableModel tableModel= new DefaultTableModel(10, 3){
            @Override
            public Object getValueAt(int arg0, int arg1) {
                return "value"+new Random().nextInt(4);
            }       
        };
        JTable jTable = new JTable(tableModel);
        jTable.setDefaultRenderer(Object.class, renderer);
        JOptionPane.showMessageDialog(null, jTable);
    }
}


这可能是一个更好的长期解决方案,因为它还允许OP设置特定列的单元格渲染器。 –充满鳗鱼的气垫船

更好的是,当您覆盖TableModel getColumnClass()时,您不需要预先知道列索引:

所有列均使用相同的Renderer类:

class DefaultTableCellRendererBackground extends DefaultTableCellRenderer {
    private final Color highlightColor;

    DefaultTableCellRendererBackground(Color highlightColor) {
        this.highlightColor = highlightColor;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row,
                column);
        rendererComponent.setBackground(highlightColor);
        return rendererComponent;
    }
}

TableModel每次运行都返回不同的ColumnClasses:

final class DefaultTableModelExtension extends DefaultTableModel {
    private final List<Class<?>> columnClass;

    DefaultTableModelExtension(int rowCount, int columnCount, List<Class<?>> columnClass) {
        super(rowCount, columnCount);
        this.columnClass = columnClass;
        Collections.shuffle(this.columnClass);
    }

    @Override
    public Class<?> getColumnClass(int col) {
        return columnClass.get(col);
    }

    @Override
    public Object getValueAt(int arg0, int arg1) {
        return "value" + new Random().nextInt(4);
    }
}

要返回的类型:

interface TagRed {}

interface TagBlue {}

interface TagYellow {}

用法(多次运行...):

public class TableRendererExample {
    public static void main(String[] args) {
        JTable jTable = new JTable();
        jTable.setDefaultRenderer(TagRed.class, new DefaultTableCellRendererBackground(Color.RED));
        jTable.setDefaultRenderer(TagBlue.class, new DefaultTableCellRendererBackground(Color.BLUE));
        jTable.setDefaultRenderer(TagYellow.class, new DefaultTableCellRendererBackground(Color.YELLOW));

        List<Class<?>> columnClass = Arrays.asList(TagRed.class, String.class, TagBlue.class, TagRed.class, String.class,
                TagYellow.class, TagBlue.class);
        jTable.setModel(new DefaultTableModelExtension(10, columnClass.size(), columnClass));
        JOptionPane.showMessageDialog(null, jTable);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM