Geertjan is a DZone Zone Leader and has posted 468 posts at DZone. You can read more from them at their website. View Full User Profile

Kicking the Tires on Pivot 1.0

10.16.2008
| 4101 views |
  • submit to reddit

No better way to get to know a new thing than to simply start playing with it. No better time than right after the first release (yesterday). Kicking Pivot's tires, I did little more than start off by reading the existing resources on Javalobby:

Then I hacked together Pivot's humble Hello World scenario. Here's the code:

package pivot.tutorials;

import pivot.collections.Dictionary;
import pivot.wtk.Application;
import pivot.wtk.Component;
import pivot.wtk.Display;
import pivot.wtk.Window;
import pivot.wtkx.WTKXSerializer;

public class HelloJava implements Application {
   
    private Window window = null;

    public void startup(Display display, Dictionary<String, String> properties) throws Exception {
        WTKXSerializer wtkxSerializer = new WTKXSerializer();
        Component content = (Component) wtkxSerializer.readObject("pivot/tutorials/hello.wtkx");
        window = new Window();
        window.setContent(content);
        window.setMaximized(true);
        window.open(display);
    }

    public boolean shutdown(boolean optional) {
        window.close();
        return true;
    }

    public void suspend() {
    }

    public void resume() {
    }
   
}

 

Worth noticing here is the fact that we have an application class, provided by 'pivot.wtk.Application'. Clearly, that class handles the lifecycle of our application. That's exactly the kind of thing one would expect from a framework. We also have a Window object, with a lot of interesting looking methods:

Notice how a file is referred to in line 16 above. Here's what that file looks like:

<?xml version="1.0" encoding="UTF-8"?>

<Label text="Hello WTKX!" styles=
"{font:'Arial bold 24', color:'#ff0000', horizontalAlignment:'center', verticalAlignment:'center'}"
xmlns:wtkx="http://pivot.dev.java.net/wtkx/2008" xmlns="pivot.wtk"/>

 

"Wait a minute!" you should now be thinking, if you're looking at all this for the very first time. "Are you defining a ui component in an XML file?" Yes, that's exactly what's going on here. Forget Swing, forget SWT. Pivot is a seriously radical framework—a typical framework is less daring than this one, because typically a framework offers application-level innovations. Pivot does that, too. But, fundamentally, Pivot offers widget-level innovations, i.e., an entire new toolkit, in the same space as Swing and SWT.

Here's an IDE view on the above, first in IntelliJ and then in NetBeans IDE, showing the above two files together with the required Pivot JARs:


Not all these JARs are required for this simple sample, but these are all the JARs that will be needed in all cases, since these JARs constitute the entire Pivot distro. In the latter case, i.e., NetBeans IDE, I used this Ant script to run the application:

<target name="run" depends="jar">
    <property file="nbproject/project.properties" />
    <java classpath="${run.classpath}" classname="pivot.wtk.DesktopApplicationContext">
        <arg value="pivot.tutorials.HelloJava"/>
    </java>
</target>


Cool. Then run the application and you have this simple result:


OK. Let's now get a bit further and look at one of the cool samples that comes with the distro:

For this, our application is structured as follows:

Here's the content of 'reflection.wtkx':

<?xml version="1.0" encoding="UTF-8"?>

<ImageView image="@IMG_0767_2.jpg"
    xmlns:wtkx="http://pivot.dev.java.net/wtkx/2008" xmlns="pivot.wtk"/>

And here's 'translucent.wtkx':
<?xml version="1.0" encoding="UTF-8"?>

<FlowPane orientation="vertical" styles="{horizontalAlignment:'justify'}"
    xmlns:wtkx="http://pivot.dev.java.net/wtkx/2008" xmlns="pivot.wtk">
    <Label text="A Translucent Window"/>
    <Border styles="{color:13, padding:0}">
        <content>
            <ListView listData="['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']"/>
        </content>
    </Border>
</FlowPane>

Finally, here's the Java source file:
package pivot.tutorials;

import pivot.collections.Dictionary;
import pivot.wtk.Application;
import pivot.wtk.Component;
import pivot.wtk.ComponentMouseListener;
import pivot.wtk.Display;
import pivot.wtk.Frame;
import pivot.wtk.Window;
import pivot.wtk.effects.FadeDecorator;
import pivot.wtk.effects.ReflectionDecorator;
import pivot.wtkx.WTKXSerializer;

public class DecoratorDemo implements Application {
    private Window reflectionWindow = null;
    private Frame fadeFrame = null;
   
    public void startup(Display display, Dictionary<String, String> properties)
        throws Exception {
        WTKXSerializer wtkxSerializer = new WTKXSerializer();

        reflectionWindow =
            new Window((Component)wtkxSerializer.readObject(
getClass().getResource("reflection.wtkx")));
        reflectionWindow.setTitle("Reflection Window");
        reflectionWindow.getDecorators().add(new ReflectionDecorator());
        reflectionWindow.setLocation(20, 20);
        reflectionWindow.open(display);

        fadeFrame =
            new Frame((Component)wtkxSerializer.readObject(
getClass().getResource("translucent.wtkx")));
        fadeFrame.setTitle("Translucent Window");

        final FadeDecorator fadeDecorator = new FadeDecorator();
        fadeFrame.getDecorators().update(0, fadeDecorator);

        fadeFrame.getComponentMouseListeners().add(new ComponentMouseListener() {
            public boolean mouseMove(Component component, int x, int y) {
                return false;
            }

            public void mouseOver(Component component) {
                fadeDecorator.setOpacity(0.9f);
                component.repaint();
            }

            public void mouseOut(Component component) {
                fadeDecorator.setOpacity(0.5f);
                component.repaint();
            }
        });

        fadeFrame.setLocation(80, 80);
        fadeFrame.open(display);
    }

    public boolean shutdown(boolean optional) {
        reflectionWindow.close();
        fadeFrame.close();
        return true;
    }

    public void suspend() {
    }

    public void resume() {
    }
   
}

 

Now, with the above fresh on your mind, here are the unique features in Pivot's ambit:

  • UI can be (but does not have to be!) done in XML. Click here for more

  • All logic is done in Java, so that there is a clear differentiation/separation between UI and logic. Click here for more.

  • There are several key pain points that Pivot tries to solve, in addition to the areas of UI design/composition pointed out above. These focus on facilitating interaction with modern technologies, such as JSON and REST. Firstly, web queries; secondly, data binding; (would be interesting to compare how this is done with the Groovy/Griffon approach); thirdly, localization.

The biggest thing one needs to get used to, in this context, is the XML markup (which, again, is optional). But I imagine some cool things flow from using this approach instead of Java. For example, no need to recompile when changes are made to the UI. Potentially, UI generators could also be simpler to implement if the output is simple XML rather than source code. Finally, before diving in yourself, I recommend reading the interview with Greg and Todd, Pivot's creators, and then taking a look through the excellent documentation, available here on-line, especially the tutorial.

 

AttachmentSize
pivot-fig-1.png86.02 KB
pivot-fig-2.png44.43 KB
pivot-fig-3.png87.91 KB
pivot-fig-4.png122.48 KB
pivot-fig-5.png4.92 KB
pivot-fig-6.png21.72 KB
Published at DZone with permission of its author, Geertjan Wielenga.