I'm trying to make an application which uses the tab key to do something. I've implemented the KeyListener interface and I'm able to program all the other keys. But when I press the Tab key and in the keyPressed() method I put this:
System.out.println(ke.getKeyCode());
I get no output. The 'Tab' key is the only which gives no output. All the other keys have their relative keycode printed. Why is this?
Use setFocusTraversalKeysEnabled(false) on the control that you listen on (JTextField?).
EDIT:
The Tab key is usually used to switch input focus between UI controls, for easier keyboard input without the need for a mouse. When a UI control receives a key press event it first tries to "consume" it on its own, and if the key is a special key (Tab, Shift-Tab, etc.) then the control consumes the event and doesn't propagate it further. On the other hand, if the key is not a "special" key it propagates the event to attached listeners (if any). Calling setFocusTraversalKeysEnabled(false) disables this built-in behavior for the control (but in this case just for FocusTraversal, i.e. Tab and Shift+Tab), so that event gets propagated to listeners.
Related
I am doing a project in JavaFX, using Java 8 and Gluon scenebuilder. I want to detect when backspace is pressed inside a TextField. This is the code I am using:
public void keyPressed(KeyEvent kEvent) {
if (kEvent.getCode() == KeyCode.BACK_SPACE) {
System.out.println("Backspace pressed");
}
This code is inside the controller file, called FXMLDocumentController, which controls the GUI xml file FXMLDocument. You can see from the image below the function is called whenever a key is typed inside TextField. This works with all the letters/numbers, but not with backspace.
Gluon scene builder settings
Theoretically it should work, but it doesn't.
How can I manage typing of the backspace button?
Edit:
Notice that putting this exact function on the root of the elements, on the "Window itself" (which is the AnchorPane) works. The problem is with reading the pressing of the backspace inside the TextField. You can see in the image below where I've put the function:
On the window backspace's detecting works
You should use your keyPressed method in either on key pressed or on key released.
In the Docs, it states that:
No key typed events are generated for keys that don't generate Unicode
characters (e.g., action keys, modifier keys, etc.).
Backspace is consider an Action Key.
In the screenshot of your SceneBuilder I can see you are referencing the keyPressed(KeyEvent kEvent) controller method with On Key Typed not On Key Pressed.
For events of KeyEvent.KEY_TYPED the value of getCode() is always KeyCode.UNDEFINED.
Edit: I came back to this answer and reread your question. I want to clarify something but what I said above is still correct.
In your edit you mention the "exact" same setup works with the AnchorPane but when looking at your screenshot there are some differences. For your AnchorPane you have the controller method referenced for all three types: On Key Pressed, On Key Released, and On Key Typed.
This means that the method should be called up to 3 times for each key stroke (when the events reach the AnchorPane). Once when pressed, once for typed (if the key is capable of sending typed events - see the answer by Sedrick for clarification), and then once for released. Because of this, the method will work for the pressed and released events, but it won't work for the typed events.
In other words, the reason your code works for the AnchorPane but not the TextField is because you configured it correctly for the AnchorPane but not the TextField.
I'm having trouble understanding the difference between the 2 methods in the SWT SelectionListener. The javadoc is as follows:
void
org.eclipse.swt.events.SelectionListener.widgetSelected(SelectionEvent
e)
Sent when selection occurs in the control.
For example, selection occurs in a List when the user selects an item
or items with the keyboard or mouse. On some platforms, the event
occurs when a mouse button or key is pressed. On others, it happens
when the mouse or key is released. The exact key or mouse gesture that
causes this event is platform specific.
void
org.eclipse.swt.events.SelectionListener.widgetDefaultSelected(SelectionEvent
e)
Sent when default selection occurs in the control.
For example, on some platforms default selection occurs in a List when
the user double-clicks an item or types return in a Text. On some
platforms, the event occurs when a mouse button or key is pressed. On
others, it happens when the mouse or key is released. The exact key or
mouse gesture that causes this event is platform specific.
It sounds to me like widgetSelected() is called when the user selects a widget in any way. The widgetDefaultSelected() is called when the user is finished interacting with the widget. For a Text widget, that would be pressing Enter; for a List, that would be double clicking on a list item; and for a Date, that would be pressing Enter.
Is this understanding correct?
Your general understanding is correct, though the term 'finished' might not be 100% accurate in all situations.
Widgets that send (default) selection events document the particular details in the JavaDoc of their respective addSelectionListener method. There you can read if and when widgetSelected and/or widgetDefaultSelected is sent.
If you look into the Link::addSelectionListener JavaDoc for example, you will see that widgetDefaultSelected() is never called.
Is it possible to have my android application start a method from pressing of the convenience key when the application in focus?
On my phone the convenience key is a button located on the right hand side of the phone. I would like to be able to know if the user presses any of the buttons on the phone, even the volume would work.
You are welcome to override onKeyDown() on your Activity and watch for a KeyEvent of interest. Note that not every key in the KeyEvent JavaDocs is accessible this way (e.g., power). Also note that it is possible that some specific View that is aware of these keys might consume the event first, though that is relatively unlikely for anything that matches your description of a "convenience key".
GXT 3.x only.
It is becoming apparent to me that Sencha had deliberately designed FileUploadField to shunt off all key press events from ever being detected.
I tried to intercept onBrowserEvent(Event) and could not detect any key press events which I would have generated by keypresses while having focus on the FileUploadField component.
Where is the key-press event shunt?
I could not find any keypress handler insertion methods.
I wish to allow triggering the file upload by either press on the space-bar or enter key.
Short of rewriting a whole new component from scratch, could someone advise me what I could do to achieve my goal of a keyboard activated file upload?
onBrowserEvent won't recieve any events unless you sink them - did you make sure to call sinkEvents? How are you adding handlers? If you use addDomHandler, it will sink them for you, but addHandler either assumes that they are not dom events, or that you already called sinkEvents. Without sinking an event, the browser doesn't know to pass that event on to a GWT widget. If all events were sunk automatically, then every time you moved the mouse across the page you would see a firestorm of events as mousemove fired for every widget you passed, and all of its parents.
If you override onBrowserEvent, then you are building the method that describes how to handle the actual event that comes from the browser - that is where the com.google.gwt.user.client.DOM class wires into the Widget to give it events. Short of making that method final, there is no way to prevent you, the widget user, from getting those events as long as the browser is generating them and passing them through the event listener.
Even if onBrowserEvent has been overridden and made final, you can still get access to many events by creating a NativePreviewHandler and checking where the event is occurring. This gets you in to the event before it even goes to the widget itself - there you can call NativePreviewEvent.cancel() to prevent it from happening on the widget itself, or you can handle it early in the handler.
i want to have some composite-wide keyboard-shortcuts. The composites in question are in a tab-folder. I have a little function, which traverses all children of my composite and adds a KeyboardAdapter to every one of them.
The problem I have is that, when I open on of the tabs pressed keys aren't registered. I first have set the focus on some selectable widget in the tab, then it works. When i switch to another tab and then back, the focus is still kind of there (a grey selection instead of a blue one in a table for example), but it, again, doesn't work, until i click somewhere.
How can I do this? I thought about adding a filter to my display, but i only want events in a certain composite (and everything in there).
Thank you
Key events are delivered to the component that has keyboard focus. Composites do not get the keyboard focus, it is usually one of their child components that gets it and then they start receiving the key events (in case they are not used by children). Having the key listener on the parent Shell may possibly work.