scala.swing.PopupMenu を実装

Scala には swing をラップした scala.swing というパッケージが標準で含まれています。Panel、Button、Table などのコンポーネントScala から扱いやすい形で提供されている一方、 JPopupMenu や JTree といったコンポーネントは提供されていません。
しかしながら、既存の swing コンポーネントをラップするのはそれほど難しくないため、ちょうど必要になった JPopupMenu を使えるようにしてみました。

ソースコードは以下のとおり。

package scala.swing

import javax.swing.JPopupMenu

class PopupMenu(title0: String) extends Component with SequentialContainer.Wrapper { self: PopupMenu =>
  def this() = this("")
  override lazy val peer: JPopupMenu = new JPopupMenu(title0)
}

trait PopupMenuContainer { self: Component =>
  def componentPopupMenu: PopupMenu = Component.wrapperFor(peer.getComponentPopupMenu)
  def componentPopupMenu_=(p: PopupMenu) = peer.setComponentPopupMenu(p.peer)

  def inheritsPopupMenu: Boolean = peer.getInheritsPopupMenu
  def inheritsPopupMenu_=(b: Boolean) = peer.setInheritsPopupMenu(b)
}

PopupMenu が JPopupMenu をラップしたコンポーネントになります。PopupMenuContainer は PopupMenu を追加する先のコンポーネントに mix-in するトレイトになります。

以下は使用例です。

package scala.swing.example

import swing._

object PopupMenuExample extends SimpleGUIApplication {
  override lazy val top = new MainFrame {
    contents = new FlowPanel with PopupMenuContainer {
      componentPopupMenu = new PopupMenu {
        contents += new MenuItem("foo")
        contents += new MenuItem("bar")
        contents += new MenuItem("baz")
      }

      contents += new Button("Inherits") with PopupMenuContainer {
        inheritsPopupMenu = true
      }
      contents += new Button("Not Inherit") with PopupMenuContainer {
        inheritsPopupMenu = false
      }
      contents += new Button("Override") with PopupMenuContainer {
        componentPopupMenu = new PopupMenu {
          contents += new MenuItem("x")
          contents += new MenuItem("y")
        }
      }
    }
  }
}

[Inherits] ボタン上では 「foo」「bar」「baz」の三つを含むポップアップメニューが表示されます。[Not Inherit] ボタン上ではポップアップメニューは表示されません。また、[Override] ボタン上では 「x」「y」の二つを含むポップアップメニューが表示されます。