如何从外部类以编程方式更新Scala / Swing?

时间:2011-09-06 07:18:25

标签: java swing scala scala-swing

例如,以下代码显示了一个简单的表

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
  }

}

假设我有一个外部类

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

如何使用计数器i?

更新SunsetTable“价格”列

2 个答案:

答案 0 :(得分:2)

当您说lazy val ui = new BoxPanel(Orientation.Vertical) { ... }时,您正在对BoxPanel类进行新的匿名扩展。 ui是一个BoxPanel,因此只有公共BoxPanel成员才能在外部范围内看到。

解决这个问题的一种方法是将table的声明移到BoxPanel之外,这样它就是SunsetTable的一个字段。然后你可以说

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

你也可以按原样保留你的代码并说出

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

最后,您可以声明一个扩展BoxPanel并包含updateTable方法的新类,并生成ui及其实例,或者创建一个可以使用的Updatable特征在ui delclaration中,使您的ui类型BoxPanel with Updatable,以便您可以访问updateTable方法。

答案 1 :(得分:1)

我不知道Scala,但我知道你不能在事件发送线程上sleep()。您需要等同于continuation的Scala来进行更新。

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