问题描述:
    我把一个JPanel jpanel放在一个JScrollPane jscrollpane里面,jpanel响应键盘事件,比如上下左右键移动里面的图象。问题是此时jscrollpane的滚动条会跟着动,因为键盘事件会传递到jscrollpane,那我在jpaneld的键盘事件处理函数里把键盘事件毁掉,像下面这样:
public void keyPressed(KeyEvent keyevent)
{
    ...//事件处理,略
    keyevent.consume();
}
这样按键盘方向键时jscrollpane的滚动条就不会跟着动了。但是问题又来了,原来定义的菜单快捷键不响应了。定义菜单快捷键的代码如下:
jmenuitem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, InputEvent.ALT_MASK));
本来是打算在jpanel按ALT+2后图象放大2倍,由于jpanel处理键盘事件后把KeyEvent销毁了,键盘事件不能发送给菜单,不知道这个情况怎么处理?是否可以在keyevent.consume()之前手动把事件传给菜单处理,那调用什么函数?或者有其它的办法...

解决方案 »

  1.   

    重写JScrollPane的processKeyEvent方法
    protected void processKeyEvent(KeyEvent evt) {
      if (isSkippedEvent(evt)) {
        return;
      }
      super.processKeyEvent(evt);
    }
    不知道行不行?或者直接取得JScrollPane的UI, 通过uninstallKeyboardActions的方式来做, 不过这个要看看源码怎么写的, 这个方法是protected. 而且事件可能是在ScrollPane上, 也可能在ScrollBar上.
      

  2.   

    先谢谢楼上的
    第一中方法是可以的,不过感觉有点不自然
    系统processKeyEvent()的调用是先于keyPressed()的,也就是说先把事件传递给上层,然后自己再响应事件。若重写processKeyEvent(),在processKeyEvent()中要先判断事件的性质然后选择是return还是super.processKeyEvent()。(在我的例子中是判断是否按了上下左右键,若是就直接return)。但return后组件本身就不响应此事件了,也不向上传递此事件了,所以若只让自身响应事件而不传递给其它地方也响应,就要在return前显式地调用keyPressed()。这样产生的问题是会调用2次keyPressed(),因为KeyReleased事件时系统也会调用processKeyEvent(),导致按1次方向键图象移动2个象素,这就不好了顺便问一下怎么在processKeyEvent(keyEvent)里判断keyEvent是按下按键还是释放按键事件??
    第二中方法不知道怎么实现
      

  3.   

    判断keyEvent为按下事件的代码:
    if (keyevent.getID() == KeyEvent.KEY_PRESSED)