deltanovember
deltanovember

Reputation: 44051

How do I update a Scala/Swing programmatically from an external class?

For example the following code shows a simple table

import java.awt.Dimension
import swing._

object SunsetTable extends SimpleSwingApplication {

  var model = Array(List("BHP", 1).toArray)

  lazy val ui = new BoxPanel(Orientation.Vertical) {
    val table = new Table(model, Array("Security", "Price")) {
      preferredViewportSize = new Dimension(1200, 600)
    }
    contents += new ScrollPane(table)
  }

  def top = new MainFrame {
    contents = ui
  }

}

Suppose I have an external class

class Counter {
    for (i <- 1 to 10) {
        // update SunsetTable with i
        Thread.sleep(1000)
    }
}

How would I update SunsetTable "Price" column with the counter i?

Upvotes: 1

Views: 824

Answers (2)

trashgod
trashgod

Reputation: 205785

I don't know Scala, but I know you can't sleep() on the event dispatch thread. You need the Scala equivalent of a continuation to do the update.

class Counter {
    for (i <- 1 to 10) {
        // begin Java
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                // update SunsetTable with i
            }
        });
        // end Java
        Thread.sleep(1000)
    }
}

Upvotes: 1

Luigi Plinge
Luigi Plinge

Reputation: 51109

When you say lazy val ui = new BoxPanel(Orientation.Vertical) { ... } you're making a new anonymous extension to the BoxPanel class. ui is a BoxPanel so only public BoxPanel members are visible in the outside scope.

One way to get around this is to move the declaration of table outside of the BoxPanel so that it's a field of SunsetTable. Then you can say

SunsetTable.table.update(0,0,"ABC")

You could also keep your code as it is and say

SunsetTable.ui.contents(0).asInstanceOf[ScrollPane].contents(0)
 .asInstanceOf[Table].update(0,0,"ABC")

Finally, you could either declare a new class that extends BoxPanel and includes an updateTable method, and make ui and instance of that, or make an Updatable trait that you can use in the ui delclaration, making your ui type BoxPanel with Updatable, so you can access the updateTable method.

Upvotes: 2

Related Questions