基于列类的Java摆动单元格渲染器

问题描述

在Java Swing中,我们有JTableTableModelColumnModelTableCellRenderer,它们共同显示一个表。

与基于列索引设置渲染器相反,如何提供定制以基于列类获取自定义单元格渲染器。

final JTable table = new JTable(model);
table.getColumnModel().getColumn(0).setCellRenderer(new DateTimeRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new SuperDuperDoubleCellRenderer());

假设我那里有20个数字单元格!!!

以上方法有效,但是我对这种解决方案并不热衷,因为它会在模型​​更改时发生变化-因此它没有很好地封装-这是客户端代码

TableModel了解基础表数据结构,在此基础上它可以对复杂类型(与DefaultTableModel和Vectors相对)进行自定义映射-在其中了解每一列的数据类型。

public class DemoTableModel implements TableModel {
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        // date time,double,etc...
        return columnInfo.get(columnIndex).getDataType();
    }
}

我想告诉JTable,嘿,列类(从表模型返回)是自定义的DateTime类型-使用CustomDateTimeCellRenderer。如果是双精度型,则使用自定义SuperDuperDoubleCellRenderer

麻烦在于从源头中挖掘出这种行为的根源。

解决方法

我想告诉JTable,该列类(从表模型返回)是自定义DateTime类型-使用CustomDateTimeCellRenderer。如果是双精度型,则使用自定义的SuperDuperDoubleCellRenderer。

您可以通过指定类和渲染器在表级别设置渲染器:

2020-10-15T06:00
,

您可以在CellRenderer级执行此操作-只需执行单元格渲染器即可

Component getTableCellRendererComponent​(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column)

您不会阻止整个JTable使用SmartCellRenderer来呈现单元格,例如,DoubleCellRenderer会检查传入值的类型并将实际呈现委托给StringCellRenderer,{{ 1}}或CuteInternetCatRenderer。假设对象类型是唯一的,这应该很容易做到(如果由于if (value instanceof InternetCat) { ... }的集合而有些丑陋,它决定了如何根据其类来呈现每个对象)。

更好的解决方案(不需要丑陋的instanceof)是在插入列时将特定的渲染器分配给特定的列:

 // model index 0,width 75,renderer to use,editor to use
 myTable.getColumnModel().addColumn(0,75,cuteInternetCatRenderer,null);