问题
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