scala.swing

scala swing table model

I’ve been playing with scala.swing as an alternative to java.swing to develop a bit of code for spectral analysis. I’ve not had much experience with java GUI work before but the stuff I have been exposed to hasn’t been fun. Scala however is fun to write, so i figured I would take a look at it as an alternative.

To GUI I need to develop needs to look identical to the one already in use, this means dumping some of the data into a table. When I was looking into this, the doc for scala.swing wasn’t very good but I did find the default table model…

import scala.swing._
import javax.swing.table._

object MyTable extends SimpleSwingApplication {
  def top = new MainFrame {
    title = "MyTable"
    preferredSize  = new Dimension( 100,100 )
    val tableModel = new DefaultTableModel( new Array[Array[AnyRef]](0,2), Array[AnyRef]("A", "B") )
    val table      = new Table( 1, 2 ) { model = tableModel }
   
    for ( i <- 0 to 10 ) { 
		tableModel.addRow( Array[AnyRef]( i.asInstanceOf[AnyRef], (i*2).asInstanceOf[AnyRef] ) ) 
	}

    contents = new BorderPanel {
      import BorderPanel.Position._
      add(new ScrollPane(table), Center)
    }
  }
}

Apparently this isn’t the ideal way to implement a table. Instead a new class should be implemented that extends the AbstractTableModel:

class MyTableModel( var rowData: Array[Array[Any]], val columnNames: Seq[String] ) extends AbstractTableModel {
  override def getColumnName( column: Int) = columnNames(column).toString
  def getRowCount() = rowData.length
  def getColumnCount() = columnNames.length
  def getValueAt( row: Int, col: Int): AnyRef = rowData(row)(col).asInstanceOf[AnyRef]
  override def isCellEditable( row: Int, column: Int) = false
  override def setValueAt( value: Any, row: Int, col: Int) {
    rowData(row)(col) = value
  }    
  def addRow( data: Array[AnyRef]) {
    rowData ++= Array(data.asInstanceOf[Array[Any]])
  }
}

Then, when creating the table model:

val tableModel = new MyTableModel( Array[Array[Any]](), List("A","B") )

When used instead of the defaultTableModel, the code looks something like this:

import scala.swing._
import javax.swing.table._

object MyTable extends SimpleSwingApplication {
  def top = new MainFrame {
    title = "MyTable"
    preferredSize  = new Dimension( 100,270 )
    val tableModel = new MyTableModel( Array[Array[Any]](), List("A","B") )
    val table      = new Table( 1, 2 ) { model = tableModel }
   
    for ( i <- 0 to 10 ) { tableModel.addRow( Array[AnyRef]("i", "j") ) }

    contents = new BorderPanel {
      import BorderPanel.Position._
      add(new ScrollPane(table), Center)
    }
  }
}

The result should be a table in the top left hand corner of the monitor – how very exciting. A disadvantage of using scala.swing instead of java.swing is the lack of a netbeans-like environment that helps out (I am not familiar with GUI development in either language – as is probably obvious to someone who is). Life can be made a little easier using the scala eclipse plugin rather than emacs. I am also a fairly basic level user of scala & java.