在 DefaultTableCellRenderer 中将复选框替换为布尔值的字符串

Replace checkbox with String for Booleans in DefaultTableCellRenderer

我一直在尝试学习 JTable 渲染器,并且几乎确定了我正在寻找的行为,除了这最后一部分。我想删除 JTable 默认为布尔值呈现的复选框,并改为呈现一个简单的字符串,我只是无法解决这里的问题。

由于我对渲染器的更改非常小(只有基本的字符串操作,加上布尔值的前景色),我想扩展 DefaultTableCellRenderer 而不是实现 TableCellRenderer 并从头开始。 我也一直对所有单元格类型使用相同的渲染器,因为为我的每个简单操作创建一个新的 class 似乎很愚蠢。 这是我的相关代码:

public class MyTableRenderer extends DefaultTableCellRenderer {

    public MyTableRenderer() {
        super();
    }

    @Override
    public void setValue(Object value) {
        if(value instanceof Boolean) {
            boolean v = (boolean) value;
            setForeground( v ? Color.GREEN : Color.RED );
            setText( v ? "Alive" : "Dead" );
        }
    /*  else if(value instanceof //Other types, and so on and so forth */

    }

}

我正在将渲染器应用到 table 中:

JTable myTable = new JTable(myTableModel);
myTable.setDefaultRenderer(Object.class, new MyTableRenderer());

我已确保我的 table 模型正确响应 getColumnClass(),并且我的渲染器对所有其他类型的 value 表现正常,只有布尔值起作用。无论我 setText 在布尔值的情况下做什么,我的文本都会被默认复选框替换。 我知道布尔值默认使用单独的渲染器,但不应该调用 setDefaultRenderer on Object.class 覆盖默认值 Boolean.class?

myTable.setDefaultRenderer(Object.class, new MyTableRenderer());

您正在创建布尔渲染器,而不是对象渲染器。所以你应该使用:

myTable.setDefaultRenderer(Boolean.class, new MyTableRenderer());

but shouldn't calling setDefaultRenderer on Object.class override the default for Boolean.class?

没有。如果没有为特定 class 指定渲染器,则对象渲染器将用作默认渲染器。由于有一个默认的布尔渲染器,您将使用该渲染器,除非您将渲染器替换为您自己的渲染器。

I also have been using the same renderer for all cell types since it seemed silly to create a new class for each one of my simple operations

在不知道自己在做什么的情况下,一般来说,您应该创建自定义渲染器。每当您在代码中看到 if/else 逻辑时,您就知道您遇到了设计问题。使用 JTable 提供的功能并为每个 class 数据创建渲染器,而不是使用 if/else.

如果您认为自己有很多通用的渲染逻辑,那么您可以使用通用的渲染代码创建一个渲染器。然后创建多个渲染器,为每个 class 要支持的数据扩展基础渲染器。

I'm trying to use this same renderer for all cell types,

嗯,这就是我上面所说的问题。

如果您确实有充分的理由这样做,那么您还需要为要共享同一渲染器的所有 class 数据添加我上面建议的代码行。至少您需要为具有默认渲染器的 classes 执行此操作。