Hi all,

I've recently been working on a "real-world" app using Pivot, and I've run into a situation where I'd like to use WTKX binding, but I can't. I want to create a FileBrowserSheet class that extends Sheet and loads its contents from a WTKX file.

In order for a Sheet subclass to take advantage of binding to process the WTKX, Sheet would somehow need to extend Bindable. However, Sheet's root base class is Component, which currently extends Object. We could conceivably make Component extend Bindable; however, we decided a while back for a variety of reasons that WTK classes should not be dependent on WTKX, and I would prefer to stick with that decision.

I think it will be fairly common for developers to want to bind to application-specific Window subclasses; for example, LoginDialog, FileOpenDialog, ContactInfoSheet, etc. I also think that any non- trivial application will want to define a main application window class rather than embedding the UI details in the application itself. For example, I might define MyApplication that implements Application, and MyApplicationWindow that extends Window. MyApplication would simply serve as the entry point into the application, playing the same role as the main() method in a typical Java application. We wouldn't be able to use binding in any of these use cases.

I see two options for resolving this issue:

1) Continue to support Bindable, but move it out of pivot.wtkx, possibly to pivot.util or pivot.wtk. As a result of this move, we would lose support for @Load, since it depends on WTKXSerializer. However, we could retain support for @Bind.

2) Eliminate Bindable altogether. This seems drastic, especially since the annotations do tend to clean up the code a bit. However, there is a lot of code behind that support that needs to be maintained, and I'm not sure it is justified.

I'm leaning pretty strongly towards #2. This is what the code in my FileBrowserSheet constructor looks like without binding (I'm assuming the existence of a template parameter in WTKXSerializer - that can be discussed as another topic, if necessary):

Resources resources = new Resources(this);
setTitle(resources.getString("title"));

WTKXSerializer<Component> wtkxSerializer = new WTKXSerializer<Component>(resources);
setContent(wtkxSerializer.readObject(this, "file_browser.wtkx"));

folderTreeView = wtkxSerializer.get("folderTreeView");
okButton = wtkxSerializer.get("okButton");
cancelButton = wtkxSerializer.get("cancelButton");

With binding, the final three lines would be replaced with bind(), which is very concise. However, the above code is still pretty readable. Yes, we have to manually assign the member variables, but is that really that much of a burden on developers? Is the simplification offered by the bind() method enough to justify the additional code maintenance of the Bindable class and the bind processor?

The bind processor is what we use to rewrite the Bindable class files at compile time so they can run in an untrusted applet. It is worth noting that the processor currently relies on undocumented features of the javac compiler. When binding seemed like it might be more generally useful, I thought that this would be an OK risk to take. However, now I don't think so.

I'm going to suggest that we eliminate the Bindable class and revert to the previous way of loading and processing WTKX. I've made some minor API additions that simplify the use of WTKXSerializer directly. pivot.util.Resources now takes a base object or class, so you can write:

Resources resources = new Resources(this);

If your class is named com.foo.MyClass, it will automatically load com.foo.MyClass.json.

I also added a readObject() overload to WTKXSerializer that takes an object and a resource name. Now, instead of this:

wtkxSerializer.readObject(getClass().getResource("foo.wtkx"));

you can write this:

wtkxSerializer.readObject(this, "foo.wtkx");

Again, minor changes, but they make the code that much more readable.

I understand that @Bind is pretty convenient, but it can't currently be used in what I suspect will be a common use case, and, in my opinion, adapting it such that it can be used for this purpose makes it less compelling (especially since it requires undocumented features of the compiler). Please let me know what you think.

Thanks,
Greg

Reply via email to