我目前正在尝试在拖放过程中接收关键事件,但在我看来,拖动时焦点被移除,因此我无法收听任何关键事件。
我正在拖动一个实现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
。
答案 0 :(得分:3)
在拖放过程中不确定谁有焦点。但是,对您的问题的另一种解决方案是为您的Stone类添加KeyEventDispatcher到KeyboardFocusManager。来自JavaDoc:
KeyboardFocusManager既是客户端代码的集中位置,可以查询焦点所有者并启动焦点更改, 的 事件调度程序 FocusEvents,与焦点相关的WindowEvents,以及 KeyEvents + 。
+我的重点。
基本上我们使用类似的代码拦截KeyEvent,然后才能点击具有焦点的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来确定在拖放过程中谁最终得到了焦点?
无论如何,我希望这会给你一些新想法。