Also, in "FocusWidget" class, clickListeners field is listed as ::

private ClickListenerCollection clickListeners;

which means that every Button instance has its own set of of
ClickListenerCollection, whereas (if I correctly decipher your post),
javascript seems to create a static set of "ClickListenerCollection",
which happens to be shared by all Button instances, and (assuming this
is the case), the one-listener-paradigm clearly wins over a self-
independent-listener-per-anonymous-class.

However, I am not sure, and is driving me nuts as to how weird can
this get, wherein an instance variable in Java is converted to a
static variable in Javascript..

Looking forward to some potions of wisdom..

On Feb 4, 10:21 am, Ajay Garg <[email protected]> wrote:
> But isn't Javascript "static" keyword, different from Java "static"
> keyword ... In Javascript, it still regains object scope, while in
> Java, it is a class scope .....??????
>
> On Feb 3, 9:42 pm, gregor <[email protected]> wrote:
>
>
>
> > It's interesting to see how these various methods actually work in
> > javascript.
>
> > In all cases click listeners are managed using the following methods.
> > If you look at the basic Button constructor you can see it calls the
> > addClickListener(..) function
>
> > function $addClickListener(this$static, listener){
> >   if (!this$static.clickListeners) {
> >     this$static.clickListeners = $ClickListenerCollection(new
> > ClickListenerCollection());
> >     sinkEvents(this$static.element, 1 | (this
> > $static.element.__eventBits || 0));
> >   }
> >   $add_2(this$static.clickListeners, listener);
>
> > }
>
> > Then the user click is detected
>
> > function onBrowserEvent(event_0){
> >   if ($eventGetTypeInt(event_0) == 1) {
> >     if (this.clickListeners) {
> >       $fireClick(this.clickListeners, this);
> >     }
> >   }
>
> > }
>
> > Then the elements with ClickListeners attached are queried to see if
> > any match the element the user clicked. Obviously the more there are,
> > the longer this will take.
>
> > function $fireClick(this$static, sender){
> >   var listener, listener$iterator;
> >   for (listener$iterator = $AbstractList$IteratorImpl(new AbstractList
> > $IteratorImpl(), this$static); listener$iterator.i < listener
> > $iterator.this$0.size_0();) {
> >     listener = dynamicCast($next_0(listener$iterator), 5);
> >     $onClick(listener, sender);
> >   }
>
> > }
>
> > Now we can look at how three methods of setting up Buttons with
> > ClickListsners is set up in javascript.
>
> > Method 1: A shared ClickListener - note using a hash table lookup
> > would be much more efficient than this if there where a lot of
> > them.
>
> >     ClickListener buttonListener = new ClickListener() {
> >         public void onClick(Widget sender) {
> >             if (sender==sharedButtonOne) {
> >                 Window.alert("Shared One");
> >                 return;
> >             }
> >             if (sender==sharedButtonTwo) {
> >                 Window.alert("Shared Two");
> >                 return;
> >             }
>
> >         }
> >     };
>
> >     Button sharedButtonOne = new Button("Shared 1",buttonListener);
> >     Button sharedButtonTwo = new Button("Shared 2",buttonListener);
>
> > This translates as follows. Note the single listener instance is
> > translated to Sandbox$1 (my scratch module is called SandBox BTW).
> > However many Buttons are added we will still have this single instance
> > of it.
>
> > function $SandBox(this$static){
> >   this$static.layout = $HorizontalPanel(new HorizontalPanel());
> >   this$static.buttonListener = new SandBox$1();
> >   this$static.sharedButtonOne = $Button_0(new Button(), 'Shared 1',
> > this$static.buttonListener);
> >   this$static.sharedButtonTwo = $Button_0(new Button(), 'Shared 2',
> > this$static.buttonListener);
> >   return this$static;
>
> > }
>
> > function $SandBox$1(this$static, this$0){
> >   this$static.this$0 = this$0;
> >   return this$static;
>
> > }
>
> > function $onClick(this$static, sender){
> >   if (sender == this$static.this$0.sharedButtonOne) {
> >     $wnd.alert('Shared One');
> >     return;
> >   }
> >   if (sender == this$static.this$0.sharedButtonTwo) {
> >     $wnd.alert('Shared Two');
> >     return;
> >   }
>
> > }
>
> > function SandBox$1(){
>
> > }
>
> > _ = SandBox$1.prototype = new Object_0();
> > _.typeId$ = 23;
> > _.this$0 = null;
>
> > Method 2: using anonymous inner class
>
> >     Button innerButtonOne = new Button("Inner One", new ClickListener
> > () {
> >         public void onClick(Widget sender) {
> >             Window.alert("Inner One");
> >         }
> >     });
>
> >     Button innerButtonTwo = new Button("Inner Two", new ClickListener
> > () {
> >         public void onClick(Widget sender) {
> >             Window.alert("Inner Two");
> >         }
> >     });
>
> > This translates as follows: Note that we now have two listener
> > objects, both of which will be added to the main ClickListener
> > collection. With 100 buttons, we would have 100 of them.
>
> > function $SandBox(this$static){
> >   this$static.layout = $HorizontalPanel(new HorizontalPanel());
> >   this$static.innerButtonOne = $Button_1(new Button(), 'Inner One',
> > new SandBox$1());
> >   this$static.innerButtonTwo = $Button_1(new Button(), 'Inner Two',
> > new SandBox$2());
> >   return this$static;
>
> > }
>
> > function onClick(sender){
> >   $wnd.alert('Inner One');
>
> > }
>
> > function SandBox$1(){
>
> > }
>
> > _ = SandBox$1.prototype = new Object_0();
> > _.onClick = onClick;
> > _.typeId$ = 23;
> > function onClick_0(sender){
> >   $wnd.alert('Inner Two');
>
> > }
>
> > function SandBox$2(){
>
> > }
>
> > _ = SandBox$2.prototype = new Object_0();
> > _.onClick = onClick_0;
> > _.typeId$ = 24;
>
> > method 3: your EButton
>
> >     EButton ajaysButtonOne = new EButton("Ajay's One") {
> >         public void onClick(Widget sender) {
> >             Window.alert("Ebutton 1");
> >         }
> >     };
>
> >     EButton ajaysButtonTwo = new EButton("Ajay's Two") {
> >         public void onClick(Widget sender) {
> >             Window.alert("Ebutton 2");
> >         }
> >     };
>
> > This translates as follows: As you can see a separate instance (SandBox
> > $1 & sandBox$2) created for each EButton instance. It appears to have
> > basically turned itself into a ClickListener equivalent to method 2.
> > It's instructive to compare this with how a normal Button is
> > constructed in methods 1 & 2.
>
> > function $SandBox(this$static){
> >   this$static.layout = $HorizontalPanel(new HorizontalPanel());
> >   this$static.ajaysButtonOne = $SandBox$1(new SandBox$1(), "Ajay's
> > One");
> >   this$static.ajaysButtonTwo = $SandBox$2(new SandBox$2(), "Ajay's
> > Two");
> >   return this$static;
>
> > }
>
> > function $EButton(this$static, text){
> >   $ButtonBase(this$static, $doc.createElement('button'));
> >   adjustType(this$static.element);
> >   this$static.element['className'] = 'gwt-Button';
> >   $setInnerText(this$static.element, text);
> >   $addClickListener(this$static, this$static);
> >   return this$static;
>
> > }
>
> > function EButton(){
>
> > }
>
> > _ = EButton.prototype = new Button();
> > _.typeId$ = 23;
> > function $SandBox$1(this$static, $anonymous0){
> >   $EButton(this$static, $anonymous0);
> >   return this$static;
>
> > }
>
> > function onClick(sender){
> >   $wnd.alert('Ebutton 1');
>
> > }
>
> > function SandBox$1(){
>
> > }
>
> > _ = SandBox$1.prototype = new EButton();
> > _.onClick = onClick;
> > _.typeId$ = 24;
> > function $SandBox$2(this$static, $anonymous0){
> >   $EButton(this$static, $anonymous0);
> >   return this$static;
>
> > }
>
> > function onClick_0(sender){
> >   $wnd.alert('Ebutton 2');
>
> > }
>
> > function SandBox$2(){
>
> > }
>
> > _ = SandBox$2.prototype = new EButton();
> > _.onClick = onClick_0;
> > _.typeId$ = 25;
>
> > So my reading of this is:
>
> > 1) All three methods involve creating a Button instance which
> > translates into a native Button element provided by the browser and
> > attached to the DOM.
> > 2) All three methods involve creating one or more listener objects
> > (sandBox$1, SandBox$2 etc) that are added to the static ClickListsner
> > Collection
> > 3) When a Click event is fired from the browser, the click listeners
> > are queried to see if any are registered with the clicked DOM element.
> > 4) In method one there is only one of them, so that question is
> > answered very quickly
> > 5) In methods 2 & 3, the more buttons there are, the longer this
> > takes.
> > 6) Although EButtons appear to register themselves with themselves
> > ($addClickListener(this$static, this$static)) they still go through
> > the same rigmarole through the listener collection if one is clicked -
> > they do not bypass it by saying "oh, I can just call myself" as far as
> > I can see.
> > 7) The EButton option results in marginally more code than the inner
> > class option, and massively more than the shared listener option
> > (multiply it all up by e.g. 100), may run slower as a result even by
> > comparison with the inner class option, and will certainly increase
> > the size of the javascript files.
> > 8) I think it demonstrates conclusively why using the single listener
> > technique can make a huge difference if you have a large number of
> > clickable widgets in an application.
>
> > On Feb 3, 8:14 am, Ajay Garg <[email protected]> wrote:
>
> > > Hmm.. I looked at GWT's code, and went all 
> > > thewayuptohttp://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/g...
> > > code.
>
> > > Button is a sub-subclass of FocusWidget, and this is what happens.
> > > Whenever a clickListener is added to a Button for the first time,
> > > "Event.Click" event is sunk in for the newly instantiated Button
> > > instance, and the clickListener added to ClickListenerCollection.
> > > Next, whenever an onBrowserEvent(Event event) method is triggered, the
> > > onClick() method is called for each of the clickListener registered in
> > > ClickListenerCollection.
>
> > > So, as far as managing a large number of ClickListeners goes, if we go
> > > by using EButton, the number of ClickListeners is equal to the number
> > > of anonymous abstract classes made out of EButton.
>
> > > I think a more thinking point would be to consider "public void
> > > sinkEvents(int eventBitsToAdd)" method of UIObject class, which
> > > happens to be a superclass of FocusWidget. This method is called
> > > whenever a ClickListener is added to an instance for the first time.
> > > Thus, it does not matter whether the ClickListener interface being
> > > added is the same reference as the anonymous abstract
>
> ...
>
> read more »- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to