Saturday, May 31, 2008

Java SwingBuilder: support for JScrollPane, Border, Icon + new discussion group

New version up at Java Builders:
http://javabuilders.googlecode.com/files/javabuilder.swing.0.1.2008-05-31.zip

Mostly lots of work under the hood, but also plugged in some missing holes:

Border
Icon
JScrollPane

We also hava a Java Builders group now, please join if you have any questions, need an enhancements, run into a bug, etc:

http://groups.google.com/group/javabuilders

Gregg Bolinger has been putting the SwingBuilder through some tests and been able to create a nice panel such as this quite easily (after some initial learning curve and bug fixing on my part):

Tuesday, May 27, 2008

Java SwingBuilder: our first bug fix release

http://javabuilders.googlecode.com/files/javabuilder.swing.0.1.2008-05-27.zip

The Ant build was not including all the required resources in the generated jar file, and runtime exceptions could occur. Please update.

Many thanks to Gregg Bollinger for pointing this out and submitting the first defect as well (although on an unrelated issue). Defects are good (well, not for my ego, they're not...but it's good to get some feedback).

Monday, May 26, 2008

Swing/SWT programmers: discover the power of MigLayout

I am happy to announce a DevX.com article I wrote about Mikael Grev's amazing MigLayout layout manager:
http://www.devx.com/Java/Article/38017

If you are doing any UI development in either Swing or SWT, you deserver to give this layout manager a try. After getting familiar with it, I would find it painful to go back to anything else.

I used one of the samples the readers have sent me on the complex UI challenge post from a few weeks ago as the base for the most complex screen in the article...I can't even imagine how convoluted the code would have been in any standard JDK layout manager.



Don't forget to vote on the RFE to get MigLayout included in the base JDK:
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=2532262642c44ffffffffa36083a3bd0096c?bug_id=6530906

BTW, what's wrong with this picture? The RFE is in the top 10 RFEs, but Sun marked the priority as "5-Very Low". Earth to Sun, Earth to Sun...listen to your users. 90% of the layout manager tutorial could have been redone with nothing but MigLayout.

Pretty much all layout managers in the JDK (outside of FlowLayout) could be marked as @Deprecated and replaced with MigLayout.

Saturday, May 24, 2008

Java SwingBuilder : first support for validations, inching towards 0.1 release

I just committed the first working code that has some integrated validator logic. Latest code drop available as usual on javabuilders.org.

Just like with binding, it is a new root node in the YAML file:
JFrame(name=frame,title=Binding Frame,size=packed):
content:
- JLabel(name=fnLbl, text="First name:",labelFor=fName)
- JTextField(name=fName)
- JLabel(name=lnLbl, text="Last name:", labelFor=lName)
- JTextField(name=lName)
- JButton(name=ok, text=OK, onAction=(validateInput,save,cancel))
- JButton(name=cancel, text=Cancel, onAction=cancel)
layout: |
[] [grow,200px]
>fnLbl fName
>lnLbl lName
>ok+*=1,cancel=1 [grow,bottom]
bind:
- firstName: fName.text
- lastName: lName.text
validate:
- fName.text: {label: First Name, mandatory: true, minLength : 5}
Right now it only supports "mandatory" and "minLength", but shortly I will be adding all the validator routines supported by Apache Commons Validators:
http://commons.apache.org/validator/apidocs/org/apache/commons/validator/routines/package-summary.html#package_description

In the above example, if the First name field is missing or less than 5 characters,

it will display a nice error dialog to inform the user:


At this point, the validation logic still needs to be called manually from the Java side:

private final BuildResult result = SwingBuilder.build(this);

public boolean validateInput() {
return result.validate();
}
but I will be looking into automating this soon.

You can see the full YAML and Java here:
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.yaml
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.java

Happy building! Once this is done, an official 0.1 release will finally arrive.

Thursday, May 22, 2008

Java SwingBuilder: now with proper Wiki

One of the biggest shortcomings of this project was the lack of documentation, outside of this blog. I have been working on getting the Wiki complete, and although it is still not 100% done, it should give newcomers a good introduction to what this project is all about:

http://code.google.com/p/javabuilders/wiki/Overview

Friday, May 16, 2008

Java to get a new WebKit-based browser component

Exciting news for all Java developers that plugs in an outstanding hole in the stack.
Buried deep in the sometimes heated discussions about JavaFX on javalobby.org there was a statement from one of the core Swing developers at Sun:
http://java.dzone.com/articles/paying-price-javafx#comment-3252

"BTW, I was forgotting it: we're also going to have JWebPane, an embedded Swing/JavaFX component based on WebKit. It's another huge, historical gap that it's going to be closed."

This is great news! Kudos to Sun for making it happen...I'll be first in line to play with JWebPane when it arrives.

Also, all the new media stuff (video codecs, etc) will be integrated right into Java 7.

All I can say is great work Sun. Would it be better if it was a year earlier, but I'll take it anyway without asking any questions. :-)

Java SwingBuilder: turbo-charging YAML with virtual constructor flow

I *was* supposed to look into integrating Commons Validators into the JavaBuilder concept, but occasionally one had that flash of inspiration where for a moment you cross into "mad scientist" territory...and this week had one of those. I've added a new concept to YAML that I call "virtual constructor flow" that basically compacts the file format to the maximum level allowed by natural law. :-)

OK, but let's start from the beginning. Let's say we have a typical builder file like this in YAML, with the traditional YAML white-space indentaton to indicate hierarchy:

JFrame:
name: myFrame
title: My App Frame
state: max

YAML supports the concept of alternate flows, hence the same data can be expressed in-line, which basically turns a portion of it into JSON:

JFrame: {name: myFrame, title: My App Frame, state: max}

This is very cool and it helps to reduce the number of lines in a file. However, it does not work if the node in question has additional child nodes. In Java SwingBuilder, by convention children are grouped under the "content" list node (same name as in JavaFX...not a coincidence, obviously):

JFrame:
name: myFrame
title: My App Frame
state: max
content:
- JPanel:
name: mainPanel
content:
- JButton: {name: okButton, text: OK}

The limitation / design (?) of YAML is that once you escape into the JSON format the entire child node has to be expressed in it, even if it has children of its own. This unfortunately would lead to many nested "{", "}", "[", "]" brackets (if you've seen any serious JavaFX code, you will see it often has lots of secton with 10 or more levels of nested brackets of various type).

So, if I wanted to cut down on the number of lines in a file and do it all inline it loses all the nice, clear YAML whitespace indentation and descends into JSON closing bracket hell:

JFrame: {name: myFrame, title: My App Frame, state: max, content: [
{JPanel: {name: mainPanel, content: [
{JButton: {name: okButton, text: OK}}
]}
]}


In other complex file very soon you will have multiple levels of nested "}]}" type closing brackets, which makes it very unreadable IMHO. That's why I opted for YAML instead of JSON.

What I would like to do is to use the in-line formats for the properties belonging to the current node and then go back to regular white-space YAML for its children, e.g.:

JFrame: {name: myFrame, title: My App Frame, state: max}
content:
- JPanel: {name: mainPanel}
content:
- JButton: {name: okButton, text: OK}


However, this is not allowed in YAML and the YAML parsing library will exit with an exception. It's all whitespace or it's all JSON-style brackets, but you can't mix and match them.

So, this is where the mad scientist mode entered. I decided to add a new flow type to YAML via a custom preprocesor that I call "virtual constructor flow" and it looks like this:

JFrame(name=myFrame, title=MyAppFrame, state=max):
content:
- JPanel(name=mainPanel):
content:
- JButton(nam=okButton, text=OK)

This is still valid YAML (it gets processed without errors), but obviously the child properties are now embedded directly into the YAML node definition, so it does not know about them, it just sees a node defined as JFrame(name=myFrame, title=MyAppFrame, state=max)

The JB pre-processor will take the YAML Object and do a second pass through and "explode" those properties embedded int the virtual constructor flow and create at run-time the exact same "pure" YAML hierarchy as seen at the beginning.

Also, the pre-processor does some nifty stuff such as if a node is defined right off the bat as a list (e.g. "JFrame: " with "- JButton", "- JLabel" nods underneath it) it will property "move" the list one level down to the default "content" node.

Therefore all we have left is:

JFrame(name=myFrame, title=MyAppFrame, state=max):
- JPanel(name=mainPanel):
- JButton(nam=okButton, text=OK)

A lot less than the original input:

JFrame:
name: myFrame
title: My App Frame
state: max
content:
- JPanel:
name: mainPanel
content:
- JButton: {name: okButton, text: OK}

but at run-time the pre-processor will "explode" the compressed format to exactly the same thing.

Now you are wondering, "well OK, this is cool, but is it really worth it to bastardize YAML with some sort of custom extension?". And the answer is YES, it is worth, 'cause it brings amazing reduction in the size and levels of indentation when defining UIs via Java SwingBuilder.

Let's say we have a simple JFrame with 3 main menus and some child menus underneath them:


The pure YAML version of the build file for this looks like this:

http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/menu/FrameWithMenu.yaml

but the compressed version is WAY smaller less verbose:

http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/menu/FrameWithMenuCondensed.yaml

Basically, this allows you across the board to define an entire object and all of its properties in one line of "enhanced" YAML using the virtual constructor flow.

The latest build of Java SwingBuilder with support for this enhanced format is up on javabuilders.org.

P.S. Here's another form converted to the new format with before/after samples:

Before:
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.yaml?r=150
After:
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.yaml?r=157

Less code and less lines to type = good! :-)

Thursday, May 15, 2008

NetBeans 6.1 : no go for YAML development

I've tried doing some YAML work in the new NetBeans 6.1 to see how it stacks up against Eclipse for JavaBuilder development.

Unfortunately, a few things out the bat went wrong:
a) the YAML editor is not part of the base IDE, nor is it a stand-alone plugin. You have to download the entire Ruby support bundle to get it. Minor, but a little annoying.

YAML != Ruby on Rails
YAML > Ruby on Rails

b) the editor seems to only support a small subset of YAML syntax (probably just what is needed for Ruby on Rails) and in particular it does not recognize YAML block literals:
http://en.wikipedia.org/wiki/YAML#Newlines_preserved

which I use all over the place, especially for the "layout" definitions.

I've filed two issues for this, please vote on them and help to get them fixed in a future update:
http://www.netbeans.org/issues/show_bug.cgi?id=135165
http://www.netbeans.org/issues/show_bug.cgi?id=135166

Trolltech makes Qt run as GTK+



Great news for us Linux fans. One of the pain points is the different look and feels of GTK+ and KDE/Qt apps.

It seems the fine folks at Trolltech are working on making this go away by allowing Qt apps to use GTK+ for all the rendering (not imitated, real GTK+).

Thank you Trolltech, this is a great idea. I would love to see Amarok and KTorrent blend seamlessly into my Ubuntu GNOME desktop.

http://labs.trolltech.com/page/Projects/Styles/GtkStyle

Monday, May 12, 2008

Java SwingBuilder: binding done, SwingWorker done, fat trimmed

Latest code drop on javabuilders.org has the latest and greatest.

The binding support comes in two basic flavors:

a) straight bean-style property, e.g:

bind:
- this.lastName : firstNameTextField.text

This is a straighforward command to bind the text field's Text property (the source) to the "lastName" property of the backing Java class.

b) EL-style property that allows binding to multiple properties, e.g.:

bind:
- this.fullName: "${this.firstName} ${this.lastName}"

Since "{" and "}" are reserved characters in YAML you have to break out into quoted string to put it in. Note that when dealing with multiple properties like this it is NOT POSSIBLE to bind to properties from a different object (e.g. get the text from one text field and then one from another and combine them). This is just a limitation of how Beans Binding works.

As I mentioned before, the support for running background methods via @DoInBackground is done and it automatically pops up a nice progress dialog with an optional cancel button, if required. See the code in the sample's save() method to see how you can interact with it from the Java code:
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.java

In another node, I removed all the Log4J logging code and switched to regular Java logging API (even though it is sucky compared to Log4J). Thanks to this I cut nearly 500KB in the download size (for the actual JB jar and its dependencies). We are now at a total of 1.1 MB...an overhead of 50% seemed a lot for something like logging, hence Log4J had to go.

I like to keep it lean. This ain't .Net with a 30MB download forced upon you in the background via Windows Update :-)

Next up: validations. Stay tuned.

Friday, May 09, 2008

Java SwingBuilder: latest updates on binding, SwingWorker and validations

It may seem quiet in JB land, but deep in the underground bowels of the Furmankiewicz Laboratories, things are churning nightly.

There's a lot of unstable code right now that needs to be finished, hence no new updates, hopefully more next week.

Priority is to complete a 0.1 release which will have finished support for:

a) binding (Bean and EL) e.g.

bind:
- this.lastName : lastNameTextField.text
- this.fullName: "${firstNameTextField.text} ${lastNameTextField.text}"

b) support for running long running methods via SwingWorker

- first, all the event handlers now support executing multiple methods in sequence, so you can do:

onAction: save
or:
onAction: [validate, save, close]

On the Java side you can use an annotation to flag which method is to be run in background:

private void validate() {}

@DoInBackground(progressMessage="Saving customer data...")
private save(BackgroundEvent evt) {}

private close() {
//will only be executed AFTER the background method finishes successfully
}

c) integration with Commons Validations (or JSR 303 if there was a reference implementation), e.g.:

validate:
- firstNameTextField.text : {mandatory : true. minLength: 5, maxLength: 40}

etc, etc.

This is the dev plan for next week and once it's done and stable, 0.1 will be released and then maybe JB will get some notice. Wish me luck in my late night coding endeavours.

P.S. Update for May 12: binding and background task support is done!
Get latest code drop from javabuilders.org to see it.
Working example of both:
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.yaml
http://code.google.com/p/javabuilders/source/browse/trunk/org.javabuilders.swing/samples/org/javabuilders/swing/samples/binding/BindingFrame1.java

I need to do some more work on binding to allow binding a target to multiple elements, but that can come later.