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.
Related
I have a Java swing application with several panel and transitions between them (button, inputs ...).
What I want now is to set a timeout for my whole application (that will logout the user on my software), and bring back the user to another JPanel (I don't need help for that part).
After some research I have found something that seems to work (not fully implemented atm), I'm adding Key, MouseMotion and MouseWheel listener to ALL my swing elements and reloading my timer for any user action.
I wanted to know if there is any built-in function that can handle such a situation or a nicer way to do it. Thanks
I'm adding Key, MouseMotion and MouseWheel listener to ALL my swing elements
You can check out Application Inactivity which does this using an AWTEventListener so you don't need to do it for all your components.
You provide the listener with an Action to invoke after your period of inactivity.
I am looking for some ways to programmatically call onUserInteraction. Actually when I perform any click it is called, but if I programmatically call performClick() on any of the views it is not getting invoked, although the click is performed. I also tried by sending touch events through adb.
So, my question is can I programmatically invoke the onUserInteraction by doing some interactions inside the code.
I guess I have to do something that will make the OS think it is an actual user action.
actually I want to replay some events. So when one event happens I wait for the onUserInteraction callback to dispatch another event. Otherwise the views will not be inflated properly and the next view (the action to be performed) might not be yet available. Calling this.onUserInteraction() will not solve my problem as it will be executed in the same thread.
In my SWT based application, I have a Canvas-derived custom Widget, which is displaying a bunch of "items". The whole purpose of these items is for the user to drag them out of the widget. I had no trouble implementing a DragSource, DragDetectListener and all that stuff to make DND work. The problem I am trying to solve is that I want the drag to be detected much earlier, i.e. after a much shorter mouse drag distance, than the default platform behavior.
I know I can override dragDetect() of the Widget class. However, this only allows me to veto the super class implementation, not to notify that a drag already happened before the super class would think it has.
Basically, if I could generate the drag event myself, like if I could just use Widget.postEvent(SWT.DragDetect, eventWhichIAllocatedAndFilledOut) (which is package private), that would seem like my solution. I've looked at the code for drag detection in Widget, and it doesn't seem to be designed for this use-case. Is there a work around that let's me initiate drags anytime I want?
I have figured it out. It is possible to generate a custom event and distribute it to the DragDetect listener mechanism. The code below does the same as the internal implementation, but can be called at will from within the Widget implementation, for example from a MouseMoveListener's mouseMove(MouseEvent e) hook:
Event event = new Event();
event.type = SWT.DragDetect;
event.display = getDisplay();
event.widget = this;
event.button = e.button;
event.stateMask = e.stateMask;
event.time = e.time;
event.x = e.x;
event.y = e.y;
notifyListeners(SWT.DragDetect, event);
It is noteworthy that the built-in drag detection has to be disabled for this to work as intended. The default implementation is exposed via the dragDetect(MouseEvent e) method that can be called from a mouseDown() handler (as explained in the documentation for dragDetect()). It works by busy looping in the event thread until the drag is detected. It simply consumes mouse move events from the native event queue on the GTK backend at least. When a DragDetectListener is registered with the Widget, this will automatically be done, so unless one disables the mechanism via setDragDetect(false), a custom drag detection would only run after the built-in detection which imposes the delay because it is blocking the event thread, besides detecting the drag a second time, of course.
I have a JPanel with a set of items (for example combo boxes and text fields). Some action listeners are implemented on those items to register user updates.
If the user selects a value in a JComboBox (for example), the action listener captures the event. The corresponding underlying bean method is called and the panel is refreshed. Changing can have an impact on other fields displayed in the pane.
The problem is that when the panel is refreshed, all listeners are triggered, and they call for a refresh themselves. This leads to an infinite loop.
How can I avoid this? I can't get rid of the listeners, because I need to capture user updates, but I don't want these to fire when I am only refreshing the panel content.
One option is to have a central boolean value or some indicator that each listener can check to prevent the chaining of events.
Another option is to not refresh the field if the value does not change. That way each component is updated at most once per refresh.
I can't get rid of the listeners, because I need to capture user updates, but I don't want these to fire when I am only refreshing the pane content
Then remove the listeners, refresh the pane content and then restore the listeners. This way the listeners only fire when a user change is made.
I think that if your problem is in combobox it just points to a bug. Really, if user changes the value of the combobox, that somehow triggers refresh of the pane the value of the combo box should not be changed second time! So if it is onValueChanged() (or something like this) it should not be called at all when pane is being refreshed.
But if for some reason it happens you can verify whether the old and new values are the same and exit the listener.
If this still does not help I'd suggest you some non-standard solution: try to investigate the stack trace into the listener. Can you identify whether the listener was called as a direct reaction to user's action or after the pane refresh? In this case you can create utility method and put it in the beginning of all relevant listeners.
My applications also suffered from this problem, and solution with the flag, that I should check in every listener and enable/disable in code, feels not very good for me. I always forgot to set this flag to true/false in necessary places.
That is why I decide to implement another solution.
I just subclass all default swing components that I am using often, and implemented custom ValueChanged event that I fire after mouse/keyboard/clipboard/etc events. Now I am always know, that if ValueChanged event is fired, it means, that value was issued by user, not by code. Event handling in this way much more cleaner. This solution solves my problem.
Any idea how I can fire the blur even just after the focus event, such that it doesn't occur "loosly coupled" (the actions are send one-by-one to the selenium server).
Let me explain:
In Selenium RC you fire the blur and focus through fireEvent(locator, "blur") and fireEvent(locator, "focus"). However, after the blur event is send to the browser the focus event doesn't directly follow the blur event in the javascript command stack. This is a problem is in the following case: detecting the blur of a group of widgets, like a group of textboxes.
What I do: all text boxes share the same listener and when a blur occurs I simple run an additional command that checks if a focus event was captured by one of the textboxes, if so, you ignore the blur. This additional command that I run in javascript is automatically executed after all waiting commands are run, in this case, a focus command is one of these waiting commands.
Back to Selenium RC: after the blur event is fired by the Selenium server, it waits for the next command, in this case the focus event and will fire it. However, as you can understand, in the mean time, the addiontal command already has been fired and no new focus event has been detected. As such, a group-blur is detected and handled, in this case however the blur is incorrectly handled as the focus isn't fired directly after the blur, such as a browser would do....
I hope you understand my problem as it's a bit hard to explain.
Any idea's on how to solve this? so I can test the correct behavior? (no my validation takes place too early as a group-blur isn't correctly captured)
I think the way to solve this: send a piece of javascript to the Selenium server that will be evaluated and will fire both events after eachother. Or not?... And you how would I do this?
I belive you are looking for:
selenium.getEval("[my JavaScript here]");
You can send a javascript snippet of your choice to get evaluated by the browser, this should enable you to chain a focus and blur into one command.