http://java.sun.com/ http://java.sun.com/javaone http://java.sun.com/javaone
JavaOne - ExperiencingJava technology through education, industry, and community
Home > 2008 JavaOne Conference: JavaFX Platform - Sexy Interfaces for Mere Mortals

2008 JavaOne Conference: JavaFX Platform - Sexy Interfaces for Mere Mortals

 
by Richard Marejka  

The noon-time session presented by Joshua Smith provided some impressive examples of JavaFX technology. Joshua, a developer working in the aerospace and defense industry, has more than 9 years of Java development experience and has been working with JavaFX since its introduction at JavaOne last year.

The session was a practical look at what can be done with JavaFX, but more importantly, how it can be done. All the code is available and references to other information sources were provided at the session wrap-up.

Joshua prefaced the session with the prerequisites -- an understanding of Java, but elite-level experience with Swing or the Java 2D API was not required. It was not an overview of JavaFX, a comparison of JavaFX with technology such as Silverlight and Flash, or a language tutorial. Those topics are covered elsewhere at JavaOne. This was a practical demonstration of JavaFX, what it can do, and the idioms required to build a compelling GUI.

The first question was "Why do we need JavaFX?". The perception is that Swing and the Java 2D APIs are too difficult to use. The reality may be not that they are too difficult to use, but that they are too time-consuming to use. Too much boilerplate is just more code to support, more places to introduce errors, and hence the potential for more bugs.

JavaFX provides the features to make building the "rich client application" easier. Personally, I'm getting tired of that phrase, it's becoming the equivalent of "Web 2.0", but it's all we have for now. My issue is that it degrades previous efforts, which given the technology and tools, were often superlative. JavaFX offers the following advantages over Java SE technology:

  • Binding model variables to visual effects is built-in
  • Animation is built-in, time is first class type
  • Effects are built-in
  • Ability to utilizie Java classes and methods
  • Declarative language - the developer specifies what to be done, not how
  • Strongly typed, but type is inferred
  • Designed to be the same technology and tools on desktop, web, and mobile platforms

Joshua gave the standing room only crowd four demos, each presented and then decomposed into code snippets for analysis. The first was a spin on The Matrix -- that well-known sequence of characters running vertically down the screen, collapsing to a line, and finally a point. Since this was the first demo, it covered a lot of elements that were used in later demos. One of the first things of note about JavaFX is the lack of a main method -- code outside the outermost class definition is the main -- sort of a variation on BASIC or Pascal. I remembered that Chris Oliver stated in an earlier session that JavaFX borrows heavily from other languages, not just Java. This was just the first example of such borrowing.

Matrix numbers screen

In JavaFX there are two UI contexts -- Canvas, which is populated with nodes, and Swing, which is populated with Components. The easiest way to create new nodes is to extend the JavaFX CustomNode. A later release of JavaFX will offer something similar for Components. With this information, Joshua launched into the specifics of the Matrix demo. First up was Clip -- a Clip uses a shape to view underlying content similar to overlaying a stencil on an image.

Winter Clip

It is an idiom using an ImageView consisting of an image and a clip, as simple as:

ImageView {
	image: Image { ... }
	clip: Text{ ... }
}

The next item from the Matrix demo was the JavaFX bind keyword. The bind keyword will find pervasive use within JavaFX applications. It is used to associate one or more variables such that when one changes, the effect is propagated to all bound items. This is similar to PropertyChangeEvents and PropertyChangeListeners in Java. This was illustrated in a simple example that dynamically changed the number of points on a star. For example, the statements in bold are all that is required to enable the slider value to control the number of points.

Star with slider control

class StarModel {
	public attribute points : Integer;
}

public class BindingStar extends CompositeWidget {
	private attribute slider : Slider;
	private attribute starModel : StarModel;

	init {
		starModel = StarModel {
			points : bind slider.value as Integer
		};

	}

	public function composeWidget() : Widget {
		BorderPanel {
			center :
			Canvas {
				content :
				Star {
					...
					points: bind StarModel.points
				}
			}
	
			bottom :
			slider = Slider {
				...
				value : 5
			}
		}
	}

}

Binding is not a 1:1 operation, it can occur between any number of variables.

The final step in the Matrix demo was to define KeyFrame animation. A keyframe "defines the starting and ending points of a smooth transition" (Wikipedia). For the JavaFX developer, this means defining the value of variables at the start and end point of the transition, and defining how the values are to be interpolated. KeyFrame is commonly thought of as a way to implement a visual animation, but it can also be used for non-visual elements. For instance, audio volume can be animated over a keyframe. The type of interpolation can be selected from a pre-defined set, or the developer can define their own interpolation function by using a subclass.

The animation syntax that Joshua presented was based on the latest JavaFX SDK, a great improvement over the previous iteration.

var xValue = 75;

var animation = Timeline {
	toggle : true;
	keyFrames : [
		KeyFrame {
			time : 0s
			values : xValue => 75
		},
		KeyFrame {
			time : 2s
			values : xValue => 425 tween Interpolator.LINEAR
		},
	]
};

Circle {
	centerX : bind xValue
	centerY : 90
	radius : 50
	...
	onMouseClicked : function( e : CanvasMouseEvent ) {
		animation.start();
	}
}

JavaFX mouse events are written as an association between a mouse event-related attribute in a node and a function to be performed on reception of the event. This is illustrated above as part of the animation example.

With this final snippet complete, the entire Matrix demo was strung together to create the final product -- the familiar Matrix "numbers" screen.

The second demo was a Peephole animation -- a circular peephole follows mouse movement over a larger image. A mouse click reveals the entire image. The feature illustrated with this demo was morphing -- changing one shape into another over some time period. This is accomplished by defining the start and end shapes along with a current shape variable:

Peephole before

Peephole after

var startingShape = Circle {
	...
};

var endingShape = Rectangle {
	...
};

var currentShape:Shape = startingShape;

The morph is specified using a keyframe animation -- no surprise:

var animation = Timeline {
	toggle : true;
	keyFrames : [
		KeyFrame {
			time : 0s
			values : currentShape => startingShape
		},
		KeyFrame {
			time : 2s
			values : currentShape => endingShape tween Interpolator.LINEAR
		}
	]
};

Lastly, a class is defined to handle the mouse input that initiates the morph:

DelegateShape {
	shape : bind currentShape
	fill : Color.ORANGE
	onMouseClicked : function( e : MouseEvent ) {
		animation.start();
	}
}

Joshua assembled these snippets along with snippets from the Matrix demo, appropriately modified to complete demo #2.

The penultimate demo provided an example of handling keyboard input on a Canvas. Joshua had crafted a very nice looking phone icon

Phone applicaiton icon

that when clicked, morphed into a full phone keypad.

Phone application keypad

The only code snippet for the demo was to illustrate how to capture keyboard input and display the character on a Canvas. First was an extension to CustomNode to manage the letter and input.

J on a Canvas

public class CanvasKeyboardEvents extends CustomNode {
	private attribute currentLetter = "?";

	public function create() : Node {
		Text {
			...
			content : bind currentLetter
		}
	}

	init {
		onKeyTyped = function( e : KeyEvent ) {
			currentLetter = e.getKeyChar();
		};
	}
}

Of note is the bind of the current letter attribute to a Text attribute -- when a new key is pressed, the displayed character should change. The usage of onKeyTyped with function is similar to the previously demonstrated mouse event handling idiom.

The final step is to define a frame with an enclosed Canvas. Several attributes are set, but it is only enabling for keyboard focus that is the important item.

Frame {
	closeAction : function() { System.exit( 0 ); }
	...
	content :
	Canvas {
		content :
		CanvasKeyboardEvents {
			focused : true
		}
	}
	visible : true
}

Joshua's last demo was a slideshow which drew from the previous demos to create a photo album slideshow. He was able to provide at least a half-dozen transition styles. Each transition was approximately 2 pages of JavaFX Script, largely boilerplate, with a a few lines of transition-specific code.

In his wrap, Joshua highlighted a few key points:

  • JavaFX is close to Java, but there are a number of other language influences present
  • JavaFX is much easier then Swing and Java 2D
  • Writing in JavaFX Script reduces the amount of code and saves time
  • The same language and tools will cover "3 screens" - desktop, browser and mobile devices

Look for the JavaFX SDK to be available in July 2008.

I'd like to thank Joshua who provided draft versions of his presentation before the conference and then cut a disc immediately after his presentation ensuring that I had the final version. He also made himself available to answer to quesitons via e-mail before the conference.

References

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.