pivot-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bill van Melle <bill.van.me...@gmail.com>
Subject Re: Simpler event listeners?
Date Fri, 19 Nov 2010 23:07:34 GMT
> Naming the files Foo.java and Foo.bxml implies that they are partial
> classes, which isn't the case. Developers may expect "new Foo()" to produce
> the same results as deserializing Foo.bxml - since it won't, this could be
> confusing. Using the "Foo.java/foo.bxml" convention avoids this ambiguity.

But it's also the case that neither can be used without the other -- you
can't do new() on the class and get a working component, and you can't
deserialize the bxml without casting it to the class.  So I think people
already have to understand the structure.  If anything, my strategy of
adding a static create method to the class simplifies that -- nobody other
than the "owner" of a bxml file ever needs to touch the serializer or even
know the name of the bxml file.

A practical benefit of naming them the same is that they're adjacent in
Eclipse's case-sensitive explorer sort, instead of far apart.

> * In lieu of a proper constructor, I add a static factory method...
> > so that code which in other systems might call new ClassName() can almost
> as painlessly call ClassName.create().
> This is an interesting idea. I wonder if it might be worth adding a
> parameterized static method to BXMLSerializer to do this, so you don't have
> to add this to every class:
> public static <T> T create(URL, Resources) throws IOException,
> SerializationException { ... }

Doesn't do anything for me.  I add the create method as a way of simplifying
the interface to the class, not because I dislike casting the result of the
serializer -- I don't want anyone outside the class to even care that
there's a bxml file and how to deserialize it.

Hmm, this now makes me wonder if it would be easy to make an Eclipse plugin
that would offer a "New" option "Pivot component with bxml", which would
create two files with the kind of boilerplate I spoke of.

> The "this" reference in the inner class points to itself, but you can
> always use <OuterClass>.this to get access to the containing object if you
> need to. However, in most cases this isn't necessary since inner classes
> don't need to qualify access to outer class methods.

Good to know (about qualified this).  I already knew I could call outer
methods without qualification, but a common thing that a button press
listener does is popup a dialog, something that requires passing the parent
reference in.

> - In general, I'd expect handler methods such as "loginButtonPressed" to be
> private (you probably don't want to expose this logic to arbitrary callers).
> We can use reflection to call a private method, but that requires that the
> code be trusted (i.e. you couldn't do this in an applet unless it was
> signed). This isn't necessarily a blocker - the same applies to the @BXML
> annotation, which is often used to populate private members. It's just
> something to consider.

Oh dear, so I can't even use @BXML on private members in an unsigned applet?
 Well, that kills part of my strategy if I ever want to do an unsigned
applet (not important to me right at the moment, though).  Yes, in general
listeners ought to be private.

> - As a developer, I might expect the "loginButtonPressed" method to be
> defined in script within the page, rather than as a method on the root
> object. In other words, there's nothing in the syntax that lets me know what
> object defines the method.

True, but then currently there's no way at all to call methods on the Java
class, so you're not yet thinking to look there.  I think having the Java
class of the bxml root be a place for a listener implementation would be no
harder or unexpected a place for a programmer to look than, say, inside an
included .js file.

> - Finally, it seems like the loginButtonPressed() method should implement
> the syntax defined by the buttonPressed() method. Because .NET uses
> delegates for event handlers (and XAML is compiled), this can be enforced by
> the compiler. However, since BXML is not compiled (and Java does not support
> delegates), we can't enforce it. This again suggests that the handler should
> be script code rather than the name of a method on the root object.

Can you not use reflection to verify that the specified listener method has
a signature that matches what a buttonPressListener is expecting?  (I don't
know -- I'm not a Java expert.)  And if not, what happens?  You get a Java
runtime error when you call the listener method? I'd live with that -- as it
is, bxml deserialization errors are often plenty cryptic :).

> FWIW, I generally don't use attribute-based event handlers - I prefer the
> element-based syntax:
> <PushButton buttonData="Login">
>    <buttonPressListeners>
>    function buttonPressed(button) {
>        myWindow.login();
>    }
>    </buttonPressListeners>
> </PushButton>
> Yes, it's a bit more verbose, but I find it easier to read and write. It is
> also much easier to implement listeners with multiple handler methods this
> way.

If I have to be that verbose, I'd much rather hide the verbosity in my Java
class' initialize method, and try to keep the bxml file readable.

View raw message