مصطلح خلية الطاولة الاصطلاحية في سكالا
-
19-09-2019 - |
سؤال
كنت تستخدم جافا التقليدية 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
}
}