Java - Can we detect if a key is pressed without using a Listener?
Asked Answered
G

4

6

I need to be able to detect if a certain key (e.g. CTRL) is pressed during a specific operation of mine. I don't have access to a key listener, nor to a mouse event. What I'm hoping is that there will be some class that has a method like "boolean isKeyPressed(keycode)".

Is anyone aware of a method like this in java?

For a bit of background, I am trying to override the default drag & drop behaviour for a component. By default, according to the javadocs for DropTargetDragEvent, if no key modifier is pressed, then the it looks in the component's supported actions list for a move, then a copy & then a link and stops after finding the first one.

In my application, we support both copy & link. As per the javadoc, without the CTRL key pressed, the default action is copy. We want the user to be able to specify the default action (allowing them to set their most commonly used) and then force a specific one using the modifier keys.

If I can detect the key pressed state then I can force this to happen but I can't see any other way of changing the default action.

Thanks in advance, Brian

Grania answered 25/8, 2010 at 14:51 Comment(2)
Why don't you have access to a listener? Can't you create your own? What GUI framework are you using?Mornay
Noel - seem my comment against Erick Robertson's post.Grania
L
5

The MouseEvent.getModifiers() method will return a bitmap of modifier keys that are pressed at the time the MouseEvent was generated. Or, you could use MouseEvent.isControlDown() to check specifically the CTRL key.

Lorin answered 25/8, 2010 at 15:6 Comment(3)
I agree that in an ideal world, a key listener would probably be best. however, in my opinion, there are some problems with this approach for my scenario: What do I attach the listener to? my application is pretty complex in terms of UI and is also customisable through plugins. I've looked at attaching a Listener to the event thread, but this ends up processing all key events & so may have performance implications elsewhere. likewise, the extensibility of the application means that I don't necessarily have a way to detect the start of the drag & so I can't selectively turn the listener onGrania
I've just been playing with a key listener and it turns out that key events don't get fired while a mouse button is held down (and I'm working with drag & drop here) and so that rules out a key listener. I guess I could look at a global mouse listener and check the state of the modifiers but this does seem like overkill for this problem.Grania
I updated my response - you can check the MouseEvent being generated every time the mouse is moved or dragged.Lorin
P
1

This is a possibly dirty way to go about it. But this allows you to 'record' key events and then query them.

//register this somewhere in the startup of your application
KeyboardFocusManager mgr = KeyboardFocusManager.getCurrentKeyboardFocusManager();
    mgr.addKeyEventDispatcher(KeyEventRecorder.getInstance());

//then can query events later
    KeyEvent keyEvt = KeyEventRecorder.getLastEvent();
    if( keyEvt != null && keyEvt.getKeyCode() == KeyEvent.VK_CONTROL && keyEvt.getID() == KeyEvent.KEY_PRESSED )
      //do something..

    private class KeyEventRecorder implements KeyEventDispatcher
    {
        private static KeyEvent lastEvent;
        private static KeyEventRecorder myInstance;

        private KeyEventRecorder()
        {
            super();
        }

        public static synchronized KeyEventRecorder getInstance()
        {
            if( myInstance == null )
                myInstance = new KeyEventRecorder();
            return myInstance;
        }

        /**
         *  retrieve the last KeyEvent dispatched to this KeyEventDispatcher
         */
        public static KeyEvent getLastEvent()
        {
            return lastEvent;
        }//method

        @Override
        public boolean dispatchKeyEvent(KeyEvent e)
        {
            lastEvent = e;
            //return false to let KeyboardFocusManager redistribute the event elsewhere
            return false;
        }//method
    }//class
Plagioclase answered 22/3, 2013 at 19:58 Comment(0)
M
0

Even if there was such a method, what do you want to do with it? Call it in an endless loop in the hope it returns true at some point? I think an event-based / listener-based mechanism suits much better in this case.

Monoatomic answered 25/8, 2010 at 14:56 Comment(1)
not an endless loop, no. simply called on demand during a certain operation (callback during drag & drop).Grania
P
0

I think you are going about this the wrong way. What you want to do is change the action when the drag is initiated, not when it is dropped. There are ways to change what the action is on initiation, including interrogating the user preferences in the "no modifiers" case. It's possible that changing the way the DropTargetDragEvent is called.

Penthea answered 25/8, 2010 at 15:20 Comment(1)
I agree - but I've not been able to work out how to set the "no modifiers" case in code - the javadocs (see link in my original post) indicate that copy takes priority over link. If you've got any suggestions on how to do this then it would be much appreciated.Grania

© 2022 - 2024 — McMap. All rights reserved.