我正在创建我的第一个 JTable,它需要我创建自定义 AbstractTableModel
、TableCellEditor
和 DefaultTableCellRenderer
。鉴于我以前不需要创建这些,我在让我的表按预期运行方面取得了一些重大进展。
但是,我对覆盖的所有不同方法感到不知所措,并且我正在转动我的轮子试图弄清楚如何修改特定单元格的 ImageIcon。 单元格必须包含一个 JLabel,因为它需要一个 ImageIcon
以及一个文本字符串。我已经可以设置初始 ImageIcon
(虽然我可能做错了),但我无法设置更新的 ImageIcon
。没有失败,但没有做出任何改变。
在一般意义上,假设所有这些模型、编辑器和渲染器已经实例化了吗?
我的模型已经被定义为为这些单元格返回 JLabel.class
,如果你想知道的话,我也做了一次 fireTableCellUpdated(row, col)
据称已经进行了更改。如果我在更新前后执行 System.out.println(getIcon())
,我什至可以看到源已更改。
这是一些代码(更新了 URL/ImageIcon 修复):
class MonitorTable extends JTable {
MonitorTableModel model = new MonitorTableModel(rows, columnNames);
setModel(model);
...
public void setIconAt(ImageIcon icon, int row, int col) {
model.setIconAt(icon, row, col);
} // End setIconAt(ImageIcon, int, int)
...
class MonitorTableModel extends AbstractTableModel {
...
public void setIconAt(ImageIcon icon, int row, int col) {
StatusTableCellRenderer cell =
(StatusTableCellRenderer)getColumnModel().getColumn(col).getCellRenderer().
getTableCellRendererComponent(myTableObject, null, false, false, row, col);
System.out.println(cell.getIcon()); // Shows initial icon source
cell.setIcon(icon);
fireTableCellUpdated(row, col); // Should update the table
System.out.println(cell.getIcon()); // Shows new icon source
System.out.println("Cell updated");
} // End setIconAt(ImageIcon, int, int)
} // End class MonitorTableModel
public class StatusTableCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int col) {
setIcon(imgGray);
setText((String)value);
return this;
} // End getTableCellRendererComponent(JTable, Object, boolean, boolean, int, int)
} // End class StatusTableCellRenderer
} // End class MonitorTable
最佳答案
My model has already been defined to return JLabel.class for these cells,
但是根据渲染器中的代码,您希望这些单元格中有一个字符串值:
setText((String)value);
我不喜欢你的 setIcon() 方法。我不会传入 URL。我会传递图标。可能你有一个问题,在单元格被渲染的时候图标还没有被读入内存。
what is the best way to get and set an icon to a JLabel cell of a JTable,
您不应在 TableModel 中存储 JLable。在模型中存储 Swing 组件是昂贵的,这就是 Swing 组件使用渲染器的原因。相反,您存储一个自定义对象,如“LabelInfo”,它包含两个属性,文本和图标。然后您的自定义渲染器将扩展默认渲染器并调用 super.getTableCellRendererComponent()。然后您可以访问您的对象并保留渲染器的文本/图标属性。您不应该在渲染器中创建对象。
现在,当您想要更改模型中的某些内容时,您可以执行以下操作:
LabelInfo info = (LabelInfo)table.getValueAt(row, column);
info.setIcon(...);
table.setValueAt(info, row, column);
这就是您所需要的。没有自定义代码来重新绘制单元格或任何东西,因为它已经内置到 setValueAt(...) 方法中。你的表模型。
编辑:在 TableModel 中使用自定义对象的简单示例。
1) 要将对象添加到模型中,您可以执行以下操作:
LabelInfo info = new LabelInfo("some Text", yourIcon);
table.setValueAt(info, row, column);
2) 自定义渲染器的代码是:
class LabelInfoRenderer extends DefaultTableCellRenderer
{
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
LableInfo info = (LabelInfo)value;
setIcon( info.getIcon() );
return this;
}
}
关于java - 更新 JTable 单元格的 ImageIcon,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4740202/