Scala中的惯用表格单元渲染器 [英] Idiomatic table cell renderers in Scala

查看:135
本文介绍了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 的实例转换为由StringIcon,以显示该标签:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆