Java 基于列 class 的摆动单元格渲染器
Java swing cell renderer based on column class
在 Java Swing 中,我们有一个 JTable
、TableModel
、ColumnModel
和一个 TableCellRenderer
,它们一起工作以显示 table .
我如何提供自定义以获取基于列的自定义单元格渲染器 class - 而不是根据列索引设置渲染器。
final JTable table = new JTable(model);
table.getColumnModel().getColumn(0).setCellRenderer(new DateTimeRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new SuperDuperDoubleCellRenderer());
假设我有 20 个数字单元格!!!
上面的方法可行,但我不太喜欢该解决方案,因为它会在模型更改时更改 - 所以它没有很好地封装到那种程度 - 这是客户端代码。
TableModel
了解底层的 table 数据结构,它可以在其中进行到复杂类型的自定义映射(与 DefaultTableModel 和 Vectors 相对)- 它知道每个数据类型的数据类型列。
public class DemoTableModel implements TableModel {
@Override
public Class<?> getColumnClass(int columnIndex) {
// date time, double, etc...
return columnInfo.get(columnIndex).getDataType();
}
}
我想做的是告诉 JTable
,嘿,class 列(从 table 模型返回)是自定义 DateTime 类型 - 使用 CustomDateTimeCellRenderer
。如果是双精度,则使用自定义 SuperDuperDoubleCellRenderer
.
问题在于挖掘源代码以查看此行为在哪里结婚。
您可以在 CellRenderer
级别执行此操作 - 单元格渲染器只需要实现
Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column)
没有什么可以阻止您告诉整个 JTable 使用 SmartCellRenderer
来呈现单元格,它查看 passed-in 值的类型并将实际呈现委托给 DoubleCellRenderer
,一个 StringCellRenderer
,或者一个 CuteInternetCatRenderer
。假设对象类型是唯一的,这应该很容易做到(如果由于 if (value instanceof InternetCat) { ... }
的集合决定如何根据其 class 呈现每个对象而有些丑陋)。
更好的解决方案(不需要难看的 instanceof
s)是在列插入时将特定的渲染器分配给特定的列:
// model index 0, width 75, renderer to use, editor to use
myTable.getColumnModel().addColumn(0, 75, cuteInternetCatRenderer, null);
What I would like to do is to tell a JTable, hey the column class (returned from the table model) is a custom DateTime type - use the CustomDateTimeCellRenderer. If it is a double, then use the custom SuperDuperDoubleCellRenderer.
您通过指定 class 和渲染器将渲染器设置在 table 级别:
table.setDefaultRenderer(Double.class, yourDoubleCellRenderer);
table.setDefaultRenderer(CustomDateTime.class, yourCustomDateTimeRenderer);
在 Java Swing 中,我们有一个 JTable
、TableModel
、ColumnModel
和一个 TableCellRenderer
,它们一起工作以显示 table .
我如何提供自定义以获取基于列的自定义单元格渲染器 class - 而不是根据列索引设置渲染器。
final JTable table = new JTable(model);
table.getColumnModel().getColumn(0).setCellRenderer(new DateTimeRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new SuperDuperDoubleCellRenderer());
假设我有 20 个数字单元格!!!
上面的方法可行,但我不太喜欢该解决方案,因为它会在模型更改时更改 - 所以它没有很好地封装到那种程度 - 这是客户端代码。
TableModel
了解底层的 table 数据结构,它可以在其中进行到复杂类型的自定义映射(与 DefaultTableModel 和 Vectors 相对)- 它知道每个数据类型的数据类型列。
public class DemoTableModel implements TableModel {
@Override
public Class<?> getColumnClass(int columnIndex) {
// date time, double, etc...
return columnInfo.get(columnIndex).getDataType();
}
}
我想做的是告诉 JTable
,嘿,class 列(从 table 模型返回)是自定义 DateTime 类型 - 使用 CustomDateTimeCellRenderer
。如果是双精度,则使用自定义 SuperDuperDoubleCellRenderer
.
问题在于挖掘源代码以查看此行为在哪里结婚。
您可以在 CellRenderer
级别执行此操作 - 单元格渲染器只需要实现
Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column)
没有什么可以阻止您告诉整个 JTable 使用 SmartCellRenderer
来呈现单元格,它查看 passed-in 值的类型并将实际呈现委托给 DoubleCellRenderer
,一个 StringCellRenderer
,或者一个 CuteInternetCatRenderer
。假设对象类型是唯一的,这应该很容易做到(如果由于 if (value instanceof InternetCat) { ... }
的集合决定如何根据其 class 呈现每个对象而有些丑陋)。
更好的解决方案(不需要难看的 instanceof
s)是在列插入时将特定的渲染器分配给特定的列:
// model index 0, width 75, renderer to use, editor to use
myTable.getColumnModel().addColumn(0, 75, cuteInternetCatRenderer, null);
What I would like to do is to tell a JTable, hey the column class (returned from the table model) is a custom DateTime type - use the CustomDateTimeCellRenderer. If it is a double, then use the custom SuperDuperDoubleCellRenderer.
您通过指定 class 和渲染器将渲染器设置在 table 级别:
table.setDefaultRenderer(Double.class, yourDoubleCellRenderer);
table.setDefaultRenderer(CustomDateTime.class, yourCustomDateTimeRenderer);