6. Java’s issues as RIA platform
‣ Slow
‣ 10 - 30s for cold startup
‣ graphic performance
‣ applets often crash browser
‣ Difficult
‣ Java2D
‣ Swing - MVC (without binding & properties)
‣ Dated look & feel
‣ No built-in animation, effect
‣ No decent media support
‣ 10MB Plugin
Thursday 28 May 2009 6
7. The answer to RIA on the JVM
‣ Java 6u10 ‣ JavaFX
‣ Browser Plugin v2.0 ‣ JavaFX Scripting language
‣ Hardware rendering ‣ Keyframe Animations
‣ Modularized Java Runtime ‣ Effects
‣ Quick-starter ‣ Media Codecs
‣ Designer tools
Thursday 28 May 2009 7
8. Declarative and procedural
‣ JavaScript Object literal Notation (JSON)
‣ Java like procedural syntax
Stage {
title: quot;BEJUG DEMOquot;
scene: Scene {
width: 200
height: 200
def t:Text = Text {
x: 50
y: 50
content: quot;Click Mequot;
onMouseClicked: function(e) {
service.registerClick();
t.content = quot;Thanks!quot;;
}
}
content: t
}
}
Thursday 28 May 2009 8
9. Data types
JavaFX Java
String java.lang.String
Boolean java.lang.Boolean
Number java.lang.Number
Integer java.lang.Integer
Object java.lang.Object
Void java.lang.Void
Duration -
var s:String = “hello”;
var b:Boolean = true;
var n:Number = 0.4;
var i:Integer = 99;
var o:Object = new java.util.Date();
var d:Duration = 10ms;
Thursday 28 May 2009 9
10. Defining variables
‣ var
‣ defines a regular variable
‣ def
‣ defines a constant variable through initial assignment
‣ value can change through binding!!
‣ Statically typed
‣ Compiler can infer the type
var result;
def numOne = 100;
def numTwo = bind result;
Thursday 28 May 2009 10
11. Access modifiers
JavaFX script, variable, function access modifiers
Default, script read/write
Package, package read/write
Protected, package + subclass read/write
Public, read/write from anywhere
Public-read, read from anywhere, write from script by default, combine with
package or protected
Public-init, public-read + init from anywhere
var s:String = quot;defaultquot;;
package var s:String = quot;packagequot;;
protected var s:String = quot;protectedquot;;
public var s:String = quot;publicquot;;
public-read var s:String = quot;public-readquot;;
protected public-read var s:String = quot;protected write
public-readquot;;
public-init var s:String = quot;public-initquot;;
Thursday 28 May 2009 11
12. Sequences
‣ Dynamic array
‣ Powerful list comprehension and manipulation
for (fooItem in foos where fooItem.bar == true) {
var i = indexof fooItem;
println(“Foo with bar at index {i} of {sizeof foos}”);
}
foosWithoutBar = foos[foo|foo.bar == false];
// Creates new sequence based on the condition
insert foo in foos; // Insert object foo into sequence
insert bar before foos[3]; // Insert object bar at position 4
delete foos[0]; // Remove the first object from sequence
reverse foos; // Reverses the objects in foos
Sequences.sort(foos); // Equivalent of java.util.Collections
Thursday 28 May 2009 12
13. Functions & closures
‣ Executable block of code
‣ Return value from last expression (Void)
‣ First-class objects: “closures”
‣ Bound - Function
public class FilterableList {
public-init var list:Object[];
public function filter(predicate : function(o:Object):Boolean) {
list = list[item|predicate(item)];
}
}
function run(__ARGS__ : String[]) { } // Java main() equivalent
Thursday 28 May 2009 13
14. Multiple Inheritance
‣ No interfaces, use abstract classes
‣ JavaFX class can extend multiple JavaFX classes
‣ ** will get replaced by mixins in the near future
‣ JavaFX class can implement multiple Java interfaces
‣ JavaFX class can extend 1 Java class (no varargs, enums, generics)
public abstract class Clickable extends CustomNode {
public abstract function onClick():Void;
}
public class ListBox extends AbstractList, Clickable {
// TODO implement java.util.AbstractList.get(),
// Clickable.onClick(), CustomNode.create()
}
Thursday 28 May 2009 14
15. Binding
‣ Bi-directional binding (with inverse)
var x:Integer;
Stage {
title : quot;BEJUG DEMOquot;
scene: Scene { width: 400, height: 200
content: [
Text { x: 20 y: 20
content: bind quot;Location X = {x}quot;
},
Rectangle { width: 20 height: 20 fill: Color.BLUE
x: bind x
y: 50
onMouseDragged: function(e:MouseEvent) {
x = (e.dragAnchorX + e.dragX as Integer) - 10;
}
}
]
}
}
Thursday 28 May 2009 15
16. Bound functions
var x:Integer;
bound function percentage():Integer {
x * 100 / s.width as Integer;
}
var s:Stage = Stage {
title : quot;BEJUG DEMOquot;
scene: Scene { width: 400, height: 200
content: [
Text { x: 20 y: 20
content: bind quot;Location X = {x}, % = {percentage()}quot;
},
Rectangle { width: 20 height: 20 fill: Color.BLUE
x: bind x, y: 50
onMouseDragged: function(e:MouseEvent) {
x = (e.dragAnchorX + e.dragX as Integer) - 10;
}
}
]
}
}
Thursday 28 May 2009 16
17. Triggers
var x:Integer on replace oldVal {
if (x < 25) { x = 25; }
else if (x > 75) { x = 75; }
};
Stage {
title : quot;BEJUG DEMOquot;
scene: Scene { width: 400, height: 200
content: [
Text { x: 20, y: 20, content: bind quot;Location X = {x}quot; },
Rectangle { width: 20, height: 20, fill: Color.BLUE
x: bind x, y: 50
onMouseDragged: function(e:MouseEvent) {
x = (e.dragAnchorX + e.dragX as Integer) - 10;
}
}
]
}
}
Thursday 28 May 2009 17
18. Bind for
class CoolList extends CustomNode {
public var list:String[];
override public function create():Node {
Group {
content:
bind for (item in list) Group {
translateY: 25 * indexof item
content: [
Rectangle {
fill: Color.BLUE
width: bind s.width
height: 20
},
Text { x: 10, y: 15, content: item }
]
}
}
}
}
var s:Stage = Stage { title : quot;BEJUG DEMOquot;
scene: Scene { width: 400, height: 200
content: CoolList { list: [ quot;Firstquot;, quot;Secondquot;, quot;Lastquot; ] }
}
}
Thursday 28 May 2009 18
19. Init and postinit
‣ No support for constructors
‣ Closest equivalent: optional init and postinit function blocks
‣ ** postinit might get removed in future releases
public class MyControl extends Control {
public var myVar:Number;
override var skin = MyControlSkin{};
// initialized before myVar
}
public class MyControl extends Control {
public var myVar:Number;
postinit {skin = MyControlSkin{}; }
// initialized after myVar
}
Thursday 28 May 2009 19
20. Exceptions - throw, try, catch, finally
‣ JavaFX support Java exceptions
if (foo == null)
throw new RuntimeException(“Foo is null”);
try {
connectAndDisplayShoppingList();
} catch (e: Exception) {
showErrorMessage(e);
} finally {
closeConnection();
}
Thursday 28 May 2009 20
21. Magic variables
‣ __ARGS__ command line arguments
‣ function run(__ARGS__ : String[]): java.lang.Object { }
‣ __DIR__ Java URI to the directory of the current script
‣ __FILE__ Java URI to the current script (class file)
‣ __PROFILE__ Profile the runtime is using:
‣ desktop, mobile, browser
‣ Often used to reference packaged (JAR) resources
‣ Image { url: quot;{__DIR__}images/close.pngquot; } cache: true }
Thursday 28 May 2009 21
22. Getting started SceneGraph
‣ Stage - Hybrid Application and/or Applet container
‣ Style (Shaped Windows)
Group
‣ Opacity
‣ Applet drag events
Overview Presentation
‣ Position & Size Panel ViewPanel
‣ Title
‣ Close-action Collapsible
Panel
‣ Scene - Root of the scene graph
‣ “Graph data structure that holds
Left Right Collapse
Splitter
‣ Container Container Button
the spatial representation (Group) (Group)
(Rectangle)
(Shape)
‣ of the graphical scene”
TopLists Presentations
Panel Panel
(HBox) (HBox)
Thursday 28 May 2009 22
25. Production Suite
‣ Produces FXD files (FXZ = zipped)
‣ Adobe Photoshop plugin
‣ Adobe Illustrator plugin
‣ SVG to FXD converter
‣ FXD Viewer
‣ Integrate into JavaFX
‣ UIStub
‣ FXDLoader
Thursday 28 May 2009 25
26. JavaFX in style
Rectangle {
arcWidth: 10;
arcHeight: 10;
}
.bg {
fill: #ccccff;
stroke: #333399;
}
var stylesheets : String = “{__DIR__}default.cssquot;;
Stage {
scene: Scene {
stylesheets: bind stylesheets
}
}
Rectangle {
x: 10 y: 70 width: 200 height: 50 fill: Color.RED
styleClass: quot;bgquot;
}
Thread on forum has more details: http://forums.sun.com/thread.jspa?threadID=5357325&tstart=0
Thursday 28 May 2009 26
27. Animations
def t2 = Timeline {
‣ First class citizen in JavaFX autoReverse: true
repeatCount: 10
keyFrames: [
at (0s) {
‣ Key-frame based r2 => 0
},
‣ Interpolators at (1s) {
r2 => 150 tween
‣ Callback functions Interpolator.EASEBOTH
},
]
‣ Timeline can be nested!
};
‣ Interpolates: numbers, colors, shapes (morphing)
‣ + any class that extends Interpolatable !!
Thursday 28 May 2009 27
28. Transformations
‣ Affine transformations supported on all Node objects
‣ Translate
‣ Rotate
‣ Scale
‣ Shear
‣ PerspectiveTransform
‣ NOT an affine transform!
‣ @see Effects
Thursday 28 May 2009 28
29. Effects
‣ One or more inputs (Effect chaining)
‣ Effect Types
‣ Reflection
‣ PerspectiveTransform Text {
effect: Reflection {
‣ Glow input: MotionBlur { angle: 180 }
}
‣ Blur translateX: 20
translateY: 20
‣ DropShadow content: quot;BeJUG JavaFX in practicequot;
fill: Color.RED
font: Font { name: quot;Verdanaquot;, size: 20 }
‣ ColorAdjust
},
‣ @see JavaFX.com EffectsPlayground DEMO by Chris Campbell
Thursday 28 May 2009 29
30. Clipping
‣ Think “digital scissors”
‣ Intersection of clip shape
‣ and Node defines the visual
‣ portion of the Node
‣ Often used to slide a group of Nodes out of the scene
Rectangle {
width: 100, height: 100
fill: Color.BLUE
clip: Circle {
centerX: 75, centerY: 75, radius: 50
}
}
Thursday 28 May 2009 30
31. Building a website menu
‣ Combines following JavaFX functionality
‣ Binding
‣ For-each
‣ CustomNode
‣ Timeline
‣ KeyFrames
‣ Interpolators
‣ Effects
‣ DropShadow
‣ Node Clipping
Thursday 28 May 2009 31
32. Media in JavaFX
‣ Easy to play video and audio content
‣ MediaView
‣ Effects, Transformations, Animations, Clipping
‣ MediaPlayer
‣ Streaming, progressive download, buffering, seeking, ...
‣ There is a business case for media!
Thursday 28 May 2009 32
34. MediaPlayer in 10 lines
‣ MediaPlayer - Controller
‣ MediaView - View
‣ Media - Model
‣ Don’t use {__DIR__} media playing from JAR URI’s not supported!
def mp:MediaPlayer = MediaPlayer {
media: Media { source: quot;file:/path/to/movie.movquot; }
}
content: [
MediaView { mediaPlayer: mp, fitWidth: 400, fitHeight: 200
onMouseClicked: function(e) {
if (mp.status == mp.PLAYING) mp.stop() else mp.play();
}
},
]
Thursday 28 May 2009 34
35. Browser integration
‣ JavaScript calling into JavaFX
public function setColor(red: Number, green: Number, blue: Number) : Void {
color = Color { red: red, green: green, blue: blue };
}
public function run(args: String[]) {
Stage {
scene: Scene {
fill: Color.DARKGRAY
content: [
Circle {
centerX : 125
centerY : 125
radius: 100
fill: bind color
}
]
}
}
}
var app = document.getElementById(quot;myAppletquot;);
app.script.setColor(1.0, 0.0, 0.0);
Thursday 28 May 2009 35
36. Browser integration
‣ JavaFX calling into JavaScript
‣ DOM manipulation through org.w3c.dom.html.HTMLDocument
import javafx.stage.AppletStageExtension;
// Show a document in a new browser window
AppletStageExtension.showDocument(quot;http://my.company.com/quot;);
// Show a document in a frame of the current browser window
AppletStageExtension.showDocument(quot;http://my.company.com/quot;, quot;LEFT_FRAMEquot;);
AppletStageExtension.eval(quot;someJavaScriptFunction()quot;);
var window: netscape.javascript.JSObject =
FX.getArgument(quot;javafx.appletquot;) as netscape.javascript.JSObject;
// Now can interact with the JSObject APIs and call JavaScript
// functions, etc. defined in the window scope
Thursday 28 May 2009 36
37. JavaFX Application Architecture
JavaFX Controls and Components
Models (JavaFX or Java)
Controller (JavaFX or Java)
Communication Layer (JavaFX or Java)
Façade exposing the Services
Enterprise Services (Spring beans / EJB)
Database or Integration Layer
Thursday 28 May 2009 37
38. Remote Services
‣ RemoteTextDocument
‣ PullParser
‣ Restful XML & JSON services
‣ Support linear mode forward, seek, …
‣ JFXtras - http://jfxtras.org/
‣ JSONHandler
‣ JFXWorker
‣ Whatever you like as long as it runs on the JVM!
Thursday 28 May 2009 38
39. RemoteTextDocument
‣ Fetches remote document asynchronously in a String
‣ document
‣ done
‣ failed
‣ canceled
var remoteTextDocument:RemoteTextDocument = RemoteTextDocument {
url: quot;http://api.flickr.com/services/feeds/photos_public.gnequot;;
}
var doc:String = bind remoteTextDocument.document on replace {
if (remoteTextDocument.done)
java.lang.System.out.println(quot;doc = {doc}quot;);
}
Thursday 28 May 2009 39
40. PullParser with XML
override function onPullEvent(event : Event) : Void {
if (quot;Resultquot;.equals(event.qname.name) and event.level == 1) {
total = event.getAttributeValue(
QName{name:quot;totalResultsAvailablequot;});
}
}
def pullParser = PullParser {
documentType: PullParser.XML;
onEvent: onPullEvent
}
def httpRequest : HttpRequest = HttpRequest {
method: HttpRequest.GET
location: “http://url.to/service”
onInput: function(is: InputStream) {
try {
pullParser.input = is; pullParser.parse();
} finally { is.close(); }
}
}
httpRequest.enqueue();
Thursday 28 May 2009 40
41. JFXtras JFXWorker
‣ Leverages SwingWorker for background task execution
‣ desktop profile
‣ Required when not using JavaFX asynchronous API’s!
‣ Call into any Java communication API or library
‣ JAX-*
var listData:Object;
‣ Java RMI def myWorker = JFXWorker {
‣ Spring Remoting / WS inBackground: function():Object {
return service.call();
}
‣ AMF onDone: function(result:Object) {
listData = result;
}
}
myWorker.start();
Thursday 28 May 2009 41
43. Deployment
‣ Deployment toolkit
‣ JavaScript library hosted at java.com
‣ Autodetects & installs correct Java version
<html>
<script src=quot;http://java.com/js/deployJava.jsquot;></script>
<script>
var attributes = {codebase:'http://yourdomain.com/YourApplet',
code:'javafx.application.Applet.class',
archive:'YourApplet.jar, javafxrt.jar, Scenario.jar, javafxgui.jar’,
width:500, height:500, java_arguments:'-Djnlp.packEnabled=true'};
var parameters = {quot;ApplicationClassquot;: quot;com.yourdomain.YourAppletquot;,
quot;draggablequot;:quot;truequot;};
var version = '1.6.0' ;
deployJava.runApplet(attributes, parameters, version);
</script>
</html>
Thursday 28 May 2009 43
44. JNLP
‣ Since 6u10 also for applets
‣ Library dependencies
‣ eg: JavaFX runtime
‣ Runtime settings
‣ Memory
‣ Commandline arguments
‣ Native libraries
‣ Security settings
‣ Escape browser sandbox
Thursday 28 May 2009 44
45. Tips and tricks
‣ Wrap custom components in a ‣ Pre-scale Images
Group ( Image.width, Image.height )
‣ Comment logical parts of the ‣ Background loading
SceneGraph
‣ Integer instead of Number
‣ Avoid unnecessary bindings
‣ Use javafx.util.Sequences
‣ Cache complex components
( Node.cache: true ) ‣ Use Java code for the heavy
lifting
‣ Transparent Rectangle to
capture mouse events ‣ Avoid the non-common profile
classes (eg: Swing components)
‣ Small Scene graph
Thursday 28 May 2009 45
46. What to expect
‣ JavaFX 1.5 (released at JavaOne ’09)
‣ Skinnable native JavaFX components (common profile)
‣ JavaFX “Designer’s Tool”
‣ JavaFX Runtime improvements (bugs, performance, documentation)
‣ Netbeans plugin improvements (bugs and features)
‣ Java App Store (aka Project Vector)
‣ Future
‣ Mixins instead of multiple inheritance
‣ Mac OS X Java 6 “update 10”
‣ Linux & Solaris media support!?
Thursday 28 May 2009 46
47. Resources
‣ http://JavaFX.com
‣ 50+ samples with source code
‣ Tutorials and JavaFX API’s
‣ Netbeans SDK with JavaFX
‣ JavaFX editor and sample applications
‣ JavaFX Production Suite
‣ http://JFXpert.com
‣ Many tutorials by “PRO JavaFX Platform” author Jim Weaver
‣ http://jfxstudio.wordpress.com
‣ 70+ samples from the community
Thursday 28 May 2009 47