Writing own key publisher for MainFrame
I want my MainFrame to catch key events. I didn't find any key publisher already in it, so I'm going to write my own ... I have something like this:
class ImageView(image: ImageIcon, parent: U开发者_开发百科IElement = null) extends MainFrame {
object keys extends Publisher {
peer.addKeyListener(new KeyListener {
def keyPressed(e: java.awt.event.KeyEvent) {
publish(new KeyPressed(e))
}
def keyReleased(e: java.awt.event.KeyEvent) {
publish(new KeyReleased(e))
}
def keyTyped(e: java.awt.event.KeyEvent) {
publish(new KeyTyped(e))
}
})
}
listenTo(keys)
reactions += {
case KeyPressed(_, key,_,_) =>
if (key == Key.Escape) dispose
}
}
Anyway when I press any key, I get this exception:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: scala.swing.Frame$$anon$1 cannot be cast to javax.swing.JComponent
at scala.swing.event.KeyPressed.<init>(KeyEvent.scala:33)
at pip.gui.ImageView$keys$$anon$2.keyPressed(ImageView.scala:35)
at java.awt.Component.processKeyEvent(Component.java:6225)
at java.awt.Component.processEvent(Component.java:6044)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Window.processEvent(Window.java:1836)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
at
.
.
.
.
(continues long further)
I brought up this publisher code from Component.keys, so what is actually wrong here?
Thanks in advance, Tony
This seems bad design in the library. Looking into KeyEvent.scala
, there's all kinds of casting to JComponent
going on, and JFrame
is a subclass of java.awt.Component
but not JComponent
, so it should be impossible to call listenTo(keys)
.
What you want is to listen to the top-most component in the frame's contents
. For instance:
import scala.swing._; import event._
import javax.swing._
class ImageView(image: ImageIcon, parent: UIElement = null) extends MainFrame {
val b = new BorderPanel {
listenTo( keys )
reactions += {
case KeyPressed(_, key,_,_) =>
println( "PRESSED : " + key )
if (key == Key.Escape) dispose
}
}
contents = b
}
val w = new ImageView( null )
w.peer.setSize( 200, 200 )
w.visible = true
w.b.requestFocus
the requestFocus
is essential because the panel doesn't request the focus by itself even if you click on it, so otherwise it wouldn't receive key events.
精彩评论