0

I'm building an application with variable number and configuration of buttons, and the application needs to listen the button clicked event, and process them.

Due to the requirements of variable number of buttons, and configurations, I feel that I must call listenTo for the just dynamically created button, in the BoxPanel scope. But I found that the buttons' event would not be received.

However, if I remember a created button, and call listenTo outside of the scope of BoxPanel, then its event would be received.

I'm wondering what's the matter why listenTo not working in the scope of BoxPanel? I didn't see any compiler error for such usage anyway.

Below is my sample code:

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

Thanks a lot for your help!

Yu

Yu Shen
  • 2,770
  • 3
  • 33
  • 48

1 Answers1

1

Is this what you mean?

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

Edit

Luigi Plinge has a good suggestion, instead of this:

  def top = new MainFrame {

    val main = this

You could also do this:

  def top = new MainFrame { main =>

And he also provided the following links:

Community
  • 1
  • 1
EECOLOR
  • 11,184
  • 3
  • 41
  • 75
  • Thanks! The "val main = this" and "main listenTo key" are missing. It might have caused to register at the scope of BoxPanel, but the reaction is still defined at the scope of FlowPanel. This might have caused the failure of responding. Thanks again for @EECOLOR's timely help! – Yu Shen Feb 16 '13 at 11:46
  • 1
    @YuShen I haven't tried it, but I think a self alias should work. In the above, just replace the `val main = this` with `main =>`. See for example http://stackoverflow.com/q/8073263/770361 and http://stackoverflow.com/q/6825729/770361 – Luigi Plinge Feb 16 '13 at 21:35
  • Yeah, that's a great idea! – EECOLOR Feb 17 '13 at 15:21