Scala / Swing:listenTo到BoxPanel范围内刚刚创建的按钮不起作用?

时间:2013-02-16 08:48:17

标签: swing scala subscribe

我正在构建一个具有可变数量和按钮配置的应用程序,应用程序需要监听按钮单击事件并处理它们。

由于可变数量的按钮和配置的要求,我觉得我必须在listenTo范围内为刚刚动态创建的按钮调用BoxPanel。但我发现按钮的事件不会被收到。

但是,如果我记得创建的按钮,并且在listenTo范围之外调用BoxPanel,则会收到其事件。

我想知道为什么listenTo无法在BoxPanel的范围内工作?无论如何,我没有看到任何编译器错误。

以下是我的示例代码:

import scala.swing._
import scala.swing.event._

object TouchSelectUI extends SimpleSwingApplication {
  val touchMap = Vector(
    Vector("a", "b", "c"),
    Vector("d", "e", "g")
    // more may be defined in the future
  )
  val keyDemension = new Dimension(40, 25)
  def top = new MainFrame {
    title = "Touch Select Experiment"
    val input = new TextArea {
      columns = 80
      text = ""
    }
    var aButtonRemebered = new Button()
    contents = new FlowPanel {
      require(touchMap.size > 0, {println("The touch key definition is empty!")})
      for (c <- 0 until touchMap(0).size) {
    contents += new BoxPanel(Orientation.Vertical) {
      for (r <- 0 until touchMap.size) {
        val key = new Button {
        text = touchMap(r)(c)
          }
        contents += key
        aButtonRemebered = key
        listenTo(key) // listenTo here does not work.
      }
    }
      }
    contents += input 
    }

    //listenTo(aButtonRemebered) // Here listTo would work to deliver the event to the following reaction!
    reactions += {
      case ButtonClicked(b) => {
    println(s"Button clicked!")
    val c = b.text
    input.text = input.text + c
      }
    }
  }
}

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

这是你的意思吗?

object TouchSelectUI extends SimpleSwingApplication {

  //..

  def top = new MainFrame {

    val main = this

    //..

    contents = new FlowPanel {
      //..
      for (c <- 0 until touchMap(0).size) {
        contents += new BoxPanel(Orientation.Vertical) {
          for (r <- 0 until touchMap.size) {
            val key = new Button
            //..
            main listenTo key
          }
        }
      }
    }
  }
}

修改

Luigi Plinge有一个很好的建议,而不是:

  def top = new MainFrame {

    val main = this

你也可以这样做:

  def top = new MainFrame { main =>

他还提供了以下链接: