9

我一直在使用传统的 JavaTableCellRenderer方法来提供渲染器,scala.swing.Table我在表的TableColumnModel. 代码如下:

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])
   }
}

不幸的是,这似乎有内存泄漏 - 大概是因为我正在为表中的每个单元格(约 30k 行)创建一个新的 Component 实例。JTable当然,当我用(使用完全相同的数据模型)替换我的 scala 表时,我的内存泄漏就消失了。

rendererComponent因此,我的问题是,假设一个人拥有自己的单元格渲染器,人们在覆盖该方法时会使用什么样的代码?

4

2 回答 2

8

使用 Scala 表格单元格渲染器的惯用方式是使用Table.AbstractRenderer(如果实现您自己的)或其子类之一:

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,您将在自己的渲染器类上定义一个方法:

class MyRenderer extends Label {
  def prepare(o: MyObj) {
      text = o.toString //or whatever
  }
}

然后通过覆盖rendererComponenton 方法来使用它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的实例转换为由a和 anTuple2组成的 a ,以便显示该标签:StringIcon

val ltcr = new LabelRenderer[MyObj] ( (o: MyObj) => (null, o.toString)  )
于 2009-08-28T15:13:37.297 回答
1

非常感谢您的示例 oxbow_lakes!

恕我直言,这个 scala 的东西已经变得像表格渲染一样丑陋。试图尽可能地隐藏它......

class TableRenderer[A](comp: TableRendererComp[A]) extends Table.AbstractRenderer[A,TableRendererComp[A]](comp) {
  def configure(t: Table, sel: Boolean, foc: Boolean, a: A, row: Int, col: Int): Unit =
    component.render(a, sel, foc)
}

trait TableRendererComp[A] extends Component {
  def render(a: A, sel: Boolean, foc: Boolean): Unit
}

使用like(至少“配置”消失了......)

val tcr = new TableRenderer[MyObj](new MyRenderer)

class MyRenderer extends Label with TableRendererComp[MyObj] {
  def render(o: MyObj, sel: Boolean, foc: Boolean) {
     text = o.toString //or whatever
  }
}
于 2012-01-12T22:53:36.140 回答