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 class of > > Ebutton, or a central wrapper ClickListener (per component, as is > > being talked about). > > > Thus, in a nutshell, if we create an anonyous abstract class of > > EButton : > > > 1. We ensure tight coupling, in the sense that the widget, and its > > "action-on-click" are bound together. > > > 2. Since we do not require any external ClickListener (remember that > > EButton is a clickListener to itself), memory leak is not a problem; > > whenever the anonymous instance goes out of scope, that is the end. In > > other words, there is no chance of a dangling reference in the > > "WrapperWidget"'s onClick method. > > > 3. There is no extra overhead of maintaining any extra ClickListener > > references, as the number of ClickListener references is equal to the > > number of anonymous instances. > > > Your thoughts ..?? > > > On Feb 2, 11:17 pm, gregor <[email protected]> wrote: > > > > > This case requires one class ( anonymous extended EButton) creation. > > > > > Your > > ... > > 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 -~----------~----~----~----~------~----~------~--~---
