Your SlideShare is downloading. ×
0
JavaFX Your Way
Building JavaFX Applications with Alternative Languages
Stephen Chin
GXS
steveonjava@gmail.com
tweet: @ste...
Meet the Presenters…
Steve Jonathan
2
Family Man
A reasonable facsimile of…
Motorcyclist
Challenge the Presenter…
Challenge the Presenter…
Disclaimer:
This is proof of
concept
THE FOLLOWING IS INTENDED TO OUTLINE ORACLE’S GENERAL
PRODUCT DIRECTION. IT IS INTENDED FOR INFORMATION
PURPOSES ONLY, AND...
Disclaimer #2:
This is code-heavy
Overall Presentation Goal
Demonstrate the future potential of the JavaFX platform.
Agenda
> JavaFX 2.0 Announcement
> JavaFX in Java
> Explore alternative languages
 JRuby
 Clojure
 Groovy
 Scala
 +???
JavaFX 2.0 Announcement
• JavaFX Script is no longer required to write
JavaFX applications
• Benefits:
– Easier integratio...
JavaFX With Java
JavaFX in Java
> JavaFX API follows JavaBeans approach
> Similar in feel to other UI toolkits (Swing, etc.)
> Researching ...
Binding
> Unquestionably the biggest JavaFX Script
innovation
> Will be supported via a PropertyBinding class
> Lazy invoc...
Observable Pseudo-Properties
> Supports watching for changes to properties
> Implemented via anonymous inner classes
> Wil...
Observable Pseudo-Properties
Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setH...
Observable Pseudo-Properties
Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setH...
Observable Pseudo-Properties
Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setH...
Observable Pseudo-Properties
Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setH...
Observable Pseudo-Properties
Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setH...
Observable Pseudo-Properties
Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setH...
Sequences in Java
> Replaced with an Observable List
> Public API is based on JavaFX sequences
> Internal code can use lig...
Example Application
public class HelloStage implements Runnable {
public void run() {
Stage stage = new Stage();
stage.set...
Summary
> The JVM has a modern UI toolkit coming to it
> Total port to Java – no hacks or kludges
> Many languages to choo...
Major Question
24
How can alternative languages make developing
JavaFX user interfaces easier & more productive?
JavaFX With JRuby
Why JRuby?
> Direct access to Java APIs
> Dynamic Typing
> Closures
> ‘Closure conversion’ for interfaces
Java in JRuby
- Accessing Properties
timeline.setAutoReverse(true)
timeline.autoReverse = true
timeline.auto_reverse = tru...
JRuby Example 1: Simple Stage
require 'java'
FX = Java::javafx.lang.FX
Stage = Java::javafx.stage.Stage
Scene = Java::java...
JRuby Example 2
rect = Rectangle.new
rect.x = 25
rect.y = 40
rect.width = 100
rect.height = 50
rect.fill = Color::RED
scen...
JRuby Closure Conversion
rect.add_changed_listener(Rectangle::HOVER) do |bean, pr|
rect.fill = rect.hover ? Color::GREEN :...
JRuby Swiby
require 'swiby'
class HelloWorldModel
attr_accessor :saying
end
model = HelloWorldModel.new
model.saying = "He...
32
JavaFX With Clojure
Artwork by Augusto Sellhorn http://sellmic.com/
A Little About Clojure
> Started in 2007 by Rich Hickey
> Functional Programming Language
> Derived from LISP
> Optimized ...
Clojure Syntax in One Slide
Symbols
> numbers – 2.178
> ratios – 355/113
> strings – “clojure”, “rocks”
> characters – a b...
Clojure GUI Example
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(.setFill scene Color/LIGHTGREE...
Clojure GUI Example
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(.setFill scene Color/LIGHTGREE...
Clojure GUI Example
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(.setFill scene Color/LIGHTGREE...
Clojure GUI Example
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(.setFill scene Color/LIGHTGREE...
Clojure GUI Example
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(.setFill scene Color/LIGHTGREE...
Simpler Code Using doto
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(doto scene
(.setFill Color...
Simpler Code Using doto
(defn javafxapp []
(let [stage (Stage. "JavaFX Stage")
scene (Scene.)]
(doto scene
(.setFill Color...
Refined Clojure GUI Example
(defn javafxapp []
(doto (Stage. "JavaFX Stage")
(.setWidth 600)
(.setHeight 450)
(.setScene (...
Refined Clojure GUI Example
(defn javafxapp []
(doto (Stage. "JavaFX Stage")
(.setWidth 600)
(.setHeight 450)
(.setScene (...
Refined Clojure GUI Example
(defn javafxapp []
(doto (Stage. "JavaFX Stage")
(.setWidth 600)
(.setHeight 450)
(.setScene (...
Refined Clojure GUI Example
(defn javafxapp []
(doto (Stage. "JavaFX Stage")
(.setWidth 600)
(.setHeight 450)
(.setScene (...
Closures in Clojure
46
> Inner classes can be created using proxy
(.addChangeListener rect Rectangle/HOVER
(proxy [Boolean...
Closures in Clojure
> Inner classes can be created using proxy
47
(.addChangeListener rect Rectangle/HOVER
(proxy [Listene...
JavaFX With Groovy
Features of Groovy
> Tight integration with Java
 Very easy to port from Java to Groovy
> Declarative syntax
 Familiar t...
Example 1: Simple FX Script to Groovy
Step 1: Lazy conversion to Groovy
class HelloStage implements Runnable {
void run() {
Stage stage = new Stage();
stage.set...
Step 2: Slightly More Groovy
class HelloStage implements Runnable {
void run() {
new Stage(
title: "Hello Stage (Groovy)",...
Slight Aside: Groovy Builders
> Groovy builders make writing custom DSLs easy
> For the next slide, I am using a builder I...
Step 3: Using a Groovy Builder
FxBuilder.build {
stage = stage(
title: "Hello World",
width: 600,
height: 450,
scene: scen...
Step 4: With Content
FxBuilder.build {
stage = stage(
title: "Hello Rectangle (Groovy FxBuilder 2)",
width: 600,
height: 4...
Example 2: FX Script Animation in Groovy
Step 1: JavaFX Script
def timeline = Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames: [
KeyFrame {...
Step 1a: JavaFX Script Simplification
def timeline = Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFram...
Step 2: Java-ish Groovy Animations
final Timeline timeline = new Timeline(
repeatCount: Timeline.INDEFINITE,
autoReverse: ...
Step 3: JavaFX Animation in Groovy
(Using Builders)
timeline = timeline(repeatCount: Timeline.INDEFINITE, autoReverse: tru...
Groovy Closures
- With interface coercion
def f = {
bean, pr -> rect.setFill(rect.isHover() ? Color.GREEN : Color.RED);
} ...
62
JavaFX With Scala
What is Scala
> Started in 2001 by Martin Odersky
> Compiles to Java bytecodes
> Pure object-oriented language
> Also a fu...
Why Scala?
> Shares many language features with JavaFX
Script that make GUI programming easier:
 Static type checking – C...
Java vs. Scala DSL
public class HelloStage implements Runnable {
public void run() {
Stage stage = new Stage();
stage.setT...
object HelloJavaFX extends JavaFXApplication {
def stage = new Stage {
title = "Hello Stage"
width = 600
height = 450
scen...
67
object HelloJavaFX extends JavaFXApplication {
def stage = new Stage {
title = "Hello Stage"
width = 600
height = 450
s...
68
object HelloJavaFX extends JavaFXApplication {
def stage = new Stage {
title = "Hello Stage"
width = 600
height = 450
s...
69
object HelloJavaFX extends JavaFXApplication {
def stage = new Stage {
title = "Hello Stage"
width = 600
height = 450
s...
70
object HelloJavaFX extends JavaFXApplication {
def stage = new Stage {
title = "Hello Stage"
width = 600
height = 450
s...
Animation in Scala
def timeline = new Timeline {
repeatCount = INDEFINITE
autoReverse = true
keyFrames = List(
new KeyFram...
Animation in Scala
72
Duration set by
Constructor Parameter
def timeline = new Timeline {
repeatCount = INDEFINITE
autoRev...
Animation in Scala
73
Operator overloading for
animation syntax
def timeline = new Timeline {
repeatCount = INDEFINITE
aut...
Closures in Scala
74
> Closures are also supported in Scala
> And they are 100% type-safe
rect.addChangedListener(Node.HOV...
Closures in Scala
> Closures are also supported in Scala
> And they are 100% type-safe
75
rect.addChangedListener(Node.HOV...
Other JVM Languages to Try
> Jython
 Started by Jim Hugunin
 High Performance Python
> Mirah
 Invented by Charles Nutte...
Fantom Code Example
Void main() {
Stage {
title = "Hello Stage"
width = 600
height = 450
Scene {
fill = Color.LIGHTGREEN
R...
timeline := Timeline {
repeatCount = Timeline.INDEFINITE
autoReverse = true
KeyFrame {
time = 50ms
KeyValue(rect1.x() -> 3...
Announcing Project Visage
79
> Visage project goals:
 Compile to JavaFX Java APIs
 Evolve the Language (Annotations, Map...
How about JavaFX on… Visage
Stage {
title: "Hello Stage"
width: 600
height: 450
Scene {
fill: Color.LIGHTGREEN
Rectangle {...
Visage Android Workshop
Today @ 21:00 – 22:00
Room: BOF 2
Description:
Bring your Android device and learn how to build
an...
Conclusion
> JavaFX as Java APIs is great
> Usable in alternate languages
> Over time improved support is possible
 Groov...
83
Stephen Chin
steveonjava@gmail.com
tweet: @steveonjava
Jonathan Giles
Jonathan.giles@oracle.com
tweet: @jonathangiles
P...
Upcoming SlideShare
Loading in...5
×

JavaFX Your Way - Devoxx Version

5,678

Published on

Updated version of the JavaFX Your Way talk for Devoxx. This includes additional JavaFX 2.0 API changes and an example of some Fantom code snippets.

Published in: Technology, News & Politics
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,678
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
39
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • There are two kinds of listener: ‘changedListener’ and ‘ChangingListener’. Being informed of the change before it happens allow for it to be vetoed.
    It is also possible to either watch a single property, or all properties belonging to a bean.
    Note that the value passed to the callback is the old value. This is to ensure that we aren’t eagerly computing the new value when it might not be required. To get the new value, you can call the function on the bean or via the propertyReference
  • Slight conversion to Groovy. This can be compiled by the Groovy compiler and run, but basically there is only one line difference (the ‘static void main’ line)
  • This is the same code as the previous slide, taking advantage of some of the Groovy syntax tricks. This is getting to look a lot more like JavaFX Script.
  • This DSL handles running on the EDT, and can actually be run as-is – there is no need for a class declaration, or anything else to ensure that we’re on the EDT. This is getting us fairly close to the simple JavaFX Script at the beginning
  • This DSL handles running on the EDT, and can actually be run as-is – there is no need for a class declaration, or anything else to ensure that we’re on the EDT. This is getting us fairly close to the simple JavaFX Script at the beginning
  • Transcript of "JavaFX Your Way - Devoxx Version"

    1. 1. JavaFX Your Way Building JavaFX Applications with Alternative Languages Stephen Chin GXS steveonjava@gmail.com tweet: @steveonjava Jonathan Giles Oracle Jonathan.giles@oracle.com tweet: @jonathangiles
    2. 2. Meet the Presenters… Steve Jonathan 2 Family Man A reasonable facsimile of… Motorcyclist
    3. 3. Challenge the Presenter…
    4. 4. Challenge the Presenter…
    5. 5. Disclaimer: This is proof of concept
    6. 6. THE FOLLOWING IS INTENDED TO OUTLINE ORACLE’S GENERAL PRODUCT DIRECTION. IT IS INTENDED FOR INFORMATION PURPOSES ONLY, AND MAY NOT BE INCORPORATED INTO ANY CONTRACT. IT IS NOT A COMMITMENT TO DELIVER ANY MATERIAL, CODE, OR FUNCTIONALITY, AND SHOULD NOT BE RELIED UPON IN MAKING PURCHASING DECISION. THE DEVELOPMENT, RELEASE, AND TIMING OF ANY FEATURES OR FUNCTIONALITY DESCRIBED FOR ORACLE'S PRODUCTS REMAINS AT THE SOLE DISCRETION OF ORACLE.
    7. 7. Disclaimer #2: This is code-heavy
    8. 8. Overall Presentation Goal Demonstrate the future potential of the JavaFX platform.
    9. 9. Agenda > JavaFX 2.0 Announcement > JavaFX in Java > Explore alternative languages  JRuby  Clojure  Groovy  Scala  +???
    10. 10. JavaFX 2.0 Announcement • JavaFX Script is no longer required to write JavaFX applications • Benefits: – Easier integration with business logic on JVM – Access to generics, annotations, (closures), etc – Java has great IDE support • Downsides: – JavaFX Script was kind to us
    11. 11. JavaFX With Java
    12. 12. JavaFX in Java > JavaFX API follows JavaBeans approach > Similar in feel to other UI toolkits (Swing, etc.) > Researching approaches to minimize boilerplate
    13. 13. Binding > Unquestionably the biggest JavaFX Script innovation > Will be supported via a PropertyBinding class > Lazy invocation for high performance > Static construction syntax for simple cases  e.g.: bindTo(<property>)
    14. 14. Observable Pseudo-Properties > Supports watching for changes to properties > Implemented via anonymous inner classes > Will take advantage of closures in the future
    15. 15. Observable Pseudo-Properties Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.addChangedListener(Rectangle.HOVER, new Listener() { });
    16. 16. Observable Pseudo-Properties Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.addChangedListener(Rectangle.HOVER, new Listener() { }); The property we want to watch
    17. 17. Observable Pseudo-Properties Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.addChangedListener(Rectangle.HOVER, new Listener() { }); Only one listener used regardless of data type
    18. 18. Observable Pseudo-Properties Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.addChangedListener(Rectangle.HOVER, new Listener() { public void handle(Bean bean, PropertyReference pr) { } }); Rectangle is a Bean
    19. 19. Observable Pseudo-Properties Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.addChangedListener(Rectangle.HOVER, new Listener() { public void handle(Bean bean, PropertyReference pr) { } }); Refers to the Rectangle.hover ‘property’
    20. 20. Observable Pseudo-Properties Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.addChangedListener(Rectangle.HOVER, new Listener() { public void handle(Bean bean, PropertyReference pr) { rect.setFill(rect.isHover() ? Color.GREEN : Color.RED); } });
    21. 21. Sequences in Java > Replaced with an Observable List > Public API is based on JavaFX sequences > Internal code can use lighter collections API > JavaFX 2.0 will also have an Observable Map
    22. 22. Example Application public class HelloStage implements Runnable { public void run() { Stage stage = new Stage(); stage.setTitle("Hello Stage"); stage.setWidth(600); stage.setHeight(450); Scene scene = new Scene(); scene.setFill(Color.LIGHTGREEN); stage.setScene(scene); stage.setVisible(true); } public static void main(String[] args) { FX.start(new HelloStage()); } }
    23. 23. Summary > The JVM has a modern UI toolkit coming to it > Total port to Java – no hacks or kludges > Many languages to choose from > Alternate languages == exciting possibilities > Choose the best language for your needs
    24. 24. Major Question 24 How can alternative languages make developing JavaFX user interfaces easier & more productive?
    25. 25. JavaFX With JRuby
    26. 26. Why JRuby? > Direct access to Java APIs > Dynamic Typing > Closures > ‘Closure conversion’ for interfaces
    27. 27. Java in JRuby - Accessing Properties timeline.setAutoReverse(true) timeline.autoReverse = true timeline.auto_reverse = true timeline.getKeyFrames().add(kf) timeline.key_frames.add(kf) timeline.key_frames.add kf
    28. 28. JRuby Example 1: Simple Stage require 'java' FX = Java::javafx.lang.FX Stage = Java::javafx.stage.Stage Scene = Java::javafx.scene.Scene Color = Java::javafx.scene.paint.Color class HelloStage include java.lang.Runnable def run ..... end end FX.start(HelloStage.new); stage = Stage.new stage.title = 'Hello Stage (JRuby)' stage.width = 600 stage.height = 450 scene = Scene.new scene.fill = Color::LIGHTGREEN stage.scene = scene stage.visible = true;
    29. 29. JRuby Example 2 rect = Rectangle.new rect.x = 25 rect.y = 40 rect.width = 100 rect.height = 50 rect.fill = Color::RED scene.content.add(rect) timeline = Timeline.new timeline.repeat_count = Timeline::INDEFINITE timeline.auto_reverse = true kv = KeyValue.new(rect.x(), 200); kf = KeyFrame.new(Duration.valueOf(500), kv); timeline.key_frames.add kf; timeline.play();
    30. 30. JRuby Closure Conversion rect.add_changed_listener(Rectangle::HOVER) do |bean, pr| rect.fill = rect.hover ? Color::GREEN : Color::RED; end 30
    31. 31. JRuby Swiby require 'swiby' class HelloWorldModel attr_accessor :saying end model = HelloWorldModel.new model.saying = "Hello World" Frame { title "Hello World“ width 200 content { Label { text bind(model,:saying) } } visible true } 31
    32. 32. 32 JavaFX With Clojure Artwork by Augusto Sellhorn http://sellmic.com/
    33. 33. A Little About Clojure > Started in 2007 by Rich Hickey > Functional Programming Language > Derived from LISP > Optimized for High Concurrency > … and looks nothing like Java! 33 (def hello (fn [] "Hello world")) (hello)
    34. 34. Clojure Syntax in One Slide Symbols > numbers – 2.178 > ratios – 355/113 > strings – “clojure”, “rocks” > characters – a b c d > symbols – a b c d > keywords – :alpha :beta > boolean – true, false > null - nil Collections (commas optional) > Lists (1, 2, 3, 4, 5) > Vectors [1, 2, 3, 4, 5] > Maps {:a 1, :b 2, :c 3, :d 4} > Sets #{:a :b :c :d :e} 34 (plus macros that are syntactic sugar wrapping the above)
    35. 35. Clojure GUI Example (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (.setFill scene Color/LIGHTGREEN) (.setWidth stage 600) (.setHeight stage 450) (.setScene stage scene) (.setVisible stage true))) (javafxapp) 35
    36. 36. Clojure GUI Example (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (.setFill scene Color/LIGHTGREEN) (.setWidth stage 600) (.setHeight stage 450) (.setScene stage scene) (.setVisible stage true))) (javafxapp) 36 Create a Function for the Application
    37. 37. Clojure GUI Example (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (.setFill scene Color/LIGHTGREEN) (.setWidth stage 600) (.setHeight stage 450) (.setScene stage scene) (.setVisible stage true))) (javafxapp) 37 Initialize the Stage and Scene Variables
    38. 38. Clojure GUI Example (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (.setFill scene Color/LIGHTGREEN) (.setWidth stage 600) (.setHeight stage 450) (.setScene stage scene) (.setVisible stage true))) (javafxapp) 38 Call Setter Methods on Scene and Stage
    39. 39. Clojure GUI Example (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (.setFill scene Color/LIGHTGREEN) (.setWidth stage 600) (.setHeight stage 450) (.setScene stage scene) (.setVisible stage true))) (javafxapp) 39 Java Constant Syntax Java Method Syntax
    40. 40. Simpler Code Using doto (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (doto scene (.setFill Color/LIGHTGREEN)) (doto stage (.setWidth 600) (.setHeight 450) (.setScene scene) (.setVisible true)))) (javafxapp) 40
    41. 41. Simpler Code Using doto (defn javafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (doto scene (.setFill Color/LIGHTGREEN)) (doto stage (.setWidth 600) (.setHeight 450) (.setScene scene) (.setVisible true)))) (javafxapp) 41 doto form: (doto symbol (.method params)) equals: (.method symbol params)
    42. 42. Refined Clojure GUI Example (defn javafxapp [] (doto (Stage. "JavaFX Stage") (.setWidth 600) (.setHeight 450) (.setScene (doto (Scene.) (.setFill Color/LIGHTGREEN) (.setContent (list (doto (Rectangle.) (.setX 25) (.setY 40) (.setWidth 100) (.setHeight 50) (.setFill Color/RED)))))) (.setVisible true))) (javafxapp) 42
    43. 43. Refined Clojure GUI Example (defn javafxapp [] (doto (Stage. "JavaFX Stage") (.setWidth 600) (.setHeight 450) (.setScene (doto (Scene.) (.setFill Color/LIGHTGREEN) (.setContent (list (doto (Rectangle.) (.setX 25) (.setY 40) (.setWidth 100) (.setHeight 50) (.setFill Color/RED)))))) (.setVisible true))) (javafxapp) 43 Let replaced with inline declarations
    44. 44. Refined Clojure GUI Example (defn javafxapp [] (doto (Stage. "JavaFX Stage") (.setWidth 600) (.setHeight 450) (.setScene (doto (Scene.) (.setFill Color/LIGHTGREEN) (.setContent (list (doto (Rectangle.) (.setX 25) (.setY 40) (.setWidth 100) (.setHeight 50) (.setFill Color/RED)))))) (.setVisible true))) (javafxapp) 44 Doto allows nested data structures
    45. 45. Refined Clojure GUI Example (defn javafxapp [] (doto (Stage. "JavaFX Stage") (.setWidth 600) (.setHeight 450) (.setScene (doto (Scene.) (.setFill Color/LIGHTGREEN) (.setContent (list (doto (Rectangle.) (.setX 25) (.setY 40) (.setWidth 100) (.setHeight 50) (.setFill Color/RED)))))) (.setVisible true))) (javafxapp) 45 Now a nested Rectangle fits!
    46. 46. Closures in Clojure 46 > Inner classes can be created using proxy (.addChangeListener rect Rectangle/HOVER (proxy [BooleanListener] [] (handle [b, p, o] (.setFill rect (if (.isHover rect) Color/GREEN Color/RED)))))
    47. 47. Closures in Clojure > Inner classes can be created using proxy 47 (.addChangeListener rect Rectangle/HOVER (proxy [Listener] [] (handle [b, p] (.setFill rect (if (.isHover rect) Color/GREEN Color/RED))))) Proxy form: (proxy [class] [args] fs+) f => (name [params*] body)
    48. 48. JavaFX With Groovy
    49. 49. Features of Groovy > Tight integration with Java  Very easy to port from Java to Groovy > Declarative syntax  Familiar to JavaFX Script developers > Builders
    50. 50. Example 1: Simple FX Script to Groovy
    51. 51. Step 1: Lazy conversion to Groovy class HelloStage implements Runnable { void run() { Stage stage = new Stage(); stage.setTitle("Hello Stage (Groovy)“); stage.setWidth(600); stage.setHeight(450); Scene scene = new Scene(); scene.setFill(Color.LIGHTSKYBLUE); stage.setScene(scene); stage.setVisible(true); } static void main(args) { FX.start(new HelloStage()); } }
    52. 52. Step 2: Slightly More Groovy class HelloStage implements Runnable { void run() { new Stage( title: "Hello Stage (Groovy)", width: 600, height: 450, visible: true, scene: new Scene( fill: Color.LIGHTSKYBLUE, ) ); } static void main(args) { FX.start(new HelloStage()); } }
    53. 53. Slight Aside: Groovy Builders > Groovy builders make writing custom DSLs easy > For the next slide, I am using a builder I defined > Hopefully the community will improve upon this
    54. 54. Step 3: Using a Groovy Builder FxBuilder.build { stage = stage( title: "Hello World", width: 600, height: 450, scene: scene(fill: Color.LIGHTSKYBLUE) { ... } ) stage.visible = true; }
    55. 55. Step 4: With Content FxBuilder.build { stage = stage( title: "Hello Rectangle (Groovy FxBuilder 2)", width: 600, height: 450, scene: scene(fill: Color.LIGHTSKYBLUE) { rectangle( x: 25, y: 40, width: 100, height: 50, fill: Color.RED ) } ) stage.visible = true; }
    56. 56. Example 2: FX Script Animation in Groovy
    57. 57. Step 1: JavaFX Script def timeline = Timeline { repeatCount: Timeline.INDEFINITE autoReverse: true keyFrames: [ KeyFrame { time: 750ms values : [ rect1.x => 200.0 tween Interpolator.LINEAR, rect2.y => 200.0 tween Interpolator.LINEAR, circle1.radius => 200.0 tween Interpolator.LINEAR ] } ]; } timeline.play();
    58. 58. Step 1a: JavaFX Script Simplification def timeline = Timeline { repeatCount: Timeline.INDEFINITE autoReverse: true keyFrames: at (750ms) { rect1.x => 200.0 tween Interpolator.LINEAR; rect2.y => 200.0 tween Interpolator.LINEAR; circle1.radius => 200.0 tween Interpolator.LINEAR; } } timeline.play();
    59. 59. Step 2: Java-ish Groovy Animations final Timeline timeline = new Timeline( repeatCount: Timeline.INDEFINITE, autoReverse: true ) final KeyValue kv1 = new KeyValue (rect1.x(), 200); final KeyValue kv2 = new KeyValue (rect2.y(), 200); final KeyValue kv3 = new KeyValue (circle1.radius(), 200); final KeyFrame kf = new KeyFrame(Duration.valueOf(750), kv1, kv2, kv3); timeline.getKeyFrames().add(kf); timeline.play();
    60. 60. Step 3: JavaFX Animation in Groovy (Using Builders) timeline = timeline(repeatCount: Timeline.INDEFINITE, autoReverse: true) { keyframes { keyframe(time: 750) { keyvalue(target: rect1.y(), endValue: 200); keyvalue(target: rect2.x(), endValue: 200); keyvalue(target: circle1.radius(), endValue: 200); } } } timeline.play();
    61. 61. Groovy Closures - With interface coercion def f = { bean, pr -> rect.setFill(rect.isHover() ? Color.GREEN : Color.RED); } as Listener; rect.addChangedListener(Rectangle.HOVER, f);
    62. 62. 62 JavaFX With Scala
    63. 63. What is Scala > Started in 2001 by Martin Odersky > Compiles to Java bytecodes > Pure object-oriented language > Also a functional programming language 2001 • Scala Started 2003/2004 • Scala v1.0 2006 • Scala v2.0 2010 • Scala 2.8.0 (latest) 63
    64. 64. Why Scala? > Shares many language features with JavaFX Script that make GUI programming easier:  Static type checking – Catch your errors at compile time  Closures – Wrap behavior and pass it by reference  Declarative – Express the UI by describing what it should look like > Scala also supports DSLs! 64
    65. 65. Java vs. Scala DSL public class HelloStage implements Runnable { public void run() { Stage stage = new Stage(); stage.setTitle("Hello Stage"); stage.setWidth(600); stage.setHeight(450); Scene scene = new Scene(); scene.setFill(Color.LIGHTGREEN); Rectangle rect = new Rectangle(); rect.setX(25); rect.setY(40); rect.setWidth(100); rect.setHeight(50); rect.setFill(Color.RED); stage.add(rect); stage.setScene(scene); stage.setVisible(true); } public static void main(String[] args) { FX.start(new HelloStage()); } } object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } 65 22 Lines 545 Characters 17 Lines 324 Characters
    66. 66. object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } 66
    67. 67. 67 object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } Base class for JavaFX applications
    68. 68. 68 object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } Declarative Stage definition
    69. 69. 69 object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } Inline property definitions
    70. 70. 70 object HelloJavaFX extends JavaFXApplication { def stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = List(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED }) } } } List Construction Syntax
    71. 71. Animation in Scala def timeline = new Timeline { repeatCount = INDEFINITE autoReverse = true keyFrames = List( new KeyFrame(50) { values = List( new KeyValue(rect1.x() -> 300), new KeyValue(rect2.y() -> 500), new KeyValue(rect2.width() -> 150) ) } ) } 71
    72. 72. Animation in Scala 72 Duration set by Constructor Parameter def timeline = new Timeline { repeatCount = INDEFINITE autoReverse = true keyFrames = List( new KeyFrame(50) { values = List( new KeyValue(rect1.x() -> 300), new KeyValue(rect2.y() -> 500), new KeyValue(rect2.width() -> 150) ) } ) }
    73. 73. Animation in Scala 73 Operator overloading for animation syntax def timeline = new Timeline { repeatCount = INDEFINITE autoReverse = true keyFrames = List( new KeyFrame(50) { values = List( new KeyValue(rect1.x() -> 300), new KeyValue(rect2.y() -> 500), new KeyValue(rect2.width() -> 150) ) } ) }
    74. 74. Closures in Scala 74 > Closures are also supported in Scala > And they are 100% type-safe rect.addChangedListener(Node.HOVER, (b, p, o) => { rect.fill = if (rect.hover) Color.GREEN else Color.RED })
    75. 75. Closures in Scala > Closures are also supported in Scala > And they are 100% type-safe 75 rect.addChangedListener(Node.HOVER, (b, p) => { rect.fill = if (rect.hover) Color.GREEN else Color.RED }) Compact syntax (params) => {body} rect.addChangedListener(Node.HOVER, (b, p) => { rect.fill = if (rect.hover) Color.GREEN else Color.RED })
    76. 76. Other JVM Languages to Try > Jython  Started by Jim Hugunin  High Performance Python > Mirah  Invented by Charles Nutter  Originally called Duby  Local Type Inference, Static and Dynamic Typing > Fantom  Created by Brian and Andy Frank  Originally called Fan  Built-in Declarative Syntax  Portable to Java and .NET  Local Type Inference, Static and Dynamic Typing 76
    77. 77. Fantom Code Example Void main() { Stage { title = "Hello Stage" width = 600 height = 450 Scene { fill = Color.LIGHTGREEN Rectangle { x = 25 y = 40 width = 100 height = 50 fill = Color.RED } } }.open } 77
    78. 78. timeline := Timeline { repeatCount = Timeline.INDEFINITE autoReverse = true KeyFrame { time = 50ms KeyValue(rect1.x() -> 300), KeyValue(rect2.y() -> 500), KeyValue(rect2.width() -> 150) } } Animation in Fantom 78 Fantom has a built-in Duration type And also supports operator overloading
    79. 79. Announcing Project Visage 79 > Visage project goals:  Compile to JavaFX Java APIs  Evolve the Language (Annotations, Maps, etc.)  Support Other Toolkits > Come join the team! > For more info: http://visage-lang.org/ > “Visage is a domain specific language (DSL) designed for the express purpose of writing user interfaces.”
    80. 80. How about JavaFX on… Visage Stage { title: "Hello Stage" width: 600 height: 450 Scene { fill: Color.LIGHTGREEN Rectangle { x: 25 y: 40 width: 100 height: 50 fill: Color.RED } } } 80
    81. 81. Visage Android Workshop Today @ 21:00 – 22:00 Room: BOF 2 Description: Bring your Android device and learn how to build and deploy Android market applications using the Visage language. Prizes will be awarded for finding defects and helping the dev team make Visage better. 81
    82. 82. Conclusion > JavaFX as Java APIs is great > Usable in alternate languages > Over time improved support is possible  Groovy Builders, Scala DSL, Visage Remember: This is a proof of concept only – you can not leave this session and do this today.
    83. 83. 83 Stephen Chin steveonjava@gmail.com tweet: @steveonjava Jonathan Giles Jonathan.giles@oracle.com tweet: @jonathangiles Presentation will be posted at: http://steveonjava.com/
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×