Tag Archives: gadgets

JavaOne 2013 BOF2605 JavaFX, Widgets, and Apps, Oh My! Launching Frameworks for Platforms Large and Small

Image

Multipurpose widget called KeyHole displaying maps and the weather.

Introduction

This is probably the longest title I’d ever create for a blog entry.

In my spare time I’ve been working with Mark Heckler(The Java Jungle), Hendrik Ebbers (GuiGarage), and Gerrit Grunwald (Harmonic Code) on the idea of application launching frameworks. We will be presenting two approaches to running widgets and applications on the desktop and embedded device (Raspberry Pi) environments. The talk will be a BoF (Birds of a feather) session at JavaOne 2013 (BOF2605). This is where the Java/JavaFX community will have lots of fun demoing, discussing and sharing ideas on topics such as:

  • Application Containers / Dashboards
  • Widgets/Apps/Games/Gadgets
  • Widget/App Development workflow
  • Widget/App life cycle
  • Deployment / App stores

To see a sneak preview of Hendrik Ebbers’ implementation of a Roku-AppleTV-like application container check out his blog entry herehttp://www.guigarage.com/2013/08/boxfx-javaone-preview-1/ The application container is called BoxFX.

Mark and I have been working on an implementation of a desktop-centric application container called TrayFX. To see a sneak preview of TrayFX visit an interview with Mark Heckler hosted by Stephen Chin. Another sneak preview of TrayFX in action is on my youtube channel herehttp://www.youtube.com/watch?v=x_KLIzVSiu8 and http://www.youtube.com/watch?v=WwzwsGxd-Jk

In this blog entry I will discuss some high level concepts relating to the framework eWidgetFX and the application container TrayFX. Since there is a lot to digest I would like to at least (briefly) show you each layer in the architecture.

Disclaimer: BoxFX and TrayFX are currently private APIs. Both approaches have similarities, however they are independent projects. It’s important to hear from the audience for potential use cases. They eventually will wind up as open source projects. Also, leading up to the JavaOne talk some diagrams or APIs are subject to change in this blog entry.

eWidgetFX

eWidgetFX is a core library (API) that widgets and app containers will depend on.  Shown below depicts the layers:

High Level Architecture of the core widget framework

Core widget framework API that widgets and widget containers depend on.

The APIs provide services for loading widgets, widget life cycles, and utilities for the widget developer. The main idea was to provide a cross platform application API for application container developers and widget developers to coexist. In fact the goal was to have cross platform widgets & apps capable of running on any app container (based on the eWidgetFX lib).

Application Containers (TrayFX)

TrayFX is an App Container instance that depends on the core widget framework (eWidgetFX). Shown below is the middle layer which is basically different custom application containers based on the core.

High Level Architecture depicting App Containers layer.

Application Containers depend on the eWidgetFX API (core). This allows developers to build their own custom application containers.

TrayFX is an App Container instance that depends on the core widget framework (eWidgetFX). This means that you to can develop your own JavaFX widget & app container of your liking if you don’t like TrayFX 🙂 For instance you could create one for a tablet device which may have different UI metaphors and varied screen sizes (real estate). Shown below is TrayFX launching a clock widget (on the Desktop).

TrayFX launching a clock widget.

A clock widget launched from TrayFX

Widgets

Widgets or Apps are either standalone applications or eWidgetFX based widgets that can be run inside of a application container. Shown below is the widgets layer:

High Level Architecture of the Widgets layer

Widgets are mini-applications that can launch standalone or launch inside a widget container such as TrayFX.

When creating widgets you can implement a Widget interface or you can extend from the abstract DefaultWidget adapter class overriding optional life cycle methods as a convenience to the developer. Shown below is a high level class diagram:

A hello world widget class extending from the eWidgetFX default widget class.

Widget’s Class Diagram using the eWidgetFX core library.

In the JavaOne BoF  (BOF2605) since the framework is still very alpha during the talk we will present a possible developer workflow to create, build, deploy, and launch widgets.  Below I would like to share a small bit of code to give you an idea of how easy it is to implement a widget on the eWidgetFX platform.

Usually, application launching frameworks have life cycles for the application containers to manage widgets & apps. Widget developers will not need to implement a Stage nor a Scene and basically focus on what they know best (their JavaFX widget as a Node). The framework APIs will allow you to interact with the JavaFX parent containers such as Stage and Scene. The eWidgetFX Widget interface is shown below which has methods that a widget developer would need to implement. For brevity please look at the comments on the methods to understand the basic widget life cycle.

package org.ewidgetfx.core;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

/**
 * User: cdea
 * Date: 4/7/13
 */
public interface Widget {
    public static enum DECORATION {
        STAGED_OS_TITLE_BAR,
        STAGED_CLOSE,
        STAGED_CONFIG_CLOSE,
        STAGED_CONFIG,
        STAGED_UNDECORATED,
        NON_STAGED_CLOSE,
        NON_STAGED_CONFIG_CLOSE,
        NON_STAGED_CONFIG,
        NON_STAGED_UNDECORATED
    };

    DECORATION getDecoration();
    void setDecoration(DECORATION decoration);

    String getName();
    void setName(String name);
    StringProperty nameProperty();

    String getVersion();
    void setVersion(String version);
    StringProperty  versionProperty();

    String getDescription();
    void setDescription(String descr);

    String getVendor();
    void setVendor(String vendor);

    String getVendorUrl();
    void setVendorUrl(String vendorUrl);

    String getVendorEmail();
    void setVendorEmail(String vendorEmail);

    LaunchInfo getLaunchInfo();
    void setLaunchInfo(LaunchInfo launchInfo);

    WidgetIcon getWidgetIcon();
    void setWidgetIcon(WidgetIcon widgetIcon);
    ObjectProperty widgetIconProperty();

    Pane getAsNode();
    Stage getParentStage();
    void setParentStage(Stage stage);

    WidgetState getWidgetState();

    /**
     * Returns a created WidgetIcon for the app container to use. Called 1st.
     * @return WidgetIcon containing a raw node representing the icon. App containers can resize.
     */
    WidgetIcon buildWidgetIcon();

    /**
     * Called after buildWidgetIcon() method to allow background processes to occur. Called 2nd.
     * Typically to collect data to update WidgetIcon's Icon overlay. An example would be
     * an email widget periodically checking email to update Icon overlay the number of emails received.
     */
    void startBackground();

    /**
     * Initialize the widget. If the developer calls this method the framework will not call it. Called 3rd.
     */
    void init();

    /**
     * Start is meant to be called when the user clicks the icon to launch widget. Called 4th.
     * Typically to start animations or position on the desktop. This should not be confused with startBackground()
 */
 void start();

 /**
 * Pause is typically used to pause animations. Or other developer defined resources.
 */
 void pause();

 /**
 * Resume is typically used to resume a animations. Or other developer defined resources.
 */
 void resume();

 /**
 * Stop is called when the widget is closed and not visible. Typically this is to stop animations, and minor cleanup.
 * The framework will call stop and stopBackground() method when exiting the app container.
 */
 void stop();

 /**
 * Stops any background processes. Called when widget is being closed by the framework when exiting app contain. Called last.
 *
 */
 void stopBackground();

}

Conclusion

While building this framework we kept coming up with more features and ideas, however with very little time left we still were able to provide common capabilities that you’ve grown to love on your device. Hopefully, this will whet your appetite before you attend the BoF at JavaOne.

All are welcome! Enjoy!

Carl