代码之家  ›  专栏  ›  技术社区  ›  André Hoffmann

如何在拖放过程中接收关键事件?

  •  3
  • André Hoffmann  · 技术社区  · 15 年前

    我目前正试图在拖放过程中接收关键事件,但在我看来,在拖动时焦点被移走,这样我就听不到任何关键事件。

    我正在拖动一个jcomponent子类,该子类实现keylister并请求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() 在我释放 石头 任何关键事件都会发送到 石头 .

    这个问题可能并不重要,但要说明我在做什么,这里有一个截图:

    image showing the "drag" http://img685.imageshack.us/img685/1884/pico.png (在这里,我拖动 石头 从下面的集合到上面的游戏场)。在这种状态下,我不知道怎么知道按了什么键。我需要弄清楚这一点以便能够旋转 石头 .

    1 回复  |  直到 15 年前
        1
  •  3
  •   Clinton    15 年前

    不确定在拖放过程中谁有焦点。但另一个解决问题的方法是 KeyEventDispatcher 为你的石头课 KeyboardFocusManager . 从javadoc:

    keyboardfocusmanager既是客户机代码查询焦点所有者并启动焦点更改的集中位置,也是 事件调度器 对于 全部的 FocusEvents、与Focus相关的WindowEvents和 关键事件+ .

    +我的重点。

    基本上,我们使用类似的代码在keyevents命中具有焦点的组件之前拦截它们。

    只需对特定的拖放上下文进行快速测试,就可以正常工作(只要应用程序在操作系统中有焦点)。基本上是这样的:

    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来确定在拖放过程中谁真正以焦点结束?

    无论如何,我希望这能给你一些新的想法去尝试。