2009-06-02 2 views
3

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

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) 

ответ

4

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

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) 

В качестве альтернативы, вы можете попробовать Петарда (Необычных пользователя в Scala Interface Builder). С Петардой, приведенным выше код становится:

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

Почему это (всплывающее меню) не входит в стандартный набор инструментов Scala Swing? Я должен сказать, что меня немного встревожило отсутствие документации вместе с некоторыми довольно базовыми конструкциями. Заставляет меня задаться вопросом, действительно ли кто-то использует набор инструментов. –

+1

oxbow, да, люди действительно используют scala-swing. Отсутствие документации не удивительно. Стоимость/выгода просто не заканчивается, так как большинство методов в scala-swing - простые простые сопоставления методам Java Swing. Я бы не стал рассматривать JPopupMenu как «базовую конструкцию», и, хотя это немного вопиющий надзор, примите во внимание объем усилий, связанных с упаковкой всех возможных компонентов Swing. В пакетах scala.swing и scala.swing.event имеется более 100 классов. –

+0

Я знаю, что этот ответ два года, но метод PopupMenu.setVisible не нужен. Когда вы наследуете метод 'Component.visible_ =', вы уже можете сказать 'popup.visible = true'. –

6

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

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, в разделе «Руководство по Writing Wrappers ", подраздел« Использование кэша обертки ».
  2. Mixin scala.swing.SequentialContainer.Wrapper, так что я могу использовать конструкцию contents +=, поэтому код Popup Menu выглядит как другой код построения Scala-Swing.
  3. Хотя вопрос использует JPopupMenu.setVisible, я думаю, что вы захотите обернуть и использовать метод JPopupMenu.show, чтобы вы могли управлять расположением всплывающего меню. (Просто установив его для отображения, он помещает его в верхний левый угол экрана для меня.)