I have a Swing application and I need to make a specific action if an alphanumeric key is pressed during a mouse drag action.
I successfuly managed the drag action but I can't get the key pressed.
It seems that only the modifiers (alt, ctrl, shift) are available in a mouse event?
Is there a a way to know if for example the W key is pressed in a java.awt.event.MouseAdapter method (without adding a keyListener) ?
Is there a a way to know if for example the W key is pressed in a java.awt.event.MouseAdapter method (without adding a keyListener) ?
No, you need to use a KeyListener.
And you also need to reverse your logic. That is when you handle the KeyEvent you need to check if the mouse is also being used by looking at the "modifiers" of the KeyEvent. Read the API for more information on the getModifiersEx() method.
Related
I need to create a program which fire event on every key press(like key logger). I couldn't able to get key value. This program will run behind and on every key press it fire event. I didn't find any thing related to this on net.
It is very strange that you cannot find anything.
You should user KeyListener to log key events. If only one event (e.g. keyUP, keyDown or keyPress) is relevant use KeyAdapter instead.
The problem is that key listener can be attached to any java screen element and catches events dispatched to this element only. For example you can create Frame and add key listener to it and capture all key events withing this frame.
You cannot capture key events outside the java application.
If you still want to do this you can use the following work-around. Create transparent window and add listener to it. The listener should catch events, log them and then imitate them on the same location on screen using java.awt.Robot.
This reference will help you to create transparent window: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html
Other way is to use JNI/JNA directly or indirectly. For example xdotools can help you.
I've got a KeyboardFocusManager with overridden dispatchKeyEvent() method to handle navigation for arrow key and enter. I need to handle key events for as long as the key is pressed. Unfortunately, holding down enter results in KEY_TYPED events which do not contain the key location. Is there a way to find out which enter is currently being pressed? Or can I suppress KEY_TYPED events for enter in favour of KEY_PRESSED events?
edit:
I can't tell you the reason why it's done with a KeyboardFocusManager instead of KeyListeners but I'm sure there were reasons it was done this way. As of now, it is not possible anymore to change this. The problem is, that for our system(an old terminal emulator), the left enter key is a navigational key. Pressing enter moves the focus to the next textfield after the current line. The right enter key is a command key that sends the user input to the server.
Using the KeyEventDemo found in How to Write a Key Listener, I am unable to reproduce the effect you describe for either KEY_PRESSED or KEY_RELEASED. Of course, "KEY_TYPED events do not have a keyLocation."
It's not clear why you are using a Focus Listener, as many components already bind certain keys to a defined Action. The example binds the arrow keys, which respond to auto-repeat events regulated by the host's preferences.
I have menu items with an accelerators. I would like to detect when a menu item was clicked as opposed to executed using accelerator. Is this possible?
Thanks,
Alexander.
While you can listen for MouseEVents and Actions, you can also just inspect the modifiers of the ActionEvent and see if a key was involved in the event or not. That way, you only have one listener to deal with...
a mouse click will fire off a MouseEvent and an Action. An accelerator will only fire off an action.
You can compare the key-info in the ActionEvent with the Action#ACCELERATOR_KEY key-value pair, which should be able to distinguish between a user clicking while holding a random/modifier key, and the actual accelerator key combination
I tried to make it so that,if I pressed the right/left key, the sprite/Mario would face right/left. If I pressed the right key, he would face right. But for some reason, When I pressed the left key, he won't face left.
Source Code: First ,Second
Images
"To fire keyboard events, a component must have the keyboard focus."—How to Write a Key Listener
Don't use a KeyListener. Instead use Key Bindings which are more flexible and are used by all Swing components.
I've a problem with setAccelerator(). Right now, I have the code that works for Ctrl+X for DELETE operation. I want to set the accelerator to Shift+Delete as well for same JMenuItem.
My code as follows:
JMenuItem item = new JMenuItem(menuText);
item.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_X, KeyEvent.CTRL_MASK));
item.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_DELETE, KeyEvent.SHIFT_MASK));
but this is working only for Shift+Delete operation. Seems it is overriding the Ctrl+X operation. Can we make both these keystrokes work at the same time?
Please guide.
Yes it can be done. Behind the scenes the setAccelerator() is just creating a Key Binding, however as you noticed the second binding replaces the first.
So, you need to create an Action (not an ActionListener) to add the to the menu item. Read the section from the Swing tutorial on How to Use Actions for more information. Now that you have created the Action, you can share the Action with another KeyStroke by manually creating a Key Binding. You can read the section from the Swing tutorial on How to Use Key Bindings for a detailed explanation. Or you can read my blog on Key Bindings which give some simple code examples.
This second binding will not show up on the menu item itself.
From: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/AWTEvent.html
The masks are also used to specify to which types of events an AWTEventListener should listen.
So you can combine the mask for two keys, but not the KeyEvents.
item.setAccelerator(
KeyStroke.getKeyStroke(
KeyEvent.VK_X, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));
A workaround solution would be to catch the KeyEvent in the middle (after your component fired it, but before your listeners will act on it) and check, whether its one of the two combinations. Then fire one event, on which you programmatically agree to represent the action you wanted.
The second call indeed overrides the accelerator. If the method starts with set, there will be only one. If the method starts with add, you can have more than one (for example for a number of listeners).
If you want multiple keystrokes to do the same, I think you should add a keyListener to the top frame (or panel, dialog, ...) which invokes the action listeners added to the menuItem.