问题描述
在Java Swing中,我们有JTable
,TableModel
,ColumnModel
和TableCellRenderer
,它们共同显示一个表。
与基于列索引设置渲染器相反,如何提供定制以基于列类获取自定义单元格渲染器。
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);