scalaのDynamicVariableの使い方

1996 ワード

 package org.scalatra
import scala.util.DynamicVariable
import javax.swing._

/**
 * Created by IntelliJ IDEA.
 * User: evilyzou
 * Date: 2010-8-20
 * Time: 14:29:05
 * To change this template use File | Settings | File Templates.
 */

object SwingBuilder{
  case class Context(frame: Option[JFrame],parent: Option[JComponent])
}

class SwingBuilder{
  import SwingBuilder._
  val context=new DynamicVariable[Context](Context(None,None))

  def frame(title: String)(f: =>Unit)={
    val res=new JFrame(title)
    res.add(new JPanel())
    context.withValue(Context(Some(res),context.value.parent)){f;res}
  }

  def menuBar(f: =>Unit)={
    val mb=new JMenuBar()
    context.value.frame.foreach(_.setJMenuBar(mb))
    context.withValue(Context(context.value.frame,Some(mb))){f;mb}
  }

  def menu(title:String)(f: =>Unit)={
    val m=new JMenu(title)
    var m2=new JMenu(title+"Test")
    context.value.parent.foreach(_.asInstanceOf[JMenuBar].add(m))
    context.value.parent.foreach(_.asInstanceOf[JMenuBar].add(m2))
    context.withValue(Context(context.value.frame,Some(m))){f;m}
    context.withValue(Context(context.value.frame,Some(m2))){f;m2}
  }

  def menuItem(title:String)={
    val mi=new JMenuItem(title)
    context.value.parent.foreach(_.asInstanceOf[JMenu].add(mi))
  }
}

object Test{

  def main(args:Array[String]){
    val builder=new SwingBuilder()
    import builder._

    val f=frame("Demo"){
      val mb=menuBar{
        menu("File"){
          menuItem("New")
          menuItem("Open")
          menuItem("SSS")
      }
    }
    mb
  }
  f.setVisible(true)
}
}