> 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.
Good points. And of course there's no reason you can't use whatever naming
scheme you prefer in your own applications.
> > * 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.
Ah, OK.
> 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.
I had actually considered doing exactly this a few months back but didn't have
time to get to it. I think it is a great idea.
> - 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.
That's correct - the JVM does not allow untrusted code to access private class
members. Note that you can still access the values via these namespace argument
to initialize(), though.
> - 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.
Sure there is - just give it an ID and then you can invoke methods on it (as
shown in the examples from my previous email).
> - 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?
You can - but the compiler won't verify it. The check would have to be done at
runtime.
> 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.
Makes sense, and I also tend to defer to Java as much as possible. I'm just
saying that, when script is appropriate, I prefer this syntax.
G