我目前正在尝试在拖放过程中接收关键事件,但在我看来,拖动时焦点被带走,因此我无法收听任何关键事件。
我正在拖动一个实现 KeyListener 的 JComponent 子类,并在 DragSourceListener 的 dragEnter 方法中请求焦点,但我的假设是之后焦点会从它身上移开。
现在,谁获得了焦点,我如何将其带回我的 JComponent。或者有没有更适合dnd的不同方法?
先感谢您。
更新 :
完成这项工作需要很多代码,所以我只会发布一些片段来向您展示我正在尝试做的事情:
public class Stone extends JComponent implements Serializable, KeyListener {
public Stone(...) {
//...
setFocusable(true);
addKeyListener(this);
this.dragSource = DragSource.getDefaultDragSource();
this.dgListener = new StoneDGListener();
this.dsListener = new StoneDSListener();
this.dragSource.createDefaultDragGestureRecognizer(
this,
DnDConstants.ACTION_MOVE,
this.dgListener
);
//...
}
//...
public void keyPressed(KeyEvent e) {
System.out.println("Stone: "+e.getKeyCode());
}
//...
public class StoneDSListener implements DragSourceListener, Serializable {
//...
@Override
public void dragEnter(DragSourceDragEvent dsde) {
//...
Stone.this.requestFocus();
addKeyListener(Stone.this);
}
//...
}
}
发生的情况是,在我拖动
Stone
组件之前,我的 JPanel 具有焦点,因此它接收我按下的任何键。在拖动过程中,我听不到任何按下的键(所以我不知道谁得到了焦点),即使我在
dragEnter()
中请求它,并且在我释放 Stone
后,任何键事件都发送到 Stone
。这个问题可能并不重要,但为了说明我在做什么,这里有一个截图:
image showing the "drag" http://img685.imageshack.us/img685/1884/pico.png
(这里我将
Stone
从下面的集合中拖到顶部的游戏字段中)。在这种状态下,我不知道如何找出按下了哪些键。我需要弄清楚这一点才能旋转 Stone
。 最佳答案
不确定在拖放过程中谁有焦点。但是您的问题的另一种解决方案是为您的 Stone 类添加一个 KeyEventDispatcher 到 KeyboardFocusManager 。来自 JavaDoc:
+ 我的焦点。
基本上,我们使用类似的代码在 KeyEvents 命中具有焦点的 Component 之前拦截它们。
刚刚对您的特定拖放上下文进行了快速测试,它似乎可以正常工作(只要您的应用程序在操作系统内具有焦点)。基本上是这样的:
Public Stone(...) {
// ...
KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
fm.addKeyEventDispatcher(
new KeyEventDispatcher() {
public boolean dispatchKeyEvent(KeyEvent e) {
System.out.println("Key Press: " + e.getKeyChar());
return false;
}
}
);
// ...
}
当用户不再拖放时,您将需要在启用和禁用方面做一些工作,因为我的测试当前一直在打印。
我还想知道是否可以使用 KeyboardFocusManager 来确定谁在拖放过程中最终获得了焦点?
不管怎样,我希望这会给你一些新的尝试。