2009-07-28 41 views
9

Tôi đã sử dụng phương pháp Java TableCellRenderer truyền thống để cung cấp các trình kết xuất trong một scala.swing.Table nơi tôi khai báo các bộ hiển thị của mình trên bảng TableColumnModel. Mã này trông giống như:Các bộ hiển thị tế bào bảng trong Scala

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

Đáng tiếc là điều này dường như có một rò rỉ bộ nhớ - có lẽ vì tôi đang tạo ra một trường hợp phần mới cho mỗi tế bào trong bảng (cho ~ hàng 30k). Chắc chắn khi tôi thay thế bảng scala của mình bằng một số JTable (sử dụng chính xác các cột dữ liệu) rò rỉ bộ nhớ của tôi biến mất.

Câu hỏi của tôi là do đó, loại mã nào mọi người sử dụng khi ghi đè phương pháp rendererComponent giả sử một người có trình kết xuất ô của riêng mình?

Trả lời

8

Cách thành ngữ sử dụng Scala kết xuất đồ họa ô trong bảng là sử dụng Table.AbstractRenderer (nếu thực hiện của riêng bạn) hoặc một trong các lớp con của nó:

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

Trong trường hợp này prepare là một phương pháp bạn sẽ xác định trên renderer của riêng bạn lớp:

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

Rồi này được sử dụng bằng cách ghi đè các phương pháp rendererComponent trên 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 đi kèm với hiện thực riêng của mình AbstractRenderer, cụ thể là LabelRenderer mà phải mất một chức năng như một tham số, chuyển đổi một thể hiện của myObj đến một Tuple2 bao gồm một String và một Icon, cho nhãn đó để hiển thị:

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

Tôi nghĩ rằng bạn muốn 'peer.convertColumnIndexToModel (col) 'thay vì' peer.convertColumnIndexToModel (hàng) ' –

+0

Bạn cũng có thể sử dụng' scala.swing.Table.viewToModelColumn (Int): Int'. Lưu ý chắc chắn lý do tại sao không có phương thức trình bao bọc tương đương cho các hàng .. –

1

Cảm ơn một tấn cho ví dụ oxbow_lakes của bạn!

IMHO điều scala này đã trở nên xấu xí khi hiển thị bảng có thể có thể nhận được. Cố gắng giấu nó càng nhiều càng tốt ...

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 
} 

Sử dụng tương tự (ít nhất là "cấu hình" đã biến mất ...)

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 
    } 
} 
+0

Tôi đã đọc nhận xét của bạn nhưng lúc đầu không nhận được. Chỉ sau khi tôi tạo ra một số lớp con của 'Table.AbstractRenderer' tôi mới nhận ra tại sao tôi cần mã của bạn. Cải tiến tôi sẽ bổ sung là bạn cũng có thể chuyển các tham số 'configure()' còn lại thành 'render (a, sel, foc, row, col)'. Cuối cùng tôi cần tất cả chúng – Core

Các vấn đề liên quan