|  A long time ago, on Mon, 2005-05-09 at 14:44 -0400, Owen Taylor wrote:
 > I did some more fooling around today, and wanted to revisit an old
 > discussion: [signal handling]
 
 I've been saving this message for a long time, hoping I'd have a chance
 to address it. So it's been almost 6 months. Oh well. First I'll write
 my views on the subject, then inline reply to some of his comments.
 
 Owen's basic concern seems to be the verbosity and clumsiness of the
 Listener/Event pattern. When I first saw this pattern in java-gnome, I
 freaked, something along the lines of "Oh my lord, what the hell is
 this?" :)
 
 But my GUI programming in Java predates Java 1.1. When I learned AWT, it
 used a very basic event handling pattern. One of the reasons I never did
 port that code from Java 1.0.2 (we're talking 1998 here) was that I was
 completely mystified by the Listener/Event thing that the AWT in Java
 1.1 introduced.
 
 ... time ... passes ...
 
 As I understand it from Mark Howard and Jeff Morgan, they added the
 Listener/Event pattern for signal handling to Java because they felt it
 was the more familiar idiom for experienced Java programmer, especially
 those coming from Swing or AWT. 
 
 I believe that this was absolutely the correct decision to make. In
 fact, as I've looked around a bit (and over enterprise code that I've
 run (though didn't write - I'm an operations guy) I've realized just how
 prevalent this pattern is in the Java world. It's everywhere - EJB, JMS,
 all over the J2EE stack.
 
 And so, even though it's somewhat (ok, very) cumbersome **especially
 from the viewpoint of someone coming from the GTK C world**, it is
 natural indeed for someone coming from the Java world, and that
 (unscientifically) is the bulk of our userbase.
 
 ++
 
 Ok. So I've said that it's ok. But that doesn't mean it can't be
 improved - or ditched. To be honest, I'd like to see a better model.
 
 But switching will be tricky indeed. We already have 2 1/2 APIs for
 signal handling. [the Listener/Event pattern which most of us use, then
 the raw Event handling which happens to be exposed, and also method name
 hookups if you care to use Glade for that]
 
 When I was in Toronto last week I met with some of the guys (and Hiro,
 who came up from Waterloo!) and discussed this issue among others. The
 biggest problem I see is that we already are close to the boundary of
 having unmaintained/unsupported APIs, and if we don't do a clean break
 (not just deprecating but hard and fast REMOVING the old APIs in favour
 of the new one) then we will end up with an even worse situation.
 
 The only possible place for us to make such a break is at a major
 version number jump (ie libgtk-java moves from 2.x.y to 3.w.z) ... which
 is hard to do unilaterally as we are now somewhat historically tied to
 following the underlying GTK release numbers. [Note to self - moving
 from java-gnome 0.8.3 to java-gnome 2.4.x was probably a bad idea - we
 lost the freedom to make a major API change on our own schedule]. 
 
 To be honest, I don't much care about this - in the modern software
 world, 1.2 to 1.4 IS a major release. So if we need to change the signal
 handling we can probably do so whenever, but we should do so with lots
 of warning and RIP OUT whatever old models we're no longer going to
 support.
 
 ++
 
 Now on to specifics. If we do change (and incur all this administrative
 burden I've just been talking about, not to mention forcing a port of
 any and all applications), then we should make it a good one. There are
 all sorts of areas of the API that could do with improvement & redesign.
 
 In the case of signal handling, there seem to be two broad option paths,
 revolving around typing.
 
 The present system is strongly typed. We have KeyListeners and KeyEvents
 and TreeViewListeners and TreeViewEvents and also interfaces with
 similar APIs, eg   TreeModelFilterVisibleMethod. The advantage of this
 is that we allow ourselves to take advantage of the strengths of the
 Java language, getting appropriate methods for appropriate events, and
 having being able at compile time to catch wrong API mistakes.
 
 The other branch of options involve not using the type safety system at
 all, and doing all the lookups by strings. This is more "traditional"
 GTK, but also is less ideal programming practice because it means that
 you have to wait until runtime to find out if you misspelled a signal
 name. The usual result of such a bug is that simply nothing happens, but
 likewise situations where the wrong method gets called arise. Worst of
 all you loose any support that IDEs like Eclipse can give you both at
 code writing time and also at debugging time (call stacks become a
 mess). The upside is that the API is really simple, although not quite
 as simple as in C or Perl as one has to fight through a class / object
 somewhere to get to the method name you're trying to call.
 
 For me the promise of absolute simplicity is not worth the cost of not
 leveraging the strongly typed character of the language we're working
 in. But in the end, I'd make my vote on the basis of how elegant our
 proposed new system would be in use. 
 
 ++
 
 To close, some replies to Owen's comments: his first suggestion
 
 > >  button.connectClicked (new ButtonClickedListener () {
 > >     public void run(Button button) {
 > >       System.out.println("Button was clicked");
 > >     }  
 > >  }
 
 Isn't too bad. Strongly typed.
 
 > > Creating one helper class for each signal might be a bit
 > > expensive... 
 
 Expensive in authoring and a little less so in maintenance to be sure.
 But in runtime terms Java is already stacked full of objects. 20-300 for
 signals isn't going to hurt anything.
 
 Owen's second message notes that this is nicer:
 
 >  button.connect(new Button.Clicked() {
 >      public void clicked(Button button) {
 >          System.out.println("Button was clicked");
 >      }
 >  });
 
 and I agree, although in general I would note that even something as
 simple as Button has a plethora of signals that need implementing: from
 Button.Type I see ACTIVATE, CLICK, ENTER, LEAVE, PRESS, and RELEASE. For
 all I know there are more down in GTK that we haven't yet properly
 wrapped.
 
 > (Maybe use
 > 'onClicked' rather than 'clicked' as the method name?)
 
 [is click or clicked the underlying event-signal name?]
 
 Not sure. Java's APIs (and java-gnome's) are schitzo in this regard.
 You've got stuff like next() and item() and present() and activate()
 floating around, but then set*, get*, and is* prevails for all the
 property accessors and mutators. Perhaps on* as a family name isn't a
 bad idea.
 
 I have some thoughts on the API design sweepstakes, but this email is
 already too long as it is. I'll follow up if there is indeed interest in
 radically changing things. Otherwise, if we're just going to leave
 things be, then let's just keep things well maintained and work on
 fixing, if nothing else, the JavaDoc for all the bloody nested Type
 statics. I remember how hard it was to learn our event handling API,
 even with some examples to follow.
 
 AfC
 Bangalore
 |