更改 JTable 中行的背景颜色

Posted

技术标签:

【中文标题】更改 JTable 中行的背景颜色【英文标题】:Change the background color of a row in a JTable 【发布时间】:2011-04-21 23:53:24 【问题描述】:

我有一个 3 列的 JTable。我已经为所有 3 列设置了 TableCellRenderer 像这样(可能不是很有效?)。

 for (int i = 0; i < 3; i++) 
     myJTable.getColumnModel().getColumn(i).setCellRenderer(renderer);
 

getTableCellRendererComponent() 为每行返回一个带有随机背景颜色的组件。 如何在程序运行时将背景更改为其他随机颜色?

【问题讨论】:

【参考方案1】:

Richard Fearn 答案的简历,将第二行设为灰色:

jTable.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    
        final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
        return c;
    
);

【讨论】:

你是对的,这是有效的,但为什么这只适用于前 5 列?有什么想法吗? @Sahan 因为超过第 5 列可能有一个自定义单元格渲染器。 我试过这个 olivier,但是在我使用上面的代码之后,我无法使用 .setSelectionBackground(Color.yellow);不再...... :( @gumuruh 您也可以使用提供的 isSelected 参数在渲染器中设置选择颜色【参考方案2】:

此处给出的其他答案效果很好,因为您在每一列中使用相同的渲染器。

但是,我倾向于认为,通常在使用 JTable 时,每列中都会有不同类型的数据,因此您不会对每列使用相同的渲染器。在这些情况下,您可能会发现 Table Row Rendering 方法很有帮助。

【讨论】:

我同意。在我看来,TableModel 应该保存表数据。渲染应该在其他地方进行。链接的文章很有启发性,谢谢! :)【参考方案3】:

getTableCellRendererComponent(...) 的调用包括寻找渲染器的单元格的值。

您可以使用该值来计算颜色。如果您还使用 AbstractTableModel,则可以为渲染器提供任意类型的值。

一旦你有了颜色,你就可以在你要返回的组件上setBackground()

【讨论】:

【参考方案4】:

一种方法是存储模型中每一行的当前颜色。这是一个固定为 3 列和 3 行的简单模型:

static class MyTableModel extends DefaultTableModel 

    List<Color> rowColours = Arrays.asList(
        Color.RED,
        Color.GREEN,
        Color.CYAN
    );

    public void setRowColour(int row, Color c) 
        rowColours.set(row, c);
        fireTableRowsUpdated(row, row);
    

    public Color getRowColour(int row) 
        return rowColours.get(row);
    

    @Override
    public int getRowCount() 
        return 3;
    

    @Override
    public int getColumnCount() 
        return 3;
    

    @Override
    public Object getValueAt(int row, int column) 
        return String.format("%d %d", row, column);
    

注意setRowColour 调用fireTableRowsUpdated;这将只更新表格的那一行。

渲染器可以从表格中获取模型:

static class MyTableCellRenderer extends DefaultTableCellRenderer 

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
        MyTableModel model = (MyTableModel) table.getModel();
        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        c.setBackground(model.getRowColour(row));
        return c;
    

改变一行的颜色很简单:

model.setRowColour(1, Color.YELLOW);

【讨论】:

【参考方案5】:

这基本上就像重新粉刷桌子一样简单。但是,我还没有找到一种方法来选择性地重新绘制一行/列/单元格。

在此示例中,单击按钮会更改一行的背景颜色,然后调用 repaint。

public class TableTest 
    public static void main(String[] args) 
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final Color[] rowColors = new Color[] 
                randomColor(), randomColor(), randomColor()
        ;
        final JTable table = new JTable(3, 3);
        table.setDefaultRenderer(Object.class, new TableCellRenderer() 
            @Override
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus,
                    int row, int column) 
                JPanel pane = new JPanel();
                pane.setBackground(rowColors[row]);
                return pane;
            
        );
        frame.setLayout(new BorderLayout());

        JButton btn = new JButton("Change row2's color");
        btn.addActionListener(new ActionListener() 
            public void actionPerformed(ActionEvent e) 
                rowColors[1] = randomColor();
                table.repaint();
            
        );

        frame.add(table, BorderLayout.NORTH);
        frame.add(btn, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    

    private static Color randomColor() 
        Random rnd = new Random();
        return new Color(rnd.nextInt(256),
                rnd.nextInt(256), rnd.nextInt(256));
    

【讨论】:

以上是关于更改 JTable 中行的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

根据列值更改 JTable 行的背景颜色

背景排序JTable后,特定值的颜色不会改变

如何更改 JTable 的空白空间颜色?

JTable 表头背景颜色

JTable/setDefaultRenderer 多选行

在 ExtJs 中更改网格中行的颜色