Scalaでは慣用テーブルセルレンダラー
-
19-09-2019 - |
質問
私は、テーブルのTableCellRenderer
に私のレンダラーを宣言scala.swing.Table
てレンダラーを提供するための従来のJava 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行のための)テーブル内のすべてのセルのための新しいコンポーネントのインスタンスを作成していますので、おそらく - 残念ながら、これはメモリリークを持っているように見えます。私はJTable
と私のScalaのテーブルを交換する際に確かに私のメモリリークが消える(正確に同じの列とデータのモデルを使用して)ます。
rendererComponent
メソッドをオーバーライドするとき、私の質問は、したがって、コードのどのような人々が使うのですか?
解決
Scalaの表のセルレンダラーを使用しての慣用的な方法は、(自分自身を実装する場合)Table.AbstractRenderer
を使用することですまたはそのサブクラスの1:
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
}
}
そしてこれはrendererComponent
に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
からなるTuple2
にするこのmyobjののインスタンスを変換する、String
の独自の実装では、引数として関数を取るすなわちIcon
が付属してい:
val ltcr = new LabelRenderer[MyObj] ( (o: MyObj) => (null, o.toString) )
他のヒント
あなたの例のoxbow_lakesのための
おかげでトン!
私見このスカラ-事はおそらく得ることができ、テーブルのレンダリングのように醜いとなっています。 限り、それを隠そうとし、可能な限り...
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
}
(少なくとも "の設定が" 消えた...)のように使用します。
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
}
}
所属していません StackOverflow