OnLoad Event of GWT Widget like TextBox, TextArea - events

I want to catch the onLoad Event of TextBox. But I am not finding any handler through which I can call it. GWT provides LoadHandler for the same purpose. But I don't know how should I instantiate the Load Event from TextBox.
Any help would be appreciable!!!

TextBox extends ValueBoxBase which has a protected method called onLoad().
All you have to do is the following
public class MyTextBox extends TextBox
{
#Override
protected void onLoad() {
//Do your stuff
}
}

It seems you are looking for addAttachHandler() .
If you are designing an custom textbox implement the interface HasAttachHandlers .

textBox.addAttachHandler(new Handler() {
#Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()){
doMyOnLoadMethod();
}
}
});

Related

Apache Wicket: React on Ajax Request Before Model is Updated

I have a number of Wicket components on a page that use a PropertyModel to reflect properties of some beans. Using AjaxFormComponentUpdatingBehaviors, these components are automatically updated via Ajax when the user changes them.
When properties are changed, the beans I want to edit with my components fire PropertyChangeEvents that should trigger re-renders of certain components that listen to these events (implementing PropertyChangeListener):
Example:
User edits a TextField with a PropertyModel and an AjaxFormComponentUpdatingBehavior
An AJAX request is sent
Wicket dispatches the request to the AjaxFormComponentUpdatingBehavior
The behavior's onEvent updates the PropertyModel (unfortunately, this method is final)
The PropertyModel calls the backing bean's property setter
The backing bean fires and PropertyChangeEvent
Now I want all components listening for changes of the same backing bean to be notified
The behavior calls the abstract onUpdate, but now it's to late, the property change events are already handled.
Since my beans are not serializable, I cannot register the components permanently as event listeners. I either need to register proxy objects that somehow retrieve the component to notify, or register my components temporarily for the scope of the AJAX request.
What I would like to do is to hook into Wickets request cycle after the target page has been loaded but before the Ajax behavior updates the model, that would lead to the PropertyChangeEvent. Here I can register every component as a event listener on their backing beans (addPropertyChangeListener) so that they are notified if they need to be updated.
Then, in onEvent, each component can take measures to update itself using the AjaxRequestTarget if they received a PropertyChangeEvent before.
Finally, in onDetach, the components can unregister from their beans (removePropertyChangeListener).
Unfortunately, I found no built-in way to get a notification "on Ajax request". In my Ajax behavior's onUpdate methods, the model has already been updated and it is too late to register change listeners. I could implement my own behavior, but with the different component options (text fields, choice lists, etc.), this is quite an effort.
Did I miss something?
I don't quite understand exactly what you mean by "components registering as event listeners". Are you talking about registering IRequestCycleListeners?
Either way, perhaps Wicket's inter-component events can help you here. Every component implements the following interface:
public interface IEventSink
{
/**
* Called when an event is sent to this sink
*
* #param event
*/
void onEvent(IEvent<?> event);
}
You could subclass AjaxFormComponentUpdatingBehavior to fire an event after a model is updated like so:
public class AjaxUpdateEvent {
private final AjaxRequestTarget target;
public AjaxUpdateEvent(AjaxRequestTarget target) {
this.target = target;
}
public AjaxRequestTarget getAjaxRequestTarget() {
return target;
}
}
public class BeanModifiedEvent extends AjaxUpdateEvent {
private final Bean bean;
public BeanModifiedEvent(AjaxRequestTarget target, Bean theBean) {
super(target);
}
public Bean getBean() {
return bean;
}
}
public class CustomUpdatingBehavior extends AjaxFormComponentUpdatingBehavior {
protected abstract void onUpdate(AjaxRequestTarget target) {
Bean bean = getFormComponent().getModelObject();
getComponent().send(getComponent().getPage(), Broadcast.BREADTH, new BeanModifiedEvent(target, bean));
}
}
You can then catch the event in the required components and add them to the ajax request:
public class UserDetailsPanel extends Panel {
.....
#Override
public void onEvent(IEvent event) {
if(event.getPayload() instanceof BeanModifiedEvent) {
// if(whatever) to control whether to add or not
AjaxRequestTarget target = ((BeanModifiedEvent) event.getPayload()).getAjaxRequestTarget();
target.add(...);
}
}
Event doc:
17.2, "Wicket events infrastructure" section
18.3, "Built-in AJAX behaviors" section
You can override #getUpdateModel() to return false, then in #onUpdate() do whatever you want before calling getFormComponent().updateModel().
You could be overriding onModelChanging of each component you are using and firing your PropertyChangeEvent there. According to the documentation onModelChanging is called before
the model is changed.
#Override
protected void onModelChanging() {
super.onModelChanging();
oldModelObject = yourComponent.getModelObject();
//fire PropertyChangeEvent
}
This is what I came up with in the end.
I subclassed IContextProvider<AjaxRequestTarget, Page> to create a custom provider for AjaxRequestTarget objects. When an AjaxRequestTarget is requested, I broadcast it to the component tree using Wicket's event mechanism.
public class BroadcastingAjaxRequestTargetProvider implements IContextProvider<AjaxRequestTarget, Page> {
private final IContextProvider<AjaxRequestTarget, Page> parent;
public BroadcastingAjaxRequestTargetProvider(IContextProvider<AjaxRequestTarget, Page> parent) {
this.parent = parent;
}
#Override
public AjaxRequestTarget get(Page page) {
AjaxRequestTarget target = parent.get(page);
page.send(page, Broadcast.BREADTH, new AjaxRequestBegin(target));
return target;
}
}
The class AjaxRequestBegin is just a small payload object encapsulating the AjaxRequestTarget.
I register this provider in my Wicket application's init() method:
setAjaxRequestTargetProvider(new BroadcastingAjaxRequestTargetProvider(getAjaxRequestTargetProvider()));
Now each component gets notified when an AJAX request is handled, before Wicket dispatches it to a component or behavior. A component can override onEvent to register a PropertyChangeListener for the request:
public void onEvent(IEvent<?> event) {
final Object payload = event.getPayload();
if (payload instanceof AjaxRequestBegin) {
final AjaxRequestTarget target = ((AjaxRequestBegin) payload).getTarget()
AjaxPropertyChangeListener listener = new AjaxPropertyChangeListener(target);
target.addListener(listener);
getBean().addPropertyChangeListener(listener);
}
}
private class AjaxPropertyChangeListener implements PropertyChangeListener, AjaxRequestTarget.IListener {
private final AjaxRequestTarget target;
public AjaxPropertyChangeListener(AjaxRequestTarget target) {
this.target = target;
}
#Override
public void propertyChange(PropertyChangeEvent event) {
target.add(MyComponent.this);
}
#Override
public void onBeforeRespond(Map<String, Component> map, AjaxRequestTarget target) {
}
#Override
public void onAfterRespond(Map<String, Component> map, IJavaScriptResponse response) {
getBean().removePropertyChangeListener(this);
}
}
Note that AjaxPropertyChangeListener also implements AjaxRequestTarget.IListener to unregister itself after the AJAX request has been completed.

GwtEvent does not get dispatched

I have an application that uses EventBus for dispatching Application wide events. For some reason if I call one event and then try to register handler immediately before firing the second event it does not get dispatched. Is there any other way to dynamically register handlers on event ? Please see the code below:
MyEntry.java
package com.example.eventbus.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
public class MyEntry
implements EntryPoint {
SimpleEventBus bus;
#Override
public void onModuleLoad() {
bus = new SimpleEventBus();
fireEvent1();
}
private void fireEvent1(){
bus.addHandler(MyEvent1.TYPE,new MyEvent1.Handler() {
#Override
public void onEvent1(MyEvent1 event) {
RootPanel.get().add(new Label("Event1"));
fireEvent2();
}
});
bus.fireEvent(new MyEvent1());
}
private void fireEvent2(){
bus.addHandler(MyEvent2.TYPE,new MyEvent2.Handler() {
#Override
public void onEvent2(MyEvent2 event) {
RootPanel.get().add(new Label("Event2")); //!!!!!This line is not being called
}
});
bus.fireEvent(new MyEvent2());
}
}
MyEvent1.java
package com.example.eventbus.client;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
public class MyEvent1 extends GwtEvent<MyEvent1.Handler>{
public static Type<MyEvent1.Handler> TYPE=new Type<MyEvent1.Handler>();
#Override
public com.google.gwt.event.shared.GwtEvent.Type<Handler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(Handler handler) {
System.out.println("dispatch Event1");
handler.onEvent1(this);
}
public interface Handler extends EventHandler{
public void onEvent1(MyEvent1 event);
}
}
MyEvent2.java
package com.example.eventbus.client;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
public class MyEvent2 extends GwtEvent<MyEvent2.Handler>{
public static Type<MyEvent2.Handler> TYPE=new Type<MyEvent2.Handler>();
#Override
public com.google.gwt.event.shared.GwtEvent.Type<Handler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(Handler handler) {
System.out.println("dispatch Event2"); //!!!! This line is never called
handler.onEvent2(this);
}
public interface Handler extends EventHandler{
public void onEvent2(MyEvent2 event);
}
}
The issue is that while an event bus is firing events, it queues up any added or removed handler, and deals with them when it is finished. The idea is that if you only start listening to something while another event is still going off, then you are not interested for this round of events, but for the next round. The same thing happens when removing a handler - you will still hear about events that are still in the process of happening, but after the event bus is finished firing, it will deal with removal.
Try changing your code to wire up both handlers before firing anything, then try firing one event to the other.
Let me suggest to take a try to a new feature in gwtquery called 'custom events'.
We have introduced the new events mechanism during the recent GWT.create conferences, take a look to this slide (use arrows to move between slides).
You can attach custom events to any element in the DOM tree, widgets, and the window element.
Then you can trigger the event from any point in your code and every handler with this custom event name will be executed.
The main goal of the gQuery approach apart from being simpler, is that it performs significantly better than gwt eventbus, since the native browser selects in a low-level way which handlers to execute instead of using javascript to loop over a list, and execute handlers sequentially.
You might want to check out GWTP #ProxyEvent:
So when should you use #ProxyEvent? Basically, you use it every time that an event should have the ability to “wake up” your presenter. That is, whenever the presenter should be notified of an event even before it is first instantiated.

Using Events From A Class

I am trying to get a function to be called everytime an event occurs. In the KinectRegion class there is an event called HandPointerGrip: http://msdn.microsoft.com/en-us/library/microsoft.kinect.toolkit.controls.kinectregion.handpointergrip.aspx.
I see that it has declared the event and it seems to me that the event has already been set to be invoked(HandPointerEventArgs)? How do I attach a function to this event?
public Menu()
{
KinectRegion.HandPointerGripEvent+=Hand_Gripped; // why doesn't this work? :(
}
private void Hand_Gripped(object sender, HandPointerEvnetArgs e)
{
MessageBox.Show("I work!"); // I wish this would work
}
Been working hard on this problem and here is something I think will work. Afraid to test it. Learning a lot about routed events, delegates, and events.
namespace ...
{
public delegate void HandPointerEventHandler(object sender, HandPointerEventArgs e);
public partial class thePage : Page
{
public event HandPointerEventHandler HandGripped
{
add {this.AddHandler(KinectRegion.HandPointerGripEvent,value);}
remove {this.RemoveHandler(KinectRegion.HandPointerGripEvent,vlaue);}
}
public thePage()
{
InitializeComponent();
this.HandGripped += new HandPointerEventHandler(OnHandGripped);
}
protected virtual void OnHandGripped(object sender, HandPointerEventArgs e)
{
MessageBox.Show("hello"); //hopefully
}
}
}
The first block of code should work fine. My guess is that the HandPointerGripEvent is hooked up ok, it just never fires.
How are you setting up your KinectRegion?
Are you updating the interration library each frame?
Perhaps this helps?
Kinect SDK 1.7: Mapping Joint/Cursor Coordinates to screen Resolution
KinectRegion.AddHandPointerGripHandler(this.Button1, this.Button1_Click);
Here Button1 is:
< k:KinectTileButton x:Name="Button1" Height="150" Width="150" Content="Click"/ >
The namespaces:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:k="http://schemas.microsoft.com/kinect/2013"
Button1_Click is the method itself, for example:
private void Button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("YOU GOT ME !!!");
}
If you want to add a grip handler for another interface object, you just do:
KinectRegion.AddHandPointerGripHandler(< object name >, < method name >);
And s.o.

Assert that a mocked (MOQ thus DynamicProxy) event has no handlers attached

This is quite straight forward(ish) to do is the event is 'real' as in now created by DynamicProxy, but I can't work anything out for a mocked event.
The best way to explain what I'm trying to achieve is with code, please see the comment lines in the test method:
using System;
using Moq;
using NUnit.Framework;
namespace MOQTest
{
[TestFixture]
public class EventsMoqTest
{
[Test]
public void DetachTest()
{
var hasEventMock = new Mock<IHasEvent>();
using (var observer = new Observer(hasEventMock.Object))
{
//Assert that hasEventMock.Object has handler attached
}
//Assert that hasEventMock.Object DOES NOT have handler attached
}
}
public interface IHasEvent
{
event EventHandler AnEvent;
}
public class Observer : IDisposable
{
private readonly IHasEvent _hasEvent;
private readonly EventHandler _hasEventOnAnEvent;
public Observer(IHasEvent hasEvent)
{
_hasEvent = hasEvent;
_hasEventOnAnEvent = _hasEvent_AnEvent;
_hasEvent.AnEvent += _hasEventOnAnEvent;
}
void _hasEvent_AnEvent(object sender, EventArgs e)
{}
public void Dispose()
{
_hasEvent.AnEvent -= _hasEventOnAnEvent;
}
}
}
Unfortunately, you can't. This isn't really a moq issue, but the way the C# event keyword works with delegates. See this SO answer for more information.

Cancel GWT-Event for following Handlers

I want to cancel an event for the following handlers. The sample-class below shows, what I try. Altough the keyevent is canceled for the textbox, the second handler is still called. the order of the handlers is correct. i can prove that Handler1 is called before Handler2. in this sample-class I could use a flag, but in my real class, the handlers and the textbox are seperated, so flags would be a problem. any ideas?
public class EventTestTextBox extends TextBox {
public static class Handler1 implements KeyUpHandler {
#Override
public void onKeyUp(KeyUpEvent event) {
if (event.isShiftKeyDown()) {
event.preventDefault();
event.stopPropagation();
((TextBox)event.getSource()).cancelKey();
}
}
}
public static class Handler2 implements KeyUpHandler {
#Override
public void onKeyUp(KeyUpEvent event) {
Window.alert("should not appear if shift-key is down.");
}
}
public EventTestTextBox() {
super.addKeyUpHandler(new Handler1());
super.addKeyUpHandler(new Handler2());
}
}
event.stopPropagation() cancels event bubbling, i.e. prevents handlers on parent elements to be triggered. It does not prevent handlers on the same element to receive the event.
I have exactly the same question as you. Did you manage to find a solution ?
I guess that the only solution would be to not register the event listener and let the handler1 dispatch (or not) to handler 2 instead.

Resources