Stop a event from bubbling in GWT - java

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

Related

Explain the KeyListener in Java

I am someone new to Java and working with the robot class. I would like to make an emergency stop function for my robot so when it does something wrong I can make the automation end. While robot so far has been easy the key listener escapes me, please explain in a "my first keylistener" style, thank you!
Here is what I have so far:
public static void keyboard(String input, HWND window) throws Exception {
System.out.println("Keyboard Typing:\n" + input);
//This is just to stop the error, but I don't know how
//to actually listen
KeyEvent e = null;
for (int i = 0; i < input.length(); i++) {;
keepFocus(window);
if(stopBot(e /*How to pass a key press*/) == true){
break;
}
char c = input.charAt(i);
keyboardHandler(c);
Thread.sleep(80);
}
}
public static boolean stopBot(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_END){
return true;
}
return false;
}
There is other code but this is all that is relevant to my problem
The easiest way I could think about implementing a key event is by making your current class extend a Key Listener class. Basically, you want your current class to be listening for keystrokes in the background. You'll start by adding the implementation to your class name:
public YourClassName implements KeyListener {
}
Now, your class is able to listen for key strokes in the background. You'll now need to add a listener in your code and then give it instructions on what to do when hit. You'll add the listener by invoking the following method:
this.addKeyListener()
You can also replace "this" with any other instantiated object capable of handling action events. Now, you just need to be able to instruct the program on what to do when the listener picks up a key stroke event. The key listener will evoke one method from the KeyListener class you are extending: keyPressed(KeyEvent e), keyRelease(KeyEvent e), or keyTyped(KeyEvent e). These are the functions that will then run whatever code you'd like when a key-event is picked up and passed through the function. You will need to override these methods like so:
#Override
public void keyReleased(KeyEvent e) {
//whatever you want to happen in the case of
this event, I assume stop your robot
}
So, as you can see, you don't need to worry about invoking your own KeyEvent, Java's addKeyListener will take care of this as long you've extended the class and given instructions on what to do for each event! Hope this helps!

Mouse click to boolean

Hello from novice java developer, I created a MouseListener and MouseAdapter in a thread to control mouse action for mouse pressed, released and drag action. Each action will do specific things but i could not assign each MouseEvent e from each action to a variable.
So, how can deal with this problem? I also wonder if the method parameter MouseEvent e is specific to each method?
Here is my code:
Thread thread = new Thread() {
public void run() {
addMouseListener(new MouseAdapter() {
//#override deleted because i want to use e as a different action.
public void mouseaction(MouseEvent e) {
/* In here i want to control MouseEvent e action
(drag, pressed and released) and do specific things in with e event
and if e changes state should be changed in code during while(true) */
}
}
}
You can get all this information from the mouseEvent by calling the method getModifiersEx(), for example:
int eventType = e.getModifiersEx();
if (eventType & MOUSE_DRAGGED > 0) {
// Code to be executed when mouse is dragged
}
if (eventType & MOUSE_PRESSED > 0) {
// Code to be executed when mouse button is pressed
}
...
Note that the eventType is a bit field where multiple bits can be activated simultaneously.
//#override deleted because i want to use e as a different action.
public void mouseaction(MouseEvent e)
You can't just make up method names. You need to implement the methods of the listener. You need to handle the mousePressed, mouseReleased methods separately. For the mouseDragged you need to implement the MouseMotionListener.
Read the section from the Swing tutorial on Implementing Listener. You can find sections on:
How to Implement a MouseListener
How to Implement a MouseMotionListener
which both contain working examples.
I'll address this concern:
I also wonder if the method parameter MouseEvent e is specific to each method?
Every time this method is invoked by Swing, a new Event is generated. Your #Override annotation makes no difference.
So when user clicks somewhere, a MouseEvent N°2556 is generated for it, and the method is invoked with that event as a parameter.
When user drags the mouse away, a MouseEvent N°2557 is generated, and the method is again invoked with this new event as a parameter.
More broadly: All those MouseEvents will always be different instances. They are immutable, as well.
This means if you want to persist some information for your game loop to see, you need to store the relevant conditions in a field somewhere. And you won't be able to access it from an anonymous class because you won't have a handle to it. Here is a quick and dirty example (shameless reuse of #FrankPuffer's code):
public class MyMouseAdapter extends MouseAdpater {
public boolean isMousePressed = false; // This info is persisted here
public void mouseaction(MouseEvent e) { // This is only triggered upon user input
int eventType = e.getModifiersEx();
if (eventType & MouseEvent.MOUSE_PRESSED) {
isMousePressed = true;
}
if (eventType & MouseEvent.MOUSE_RELEASED) {
isMousePressed = false;
}
}
}
public static void main(String[] argc){
// Before the game loop:
MyMouseAdapter myAdapter = new MyMouseAdapter();
jpanel.addMouseListener(myAdapter);
// In the game loop
while(true) {
if(myAdapter.isMousePressed) { // This info is available anytime now!
// Do something
}
}
}

How to wait for a mouse click

class GameFrameClass extends javax.swing.JFrame {
public void MyFunc()
{
UserButton.setText(Str);
UserButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
UserButtonActionPerformed(evt);
}
});
getContentPane().add(UserButton);
}
private void UserButtonActionPerformed(java.awt.event.ActionEvent evt) {
//print some stuff after mouse click
}
}
In someother class i define this function
void functionAdd()
{
GameFrameClass gfc = new GameFrameClass()
gfc.MyFunc()
System.out.println("PRINT THIS AFTER MOUSE CLICK")
}
If someone can look into this code. I want to wait on the mouse click . Is there a way i can print the line System.out.println("PRINT THIS AFTER MOUSE CLICK") after the mouse is being clicked . For now this happens immediately and i am not able to wait for the mouse click . Is there a way of doing it ? Apart from doing it inside the function UserButtonActionPerformed() . Please let me know .
This is a really "bad" way to do it...
private void UserButtonActionPerformed(java.awt.event.ActionEvent evt) {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
System.out.println("PRINT THIS AFTER MOUSE CLICK");
removeMouseListener(this);
}
});
}
A better way would be to have a flag in the actionPerformed method that would "enable" a mouse listener (which you added earlier). This listener would check the flag on each click and when set to true it would flip the flag (to false) and process the event...
It's hard to tell from the wording, but I assume he or she simply wants to execute code after the button is triggered (and not actually wait). For that, you need to add the code inside the method being invoked inside the actionlistener (in this case UserButtonActionPerformed).
So:
private void UserButtonActionPerformed(java.awt.event.ActionEvent evt) {
System.out.println(...);
}
Also, following the Java coding conventions will help people answering your questions in the future.
You can always wait in UserButtonActionPerformed by defining it in the same class. If that is the case then you should not have the problem you are facing
Events are managed on a different thread which is the event dispatching thread, they are not managed by the thread that is executing your code (which presumably is the main thread).
This means that you can attach listeners to GUI elements but the only thing you can do to "wait" for the click is to execute the code inside the actionPerformed callback.
There is no way to pause the execution since the addActionListener doesn't do anything to effectively catch the event, it just adds the listener. Theoretically you could lock the main thread waiting to be notified by the event dispatch one but that would just be bad design.

How do you get the current keyboard state globally? (i.e. what keys are currently depressed regardless of if the inquiring application has focus)

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);
}
}

Cancel a Keypress Event in GWT

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

Categories