Search code examples
javaswingscalajtabletablerowsorter

(J)Table doesn't sort despite having enabled auto-row-sorter and using comparable data


I can't get the following Swing table view to be sortable. While I do get the little triangles on the column headers flipping, the table content is not refreshed any differently depending on the sort status:

import scala.swing._

val data = Array(
  Array("a", 4, 8.9),
  Array("b", 7, 2.3),
  Array("c", 1, 5.6)
).map(_.map(_.asInstanceOf[AnyRef]))

val m = new javax.swing.table.DefaultTableModel(data, 
  Array[AnyRef]("string", "int", "double")) {

   override def getColumnClass(c: Int): Class[_] = c match {
     case 0 => classOf[java.lang.String ]
     case 1 => classOf[java.lang.Integer]
     case 2 => classOf[java.lang.Double ]
   }
}

val t = new Table
t.model = m
t.peer.setAutoCreateRowSorter(true)

new Frame {
  contents = new ScrollPane(t)
  pack().centerOnScreen()
  open()
}

enter image description here

I have tested this with different look-and-feels (screenshot shows Nimbus) and JDKs (OpenJDK 6, OpenJDK 7). Furthermore, I have a custom tree-table component that sorts without problems, so the mistake must lie somewhere above.


Solution

  • This is some bug in Scala-Swing. Why am I not surprised?!

    import scala.swing._
    
    type I = java.lang.Integer
    type D = java.lang.Double
    
    val data = Array[Array[Object]](
      Array("a", 4:I, 8.9:D),
      Array("b", 7:I, 2.3:D),
      Array("c", 1:I, 5.6:D)
    )
    
    val m = new javax.swing.table.DefaultTableModel(data, 
      Array[AnyRef]("string", "int", "double")) {
    
      override def getColumnClass(c: Int): Class[_] = data(0)(c).getClass
    }
    
    val tj = new javax.swing.JTable(m)  // !!!
    tj.setAutoCreateRowSorter(true)
    val t = Component.wrap(tj)          // !!!
    
    new Frame {
      contents = new ScrollPane(t)
      pack().centerOnScreen()
      open()
    }
    

    It might be this bug although the title says column-sorting is affected (the texts suggests the submitter is talking about row sorting). My guess is that the renderer-wrapping is broken in terms of viewToModel/modelToView.


    Edit: Confirmed. All it takes is

    val t = new Table {
      // disable broken renderer
      override lazy val peer: JTable = new JTable with SuperMixin
    }