Scala Popup Menu - PullRequest
       19

Scala Popup Menu

3 голосов
/ 02 июня 2009

Как заставить всплывающее окно показываться в Scala? У меня есть "черный ход", но мне это кажется довольно уродливым:

val item = new MenuItem(new Action("Say Hello") {
  def apply = println("Hello World");
})
//SO FAR SO GOOD, NOW FOR THE UGLY BIT!
val popup = new javax.swing.JPopupMenu
popup.add(item.peer)
popup.setVisible(true)

Ответы [ 2 ]

6 голосов
/ 22 июня 2011

Я знаю, что вопросу два года, но я думаю, что стоит обновить с другим ответом. Вот мое решение:

import javax.swing.JPopupMenu
import scala.swing.{ Component, MenuItem }
import scala.swing.SequentialContainer.Wrapper

object PopupMenu {
  private[PopupMenu] trait JPopupMenuMixin { def popupMenuWrapper: PopupMenu }
}

class PopupMenu extends Component with Wrapper {

  override lazy val peer: JPopupMenu = new JPopupMenu with PopupMenu.JPopupMenuMixin with SuperMixin {
    def popupMenuWrapper = PopupMenu.this
  }

  def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y)

  /* Create any other peer methods here */
}

Вот пример кода использования:

val popupMenu = new PopupMenu {
  contents += new Menu("menu 1") {
    contents += new RadioMenuItem("radio 1.1")
    contents += new RadioMenuItem("radio 1.2")
  }
  contents += new Menu("menu 2") {
    contents += new RadioMenuItem("radio 2.1")
    contents += new RadioMenuItem("radio 2.2")
  }
}
val button = new Button("Show Popup Menu")
reactions += {
  case e: ButtonClicked => popupMenu.show(button, 0, button.bounds.height)
}
listenTo(button)

Некоторые вещи на заметку:

  1. Использование класса SuperMixin в соответствии с рекомендациями scala-swing-design.pdf , в разделе «Рекомендации по написанию оболочек», подраздел «Использование кэша оболочек».
  2. Mixin scala.swing.SequentialContainer.Wrapper, чтобы я мог использовать конструкцию contents +=, чтобы мой код всплывающего меню был похож на другой код построения scala-swing Menu.
  3. Хотя в вопросе используется JPopupMenu.setVisible, я думаю, что вы захотите перенести и использовать метод JPopupMenu.show, чтобы вы могли контролировать местоположение всплывающего меню. (Просто установив его на видное место, я помещу его в верхний левый угол экрана.)
4 голосов
/ 02 июня 2009

То, что вы делаете, хорошо, но если вы хотите скрыть одноранговый вызов, вы можете создать собственный класс:

class PopupMenu extends Component
{
  override lazy val peer : JPopupMenu = new JPopupMenu

  def add(item:MenuItem) : Unit = { peer.add(item.peer) }
  def setVisible(visible:Boolean) : Unit = { peer.setVisible(visible) }
  /* Create any other peer methods here */
}

Тогда вы можете использовать это так:

val item = new MenuItem(new Action("Say Hello") {
  def apply = println("Hello World");
})

val popup = new PopupMenu
popup.add(item)
popup.setVisible(true)

В качестве альтернативы, вы можете попробовать SQUIB (Scala's Quirky User Interface Builder). При использовании SQUIB указанный код становится:

popup(
  contents(
    menuitem(
      'text -> "Say Hello",
      actionPerformed(
        println("Hello World!")
      )
    )
  )
).setVisible(true)
...