Scala中的惯用表格单元渲染器 [英] Idiomatic table cell renderers in Scala
问题描述
我一直在使用传统的Java TableCellRenderer
方法在scala.swing.Table
中提供渲染器,在该渲染器中,我在表格的TableColumnModel
上声明了我的渲染器.的代码如下:
I had been using the traditional Java TableCellRenderer
approach for providing the renderers in a scala.swing.Table
where I declare my renderers on the table's TableColumnModel
. The code for this looked like:
val myTable = new Table {
lazy val tcm = initColumnModel
peer.setColumnModel(tcm)
override
protected def rendererComponent(sel: Boolean, foc: Boolean, row: Int, col: Int) = {
//GET THE VALUE FROM THE TableModel
val value = model.getValueAt(
peer.convertRowIndexToModel(row),
peer.convertColumnIndexToModel(col))
//GET THE RENDERER FROM THE ColumnModel
val renderer = tcm.getColumn(col).getCellRenderer
//WRAP IN A COMPONENT
Component.wrap(renderer.getTableCellRendererComponent(
peer,
value,
sel,
foc,
row,
col).asInstanceOf[JComponent])
}
}
不幸的是,这似乎存在内存泄漏-大概是因为我正在为表中的每个单元(约3万行)创建一个新的Component实例.当然,当我用JTable
(使用完全相同的 column 和 data 模型)替换scala表时,内存泄漏就消失了.
Unfortunately this appears to have a memory leak - presumably because I am creating a new Component instance for every cell in the table (for ~30k rows). Certainly when I replace my scala table with a JTable
(using exactly the same column and data models) my memory leak goes away.
因此,我的问题是,假设人们拥有自己的单元格渲染器,人们在覆盖rendererComponent
方法时会使用哪种代码?
My question is therefore, what sort of code do people use when overriding the rendererComponent
method assuming one has ones own cell renderers?
推荐答案
使用Scala表单元格渲染器的惯用方式是使用Table.AbstractRenderer
(如果实现自己的话)或其子类之一:
The idiomatic way of using Scala table cell renderers is to use Table.AbstractRenderer
(if implementing your own) or one of its subclasses:
val tcr = new Table.AbstractRenderer[MyObj, MyRenderer](new MyRenderer) {
def configure(t: Table, sel: Boolean, foc: Boolean, o: MyObj, row: Int, col: Int) = {
//component variable is bound to your renderer
component.prepare(o)
}
}
在这种情况下,prepare
是您将在自己的渲染器类上定义的方法:
In this case prepare
is a method you would define on your own renderer class:
class MyRenderer extends Label {
def prepare(o: MyObj) {
text = o.toString //or whatever
}
}
然后通过覆盖Table
上的rendererComponent
方法来使用此方法:
Then this is used by overriding the rendererComponent
method on Table
:
val t = new Table {
override def rendererComponent(sel: Boolean, foc: Boolean, row: Int, col: Int) = {
//FIND VALUE
val v = model.getValueAt(
peer.convertRowIndexToModel(row),
peer.convertColumnIndexToModel(row))
col match {
case 0 => tcr.componentFor(this, sel, foc, v, row, col)
}
}
}
Scala带有自己的AbstractRenderer
实现,即LabelRenderer
,它以函数作为参数,将 MyObj 的实例转换为由String
和Icon
,以显示该标签:
Scala comes with its own implementations of AbstractRenderer
, namely LabelRenderer
which takes a function as an argument, converting an instance of MyObj to a Tuple2
consisting of a String
and an Icon
, for that label to display:
val ltcr = new LabelRenderer[MyObj] ( (o: MyObj) => (null, o.toString) )
这篇关于Scala中的惯用表格单元渲染器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!