I want to cancel a keypress event for a long textbox so that the character newly pressed by the user is not entered in the textbox
longBox_1.addKeyPressHandler(new KeyPressHandler(){
#Override
public void onKeyPress(KeyPressEvent event) {
String Valid="1234567890";
if (!Valid.contains(String.valueOf(event.getCharCode()))) {
// the code to cancel the event to be placed here
}
}
});
If your longBox_1 is a private member of your class, or a final var, the code to cancel the event is :
longBox_1.cancelKey();
Otherwise you can cast the source of the event, if you are sure it correspond to the TextBox :
((TextBox)event.getSource()).cancelKey();
Here is the doc for cancelKey :
If a keyboard event is currently being
handled on this text box, calling this
method will suppress it. This allows
listeners to easily filter keyboard
input
Related
I'm new to Java programming, so this question may sound stupid to many here. I'm trying to get myself comfortable with JavaFX Event handling mechanism.
I'm developing a GUI where I want a button to perform the same function when it's clicked and also when the Enter key is pressed.
Can I do the following?
public class ButtonHandler implements EventHandler<ActionEvent>
{
somefunction();
}
And then use it for both KeyEvent & MouseEvent
button.setOnMouseClicked(new ButtonHandler);
button.setOnKeyPressed(new ButtonHandler);
As long as you don't need any information from the specific event (such as coordinates of the mouse, or the key that was pressed), you can do
EventHandler<Event> handler = event -> {
// handler code here...
};
and then
button.addEventHandler(MouseEvent.MOUSE_CLICKED, handler);
button.addEventHandler(KeyEvent.KEY_PRESSED, handler);
Of course, you can also just delegate the actual work to a regular method:
button.setOnMouseClicked(e -> {
doHandle();
});
button.setOnKeyPressed(e -> {
doHandle();
});
// ...
private void doHandle() {
// handle event here...
}
I have a trouble with handling key presses. My plugin must log every keyboard actions of user. So, I created handler win methods:
private Display display;
public ActionsRecorder() {
display = Display.getCurrent();
if (display == null) {
display = Display.getDefault();
}
}
public void handleKeyPress() throws ExecutionException {
display.addFilter(SWT.KeyDown, this);
}
#Override
public void handleEvent(Event event) {
System.out.println(event.keyCode);
}
So, if I press Ctrl+B, both presses are processed correctly. But if I press hot keys for instance Ctrl+A, only the Ctrl button is processed.
I think that another default handler catches event and assign event.doit value to false.
How to fix it? Are there another ways to create global (in ide window) logger?
UPD: Baz, thanks for help. But my problem is that eclipse (luna) doesn't call .handleEvent(e) method, if pressed hotkey.
Where you add listener in plugin lifecycle?
I'm writing a screen capture utility, and I'd like to be able to store the current state of the keyboard and mouse whenever a screenshot is taken.
Doing this for the mouse is simple, since using the PointerInfo class in a manner described in this related question gives you the screen coordinates for the current mouse location and the click information if desired. However, I haven't been able to find an analog to this class for the keyboard; all the keyboard related classes appear to be focus specific.
So, is there a way to get the current keyboard state in Java?
P.S. Remember that I'm looking for a function to call to retrieve the information regarding what keys are depressed, not a listener for such depression events.
Something you can do is implement the KeyListener interface and give states to all the keys you're interested in.
If you're interested in checking if the arrow keys are depressed upon a screenshot, for instance, you can implement this KeyListener interface and override keyPressed() and keyReleased() methods and set the state for those keys you are interested in to keyPressed or keyReleased. Depending on the event. That way, when the screenshot occurs, you can just read the state of those keys
If you need this solution to be global, regardless of application focus, you could write a small hook in C that you can integrate with Java Native Interface to listen for key events. Java doesn't let you listen to key events without you attaching the listener to a component and that component having focus. Have a look at JNativeHook.
If you just need it when your application has focus but on every component you could inelegantly attach the listener to all your components or you could write your own custom KeyEventDispatcher and register it on the KeyBoardFocusManager. That way, as long as your application has focus, regardless of component that has specific focus, you could catch all keyboard events. See:
public class YourFrame extends JFrame {
public YourFrame() {
// Finish all your layout and add your components
//
// Get the KeyboardFocusManager and register your custom dispatcher
KeyboardFocusManager m = KeyboardFocusManager.getCurrentKeyboardFocusManager();
m.addKeyEventDispatcher(new YourDispatcher());
}
private class YourDispatcher implements KeyEventDispatcher {
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_TYPED) {
// Do something to change the state of the key
} else if (e.getID() == KeyEvent.KEY_PRESSED) {
// Do something else
}
return false;
}
}
public static void main(String[] args) {
YourFrame yF = new YourFrame();
yF.pack();
yF.setVisible(true);
}
}
I notice that the ModifyListener will be triggered regardless the action is caused by user or system itself, for instance,
Text t = new Text(shell, SWT.BORDER);
t.addModifyListener(new TModifyListener());
...............................................
private class TModifyListener implements ModifyListener
{
#Override
public void modifyText(ModifyEvent event)
{
Text text = (Text) event.widget;
t.setText(process(text.getText()));
}
}
This will cause infinite loop and crash the program. Do you guys have any idea how to disable the event listening if the event is generated by system, and enable it if the event is caused by user?
Couldn't you just set a ThreadLocal in your listener and check it when it's re-entered?
edit: In fact it wouldn't even need to be a ThreadLocal, since SWT is single-threaded. Just set a boolean field on the listener.
private class TModifyListener implements ModifyListener {
private boolean _setting;
#Override
public void modifyText(ModifyEvent event)
{
if(!_setting) {
_setting = true;
try {
Text text = (Text) event.widget;
t.setText(process(text.getText()));
} finally {
_setting = false;
}
}
}
}
I don't know swt but...
If process is idempotent then perhaps you could setText only if it is different from getText
Another option is to set some property on the widget in the first callback which you can query, unset and not call setText in the second callback.
I have the following snippet of code, changeTextArea is a TextArea object.
changeTextArea.addKeyboardListener(new KeyboardListenerAdapter()
public void onKeyPress( Widget sender, char keyCode, int modifier){
//do something
//I WISH TO STOP THE EVENT THAT MAPS TO THIS KEYPRESS FROM BUBBLING ANY FURTHER
}
}
How would I stop the Event that is causing this method to be called from bubbling up from changeTextArea into the Panels/Widgets/Composites/Whatever that contain changeTextArea. Put succinctly, how do I stop it from bubbling any further. Any help would be appreciated (especially code samples).
As far as I know you can't do it via a keyboard listener, but it is possible by adding an event preview using the DOM class:
DOM.addEventPreview(EventPreview preview)
Then when you get the event:
onEventPreview(Event event)
You should return false, to say you want to cancel the event. The Event object also supports this method:
public final void cancelBubble(boolean cancel)
Cancels bubbling for the given event. This will stop the event from being propagated to parent elements.
You can find more details here:
http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/index.html?overview-summary.html
You can definitely use the Event's cancelBubble() and preventDefault() methods from within any code that has access to the Event. There's no need to have an event preview...
You can call the sender's cancelKey() event. Here's an example that will only allow numbers to be inputted, all other keys get rejected.
private class RowColChangeHandler implements KeyPressHandler
{
public void onKeyPress(KeyPressEvent event) {
char keyCode = event.getCharCode();
if(keyCode <48 || keyCode >57)
{
((TextArea)event.getSource()).cancelKey();
}
}
}
you could reach it when possible by doing
event.doit = false