为MainFrame编写自己的密钥发布者

时间:2011-04-03 18:18:14

标签: scala

我希望我的MainFrame能够捕获关键事件。我没有找到任何关键的出版商,所以我要写自己的...我有这样的事情:

class ImageView(image: ImageIcon, parent: UIElement = 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
  }

}

无论如何,当我按任意键时,我得到了这个例外:

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)

我从Component.keys中提出了这个发布商代码,那么这里究竟出现了什么问题?

提前致谢, 贝

1 个答案:

答案 0 :(得分:2)

这在图书馆看起来很糟糕。展望KeyEvent.scalaJComponent正在进行各种投射,而JFramejava.awt.Component但不是JComponent的子类,所以它应该是不可能的致电listenTo(keys)

您想要的是聆听框架contents中最顶层的组件。例如:

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

requestFocus是必不可少的,因为即使您点击它,面板也不会自行请求焦点,否则它将不会收到关键事件。