• Save
BeJUG JavaFx In Practice
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

BeJUG JavaFx In Practice

on

  • 4,851 views

These are the slides from the 'JavaFX in practice' session by Jo Voordeckers of Pursuit Consulting at BeJUG, 27th of May 2009 in Ghent, Belgium

These are the slides from the 'JavaFX in practice' session by Jo Voordeckers of Pursuit Consulting at BeJUG, 27th of May 2009 in Ghent, Belgium

Statistics

Views

Total Views
4,851
Views on SlideShare
4,687
Embed Views
164

Actions

Likes
3
Downloads
0
Comments
2

6 Embeds 164

http://javatrack.blogspot.com 89
http://blog.pursuit.be 50
http://www.slideshare.net 16
http://www.linkedin.com 5
http://translate.googleusercontent.com 3
http://2194501260274521490_678ded16cdf6e9789fb95935a3335e570feed13d.blogspot.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Thanks, it's for JavaFX 1.1 though, will update it soon for JavaFX 1.2 released last week.
    Are you sure you want to
    Your message goes here
    Processing…
  • Excellent introduction. Very useful compilation of most important features. Thanks for that.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

BeJUG JavaFx In Practice Presentation Transcript

  • 1. JavaFX in practice Jo Voordeckers jo.voordeckers@pursuit.be Thursday 28 May 2009 1
  • 2. About the speaker ‣ 2002 .. 2005 - Partner at Imagine-IT ‣ 2006 .. 2007 - Senior Software Engineer at Dolmen ‣ 2007 .. 2008 - Technical Project Leader at Dolmen ‣ 2008 - Founder Pursuit Consulting ‣ Independent Java EE and RIA contractor & consultant ‣ Speaker at: ‣ JavaOne, Devoxx, BeJUG, IT Works, SAI Thursday 28 May 2009 2
  • 3. Agenda ‣ Introduction ‣ Applying all the above ‣ JavaFX Script Language ‣ Media ‣ Scene graph ‣ Remote Services ‣ JavaFX Production Suite ‣ Browser Integration ‣ Styling ‣ Deployment ‣ Animation ‣ Tips and tricks ‣ Transformations ‣ Future of JavaFX ‣ Effects ‣ References ‣ Clipping ‣ Q&A Thursday 28 May 2009 3
  • 4. JavaFX Platform Thursday 28 May 2009 4
  • 5. JavaOne’08 keynote demo ParleysFX Thursday 28 May 2009 5
  • 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
  • 23. Node’s most interesting properties ‣ transforms or: ‣ hover ‣ translateX/Y ‣ onMouseXXX ‣ scaleX/Y ‣ onKeyXXX ‣ rotateX/Y ‣ boundsInLocal, boundsInParent, boundsInScene ‣ effect ‣ blocksMouse ‣ visible ‣ clip ‣ opacity ‣ id ‣ cache ‣ styleClass Thursday 28 May 2009 23
  • 24. CustomNode public class MyButton extends CustomNode { override public function create():Node { Group { content: [ Rectangle { width: 200, height: 40, arcHeight: 10, arcWidth: 10 fill: LinearGradient { startX: 0, endX: 0, startY: 0, endY: 1 stops: [ Stop { color: Color.BLACK, offset: 0 }, Stop { color: Color.BLUE, offset: 1 }, ] } }, Text { x: 100, y: 10, textOrigin: TextOrigin.TOP content: quot;Buttonquot; fill: Color.WHITE, textAlignment: TextAlignment.CENTER } ] } } } Thursday 28 May 2009 24
  • 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
  • 33. Media support Thursday 28 May 2009 33
  • 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
  • 42. JFXtras JSONHandler ‣ Glassfish v2 + Jersey JAX-RS Sample (with CustomerDB) ‣ Implement JavaFX counterpart of Java entities ‣ Implement JSONHandler ‣ Call JSONHandler.parse(); var customers:Customer[]; def handler:JSONHandler = JSONHandler { url: quot;http://localhost:8080/CustomerDB/resources/customers/quot; rootClass: quot;jaxrs.CustomerResultquot; onDone: function(result:Object, isSequence:Boolean) { customers = (result as CustomerResult).customer; } } Thursday 28 May 2009 42
  • 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
  • 48. Q & A Thursday 28 May 2009 48