问题
How do I cause a popup to get shown in Scala? I have a "backdoor" but it seems pretty ugly to me:
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)
回答1:
What you are doing is fine, but if you'd like to hide the peer call you could create your own class:
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 */
}
Then you can use it like this:
val item = new MenuItem(new Action("Say Hello") {
def apply = println("Hello World");
})
val popup = new PopupMenu
popup.add(item)
popup.setVisible(true)
As an alternative, you could try SQUIB (Scala's Quirky User Interface Builder). With SQUIB, the above code becomes:
popup(
contents(
menuitem(
'text -> "Say Hello",
actionPerformed(
println("Hello World!")
)
)
)
).setVisible(true)
回答2:
I know the question is two years old, but I think it's worth updating with another answer. Here's my solution:
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 */
}
Here is some sample usage code:
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)
Some things to note:
- Use of SuperMixin class as recommended in scala-swing-design.pdf, in section "Guidelines for Writing Wrappers", subsection "Use the wrapper cache".
- Mixin scala.swing.SequentialContainer.Wrapper so that I can use the
contents +=construct so my Popup Menu code looks like other scala-swing Menu construction code. - While the question uses
JPopupMenu.setVisible, I think you are going to want to wrap and use the methodJPopupMenu.show, so you can control the location of the Popup Menu. (Just setting it to be visible puts it in the top left-hand corner of the screen for me.)
来源:https://stackoverflow.com/questions/938753/scala-popup-menu