在动态JTable上更改Cell的背景颜色

时间:2017-06-13 11:50:11

标签: java swing jtable java-7

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

2 个答案:

答案 0 :(得分:3)

很抱歉直言不讳,但你试图捕获NPE catch(NullPointerException n){} - 是非常错误的 - 从来没有这样做,而是修复了可能导致NPE发生的错误。

至于你的问题,你没有超载实际的方法。你的方法签名:

public Component prepareRenderer(TableCellRenderer renderer, int rowIndex)

与实际方法签名不符:

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

根据JTable API,您缺少第3个参数,即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;
    }
}; 

答案 1 :(得分:3)

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

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为特定列设置单元格渲染器。 - 充气鳗鱼的气垫船

更好的是,当您在getColumnClass()中覆盖TableModel时,您不需要提前知道列索引:

所有列的相同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);
    }
}