JTable的单元格渲染器在运行时更改单元格的背景颜色

4
我正在尝试创建一个表格,并根据其他列的内容将特定单元格的颜色设置为黄色、红色或白色。为此,我循环遍历行并填入值,然后检查内容。对于当前显示在屏幕上的每一行都可以正常工作,但是当程序到达未显示的行或用户尝试滚动时,每个单元格的背景颜色都会改回白色。我已经搜索了网络上的解决方案,唯一听起来合理的想法是在每次循环后重置cellRenderer,但这不起作用,因为它也重置了每个单元格。
我希望有人能够解决这个问题,或者给我一些思路。我正在使用以下循环:
for(int e = 0; e < modules.size(); e++)
    {
    gui.clearOutputStream();
    gui.getOutputStream().setText("Load Modul " + modules.get(e) + "\r\n");
    version = getVersion(modules.get(e));

    //Update current Row
    updateRow(gui.getReleaseTabelle(), e);
    }

调用此方法的代码

public void updateRow(JTable target, int row){
//...
//insert Values here
//...
CustomRenderer cr = new CustomRenderer();
        cr.tab = target;
        if(!target.getValueAt(row, 2).equals(target.getValueAt(row, 3)))
        {
            cr.Val1 = target.getValueAt(row, 1).toString();
            target.setValueAt("X", row, 1);
        }
        else if(!target.getValueAt(row, 7).equals(""))
        {
            cr.Val1 = target.getValueAt(row, 1).toString();
            target.setValueAt("Y", row, 1);
        }
        else
        {

        }
        target.getColumnModel().getColumn(1).setCellRenderer(cr);

}

这是我的自定义渲染器

class CustomRenderer extends DefaultTableCellRenderer 
    {
private static final long serialVersionUID = 6703872492730589499L;
        public String Val1; 
        public JTable tab;

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

            if(tab.getValueAt(row, 1).equals("Y")){
                cell.setBackground(new java.awt.Color(255, 255, 0));
                tab.setValueAt(Val1, row, 1);
            }
            else if(tab.getValueAt(row, 1).equals("X")){
                cell.setBackground(new java.awt.Color(255, 50, 50));
                tab.setValueAt(Val1, row, 1);
            }
            else
            {
                //do nothing
            }
            return cell;
        }
    }

1
为了更快地获得帮助,请发布一个SSCCE,它是一个简短的、可运行的、可编译的示例。 - mKorbel
在您的 CustomRenderer 类中,存在 tab.setValueAt(Val1, row, 1); 语句。为什么需要这个语句?您应该只使用您的 CustomRenderer 类来渲染颜色。您正在重置表格中的某些内容,可能是问题所在。 - Amarnath
然而,当程序到达未显示的行或用户尝试滚动时,每个单元格都会将其背景颜色更改回白色。你的逻辑有问题,这就是导致问题的原因。 - Amarnath
永远不要在渲染器中更改表格/模型。 - kleopatra
我能在渲染器内部检查另一个单元格的值吗?如果可以,我该如何做?我认为问题在于在调用getTableCellRendererComponent时,如果没有使用我使用的变量,则if子句的结果在每种情况下都是false。 - Steffen Riek
1
好的,你们告诉我不要在渲染器内更改表格后,我找到了解决方案。这迫使我保持值不变,并从渲染器内检查其他列(这是完全可能的,通过table.getValueAt(row, column))。此外,我还必须将最后一个else编辑为cell.setBackground(new java.awt.Colo(255, 255, 255));而不是什么都不做。所以我的最后一个假设是正确的,但如果没有你们的评论,我永远不会有这个想法。谢谢Che和kleopatra :) - Steffen Riek
1个回答

8
不要在您的 CutomRenderer 类中更新表格数据。您的 Renderer 类应该检查条件并着色单元格。我已经使用了您的 CustomRenderer 类,并根据单元格中存在的数据呈现了单元格。如果单元格的数据为“Y”,将其颜色设置为黄色。如果数据是“N”,则将其颜色设置为灰色。

在 JTable 中渲染

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;


public class ColoringCells {

    private static Object[] columnName = {"Yes", "No"};
    private static Object[][] data = {
            {"Y", "N"},
            {"N", "Y"},
            {"Y", "N"}
    };


    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                JFrame frame = new JFrame();
                JTable table = new JTable(data, columnName);
                table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer());
                table.getColumnModel().getColumn(1).setCellRenderer(new CustomRenderer());

                frame.add(new JScrollPane(table));
                frame.setTitle("Rendering in JTable");
                frame.pack();
                frame.setVisible(true);
            }
        };

        EventQueue.invokeLater(r);
    }
}


class CustomRenderer extends DefaultTableCellRenderer 
{
private static final long serialVersionUID = 6703872492730589499L;

    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);

        if(table.getValueAt(row, column).equals("Y")){
            cellComponent.setBackground(Color.YELLOW);
        } else if(table.getValueAt(row, column).equals("N")){
            cellComponent.setBackground(Color.GRAY);
        }
        return cellComponent;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接