سؤال

كنت تستخدم جافا التقليدية TableCellRenderer نهج لتوفير العارض في 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). بالتأكيد عندما استبدل طاولة SCALA الخاصة بي JTable (باستخدام نفسه بالضبط عمود و البيانات نماذج) يذهب تسرب الذاكرة الخاصة بي.

سؤالي هو لذلك، أي نوع من التعليمات البرمجية يستخدم الناس عند تجاوز rendererComponent الطريقة على افتراض واحد لديه العروض العارض خلية خاصة؟

هل كانت مفيدة؟

المحلول

الطريقة الاصطلاحية لاستخدام مصادرات خلية الجدول 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
  }
}

ثم يتم استخدام هذا عن طريق تجاوز 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 الذي يأخذ وظيفة كوسيطة، تحويل مثيل myobj. إلى أ Tuple2 تتكون من أ String و Icon, ، لهذا الملصق لعرض:

val ltcr = new LabelRenderer[MyObj] ( (o: MyObj) => (null, o.toString)  )

نصائح أخرى

شكرا طن للمثال oxbow_lakes!

IMHO أصبح هذا الشيء 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
}

باستخدام مثل (على الأقل "التكوين" ذهب ...)

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
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top