SlideShare ist ein Scribd-Unternehmen logo
1 von 84
JavaFX 2.0 With Alternative Languages Stephen Chin Chief Agile Methodologist, GXS steveonjava@gmail.com tweet: @steveonjava Dean Iverson VTTI deanriverson@gmail.com tweet: @deanriverson
Meet the Presenters Stephen Chin Dean Iverson Family Man Family Man Motorcyclist Geek
Disclaimer: This is Code-Heavy THE FOLLOWING IS INTENDED TO STIMULATE CREATIVE USE OF JVM LANGUAGES. AFTER WATCHING THIS PRESENTATION YOU MAY FEEL COMPELLED TO START LEARNING A NEW JVM LANGUAGE. THE PRESENTERS ARE NOT LIABLE FOR ANY INNOVATION, BREAKTHROUGHS, OR NP-COMPLETE SOLUTIONS THAT MAY RESULT.
JavaFX With Java
Programming Languages JavaFX 2.0 APIs are now in Java Pure Java APIs for all of JavaFX Bindingand Sequences exposed as Java APIs FXML Markup for tooling Embrace all JVM languages Groovy, Scala, Clojure, JRuby Fantom, Mira, Gosu, Jython, etc. JavaFX Script is no longer supported by Oracle Existing JavaFX Script based applications will continue to run Visageis the open-source successor to the JavaFX Script language
JavaFX in Java JavaFX API uses an enhanced JavaBeans pattern Similar in feel to other UI toolkits (Swing, Apache Pivot, etc.) Uses builder pattern to minimize boilerplate
Example Application public class HelloStage extends Application {   @Override public void start(Stage stage) {     stage.setTitle("Hello Stage"); stage.setWidth(600);     stage.setHeight(450); Group root = new Group();     Scene scene = new Scene(root); scene.setFill(Color.LIGHTGREEN); stage.setScene(scene); stage.show();   }   public static void main(String[] args) {     launch(HelloStage.class, args);   } }
Example Application Using Builders public class HelloStage extends Application {   @Override public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setScene(SceneBuilder.create() .fill(Color.LIGHTGREEN) .width(600) .height(450)     .build()); stage.show(); }   public static void main(String[] args) {     launch(HelloStage.class, args);   } }
Binding Unquestionably the biggest JavaFX Script innovation Supported via a PropertyBindingclass Lazy invocation for high performance Static construction syntax for simple cases e.g.: bind(<property>), bindBiDirectional(<property>)
Observable Pseudo-Properties Supports watching for changes to properties Implemented via anonymous inner classes Will take advantage of closures in the future
Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { });
Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { }); The property we want to watch
Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { }); Only one listener used with generics to specify the data type
Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() {   public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean value) {  } }); Refers to the Rectangle.hoverProperty()
Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() {   public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean value) {     rect.setFill(rect.isHover() ? Color.GREEN : Color.RED);   } });
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 also has an Observable Map
JavaFX With Groovy
Features of Groovy Modern language Closures AST Transforms Strongly typed dynamic language Tight integration with Java Very easy to port from Java to Groovy Declarative syntax with GroovyFX Builders Familiar to Groovy and JavaFX Script developers
Java vs. GroovyFX DSL public class HelloStage extends Application {   public void start(Stage 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);  scene.setRoot(new Group(rect)); stage.setScene(scene); stage.show();   }   public static void main(String[] args) {     launch(HelloStage.class, args);   } } GroovyFX.start { stage ->   def sg = new SceneGraphBuilder(stage)   sg.stage(title: “Hello Stage”, width: 600, height: 450) {     scene(fill: groovyblue) {       rectangle(x: 25, y: 40, width: 100, height: 50, fill: red)     }   } } 19 8 Lines 180 Characters 21 Lines 430 Characters
def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) {     50.times { circle(centerX: rand(800), centerY: rand(600),               radius: 150, stroke: white,  strokeWidth: bind('hover', converter: hc)) {         fill rgb(rand(255), rand(255), rand(255), 0.2)         effect boxBlur(width: 10, height: 10, iterations: 3)       }     }   } } 20
21 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) {     50.times { circle(centerX: rand(800), centerY: rand(600),               radius: 150, stroke: white,  strokeWidth: bind('hover', converter: hc)) {         fill rgb(rand(255), rand(255), rand(255), 0.2)         effect boxBlur(width: 10, height: 10, iterations: 3)       }     }   } } Builder for GroovyFX scene graphs
22 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) {     50.times { circle(centerX: rand(800), centerY: rand(600),               radius: 150, stroke: white,  strokeWidth: bind('hover', converter: hc)) {         fill rgb(rand(255), rand(255), rand(255), 0.2)         effect boxBlur(width: 10, height: 10, iterations: 3)       }     }   } } Declarative Stage definition
23 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) {     50.times { circle(centerX: rand(800), centerY: rand(600),               radius: 150, stroke: white,  strokeWidth: bind('hover', converter: hc)) {         fill rgb(rand(255), rand(255), rand(255), 0.2)         effect boxBlur(width: 10, height: 10, iterations: 3)       }     }   } } Inline property definitions
24 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) {     50.times { circle(centerX: rand(800), centerY: rand(600),               radius: 150, stroke: white,  strokeWidth: bind('hover', converter: hc)) {         fill rgb(rand(255), rand(255), rand(255), 0.2)         effect boxBlur(width: 10, height: 10, iterations: 3)       }     }   } } Bind to properties
25 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600),               radius: 150, stroke: white,  strokeWidth: bind('hover', converter: hc)) {         fill rgb(rand(255), rand(255), rand(255), 0.2)         effect boxBlur(width: 10, height: 10, iterations: 3)       } }   } } Sequence Creation Via Loop
Properties in Java public class Person {   private StringPropertyfirstName;   public void setFirstName(Stringval) { firstNameProperty().set(val); }   public String getFirstName() { return firstNameProperty().get(); }   public StringPropertyfirstNameProperty() {      if (firstName == null)  firstName = new SimpleStringProperty(this, "firstName");     return firstName;    }   private StringPropertylastName;   public void setLastName(String value) { lastNameProperty().set(value); }   public String getLastName() { return lastNameProperty().get(); }   public StringPropertylastNameProperty() {      if (lastName == null) // etc.   }  } 26
Properties in GroovyFX public class Person {   @FXBindable String firstName;    @FXBindable String lastName; } 27
public class Person {   @FXBindable String firstName;    @FXBindable String lastName= “Smith”; } Properties in GroovyFX 28 Optional initializers
public class Person {   @FXBindable String firstName;    @FXBindable String lastName = “Smith”; } def p = new Person() def last = p.lastName p.firstName = “Agent” Properties in GroovyFX 29 Get and set values
public class Person {   @FXBindable String firstName;    @FXBindable String lastName = “Smith”; } def p = new Person() def last = p.lastName p.firstName = “Agent” textField(text: bind(p.lastNameProperty())) Properties in GroovyFX 30 Access underlying property for binding
Binding in GroovyFX @FXBindable class Time {   Integer hours   Integer minutes   Integer seconds   Double hourAngle   Double minuteAngle   Double secondAngle   public Time() {     // bind the angle properties to the clock time hourAngleProperty().bind((hoursProperty() * 30.0) + (minutesProperty() * 0.5)) minuteAngleProperty().bind(minutesProperty() * 6.0) secondAngleProperty().bind(secondsProperty() * 6.0)   } } 31
Animation in GroovyFX timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {   at (1000.ms) {     change(rect1, 'x') to 200 tweenease_both     change rect2.yProperty() to 200 tween linear   } }.play() 32
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { at (1000.ms) {     change(rect1, 'x') to 200 tweenease_both     change rect2.yProperty() to 200 tween linear } }.play() Animation in GroovyFX 33 Easy animation syntax:  at (duration) {keyframes}
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {   at (1000.ms) { change(rect1, 'x') to 200     change rect2.yProperty() to 200   } }.play() Animation in GroovyFX 34 Key frame DSL
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {   at (1000.ms) {     change(rect1, 'x') to 200 tweenease_both change rect2.yProperty() to 200tween linear   } }.play() Animation in GroovyFX 35 Optional easing
Event Listeners in GroovyFX 36 Supported using the built-in Closure syntax Optional arguments for event objects onMouseClicked { e ->   timeline {     at(3.s) { change e.source.radiusProperty() to 0 }   }.play() }
Event Listeners in GroovyFX Supported using the built-in Closure syntax Optional arguments for event objects 37 onMouseClicked {MouseEvente ->   timeline {     at(3.s) { change e.source.radiusProperty() to 0 }   }.play() } Compact syntax {body}
Event Listeners in GroovyFX Supported using the built-in Closure syntax Optional arguments for event objects 38 Optional event parameter {event -> body} onMouseClicked { MouseEvente ->   timeline {     at(3.s) { change e.source.radiusProperty() to 0 }   }.play() }
TableView in Java 39 ObservableList<Person> items = ... TableView<Person> tableView = new TableView<Person>(items); TableColumn<Person,String> firstNameCol =          new TableColumn<Person,String>("First Name"); firstNameCol.setCellValueFactory(         new Callback<CellDataFeatures<Person, String>,  ObservableValue<String>>() {   public ObservableValue<String> call(CellDataFeatures<Person, String> p)    {     return p.getValue().firstNameProperty();   } }); tableView.getColumns().add(firstNameCol);
TableView in GroovyFX 40 def dateFormat = new SimpleDateFormat("yyyy-MM-dd"); tableView(items: persons) { tableColumn(property: "name",   text: "Name",   prefWidth: 150) tableColumn(property: "age",    text: "Age",    prefWidth: 50) tableColumn(property: "gender", text: "Gender", prefWidth: 150) tableColumn(property: "dob",    text: "Birth",  prefWidth: 150,                type: Date,               converter: { from -> return dateFormat.format(from) }) }
Layout in Java 41 TextFieldurlField = new TextField(“http://www.google.com”); HBox.setHgrow(urlField, Priority.ALWAYS); HBoxhbox = new HBox(); hbox.getChildren().add(urlField); WebViewwebView = new WebView(); VBox.setVgrow(webView, Priority.ALWAYS); VBoxvbox = new VBox(); vbox.getChildren().addAll(hbox, webView);
Layout in GroovyFX 42 sg.stage(title: "GroovyFXWebView Demo", show: true) { scene(fill: groovyblue, width: 1024, height: 800) { vbox{ hbox(padding: 10, spacing: 5) { textField(“http://www.yahoo.com”, hgrow: "always") button("Go”)             } webView(vgrow: "always")         }     } }
Layout in GroovyFX 43
Layout in GroovyFX 44 gridPane(hgap: 5, vgap: 10, padding: 25) { columnConstraints(minWidth: 50, halignment: "right") columnConstraints(prefWidth: 250) label("Send Us Your Feedback", font: "24pt sanserif",  row: 0, columnSpan: GridPane.REMAINING, halignment: "center",         margin: [0, 0, 10]) label("Name: ", row: 1, column: 0) textField(promptText: "Your name", row: 1, column: 1, hgrow: 'always') label("Email:", row: 2, column: 0) textField(promptText: "Your email", row: 2, column: 1, hgrow: 'always') label("Message:", row: 3, column: 0, valignment: "baseline") textArea(row: 3, column: 1, hgrow: "always", vgrow: "always") button("Send Message", row: 4, column: 1, halignment: "right") }
Layout in GroovyFX 45
GroovyFX Supports… 46
GroovyFX Supports… 47
48 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 for High Concurrency … and looks nothing like Java! 49 (def hello (fn [] "Hello world")) (hello)
Clojure Syntax in One Slide Symbols numbers – 2.178 ratios – 355/113 strings – “clojure”, “rocks” characters –     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} 50 (plus macros that are syntactic sugar wrapping the above)
Clojure GUI Example (defnjavafxapp []   (let [stage (Stage. "JavaFX Stage")         scene (Scene.)]     (.setFill scene Color/LIGHTGREEN)     (.setWidth stage 600)     (.setHeight stage 450)     (.setScene stage scene)     (.setVisible stage true))) (javafxapp) 51
Refined Clojure GUI Example (defnjavafxapp []   (doto (Stage. "JavaFX Stage")     (.setWidth600)     (.setHeight450)     (.setScene (doto (Scene.)       (.setFillColor/LIGHTGREEN)       (.setContent (list (doto (Rectangle.)         (.setX25)         (.setY40)         (.setWidth100)         (.setHeight50)         (.setFillColor/RED))))))     (.setVisibletrue))) (javafxapp) 52
Refined Clojure GUI Example (defnjavafxapp []   (doto (Stage. "JavaFX Stage")     (.setWidth 600)     (.setHeight 450)     (.setScene (doto (Scene.)       (.setFillColor/LIGHTGREEN)       (.setContent (list (doto (Rectangle.)         (.setX 25)         (.setY 40)         (.setWidth 100)         (.setHeight 50)         (.setFillColor/RED))))))     (.setVisible true))) (javafxapp) 53 Doto allows nested data structures
Closures in Clojure 54 Inner classes can be created using proxy (.addListenerhoverProperty   (proxy [ChangeListener] []     (handle [p, o, v]       (.setFillrect         (if (.isHoverrect) Color/GREEN Color/RED)))))
Closures in Clojure Inner classes can be created using proxy 55 Proxy form: (proxy [class] [args] fs+)  f => (name [params*] body) (.addListenerhoverProperty   (proxy[ChangeListener][]     (handle [p, o, v]       (.setFillrect         (if (.isHoverrect) Color/GREEN Color/RED)))))
56 JavaFX With Scala
What is Scala Started in 2001 by Martin Odersky Compiles to Java bytecodes Pure object-oriented language Also a functional programming language 57
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 Type Safe DSLs! Implicit Conversions – type safe class extension Operator Overloading – with standard precedence rules DelayedInit / @specialized – advanced language features 58
Java vs. Scala DSL public class HelloStage extends Application {   public void start(Stage 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);     scene.setRoot(new Group(rect)); stage.setScene(scene); stage.show();   }   public static void main(String[] args) {     launch(HelloStage.class, args);   } } object HelloJavaFX extends JFXApp {   stage = new Stage {     title = "Hello Stage"     width = 600     height = 450     scene = new Scene {       fill = LIGHTGREEN       content = Seq(new Rectangle {         x = 25         y = 40         width = 100         height = 50         fill = RED       })     }   } } 59 21 Lines 430 Characters 17 Lines 177 Characters
object DisappearingCirclesextends JFXApp {   stage = new Stage {     title = "Disappearing Circles"     width = 800     height = 600     scene = new Scene {       fill = BLACK       content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600         radius = 150         fill = color(random, random, random, 0.2)         effect = new BoxBlur(10, 10, 3)       }     }   } } 60
61 object DisappearingCirclesextends JFXApp{   stage = new Stage {     title = "Disappearing Circles"     width = 800     height = 600     scene = new Scene {       fill = BLACK       content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600         radius = 150         fill = color(random, random, random, 0.2)         effect = new BoxBlur(10, 10, 3)       }     }   } } Base class for JavaFX applications
62 object DisappearingCirclesextends JFXApp {   stage = new Stage {     title = "Disappearing Circles"     width = 800     height = 600     scene = new Scene {       fill = BLACK       content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600         radius = 150         fill = color(random, random, random, 0.2)         effect = new BoxBlur(10, 10, 3)       }     }   } } Declarative Stage definition
63 object DisappearingCirclesextends JFXApp {   stage = new Stage {     title = "Disappearing Circles"     width = 800     height = 600     scene = new Scene {       fill = BLACK       content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600         radius = 150         fill = color(random, random, random, 0.2)         effect = new BoxBlur(10, 10, 3)       }     }   } } Inline property definitions
64 object DisappearingCirclesextends JFXApp {   stage = new Stage {     title = "Disappearing Circles"     width = 800     height = 600     scene = new Scene {       fill = BLACK       content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600         radius = 150         fill = color(random, random, random, 0.2)         effect = new BoxBlur(10, 10, 3)       }     }   } } Sequence Creation Via Loop
Binding in Scala Infix Addition/Subtraction/Multiplication/Division: height <== rect1.height + rect2.height Aggregate Operators: width <== max(rect1.width, rect2.width, rect3.width) Conditional Expressions: strokeWidth <== when (hover) then 4 otherwise 0 Compound Expressions: text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled" 65
Animation in Scala valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); 66
valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); Animation in Scala 67 JavaFX Script-like animation syntax: at (duration) {keyframes}
valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); Animation in Scala 68 Operator overloading for animation syntax
valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX-> random * stage.widthtween EASE_BOTH, circle.centerY-> random * stage.heighttween EASE_IN ) } } timeline.play(); Animation in Scala 69 Optional tween syntax
Event Listeners in Scala 70 Supported using the built-in Closure syntax Optional arguments for event objects 100% type-safe onMouseClicked= {   Timeline(at(3 s){radius->0}).play() }
Event Listeners in Scala Supported using the built-in Closure syntax Optional arguments for event objects 100% type-safe 71 onMouseClicked= { Timeline(at(3 s){radius->0}).play() } Compact syntax {body}
Event Listeners in Scala Supported using the built-in Closure syntax Optional arguments for event objects 100% type-safe 72 Optional event parameter {(event) => body} onMouseClicked= { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() }
Other JVM Languages to Try JRuby Faithful to Ruby language with the power of the JVM Gosu Up and coming language created at GuideWire Easy to enhance libraries and create DSLs Mirah Invented by Charles Nutter Local Type Inference, Static and Dynamic Typing Fantom Created by Brian and Andy Frank Portable to Java and .NET Local Type Inference, Static and Dynamic Typing 73
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 } 74
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 75 Fantom has a built-in Duration type And also supports operator overloading
About Project Visage 76 ,[object Object],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/
How about JavaFX on…  Visage Stage {   title: "Hello Stage"   width: 600   height: 450  scene: Scene {     fill: Color.LIGHTGREEN     content: Rectangle {       x: 25       y: 40       width: 100       height: 50       fill: Color.RED     }   } } 77
How about JavaFX on…  Visage Stage {   title: "Hello Stage"   width: 600   height: 450 scene: Scene {     fill: Color.LIGHTGREEN content: Rectangle {       x: 25       y: 40       width: 100       height: 50       fill: Color.RED     }   } } 78
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     }   } } 79
Visage is JavaFX Script++ Default Parameters New Literal Syntax For: Angles – 35deg, 4rad, 1turn Colors –#DDCCBB, #AA33AA|CC Lengths – 5px, 2pt, 3in, 4sp Null-check Dereference var width = rect.!width Built-in Bindable Maps (coming soon!) varfruitMap = ["red" : apple, "yellow" : banana] var fruit = bind fruitMap["red"] 80
Visage and JavaFX 2.0 are made for each other… Enhanced Binding Retains lazy evaluation properties with additional expressive power Integrated Collections Sequences and Maps automatically convert between JavaFX Observable Lists/Maps Built-in Animation Syntax Ties into JavaFX animation subsystem Provides consistent, clean APIs 81
Conclusion You can write JavaFX applications in pure Java JavaFX is also usable in alternate languages You can get improved support using DSL libraries GroovyFX ScalaFX Or a dedicated UI JVM Language Visage
Pro JavaFX 2 Platform Coming Soon! Coming 4th quarter this year All examples rewritten in Java Covers the new JavaFX 2.0 APIs Will includes ScalaFX, GroovyFX, and Visage 83
84 Stephen Chin steveonjava@gmail.com tweet: @steveonjava Dean Iverson dean@pleasingsoftware.com tweet: @deanriverson

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (16)

Java FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's GuideJava FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's Guide
 
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesJavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
 
Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2
 
Clojure Deep Dive
Clojure Deep DiveClojure Deep Dive
Clojure Deep Dive
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
Alternate JVM Languages
Alternate JVM LanguagesAlternate JVM Languages
Alternate JVM Languages
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
Xm lparsers
Xm lparsersXm lparsers
Xm lparsers
 
Compact and safely: static DSL on Kotlin
Compact and safely: static DSL on KotlinCompact and safely: static DSL on Kotlin
Compact and safely: static DSL on Kotlin
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189
 
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)
 
Java7 New Features and Code Examples
Java7 New Features and Code ExamplesJava7 New Features and Code Examples
Java7 New Features and Code Examples
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopOSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
 
Php forum2015 tomas_final
Php forum2015 tomas_finalPhp forum2015 tomas_final
Php forum2015 tomas_final
 

Andere mochten auch

Andere mochten auch (7)

Visage Android - Cleaner APIs, Cleaner UIs
Visage Android - Cleaner APIs, Cleaner UIsVisage Android - Cleaner APIs, Cleaner UIs
Visage Android - Cleaner APIs, Cleaner UIs
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the Cloud
 
Orishas mitos-y-leyendas
Orishas mitos-y-leyendasOrishas mitos-y-leyendas
Orishas mitos-y-leyendas
 
Efficient JavaScript Unit Testing, March 2013
Efficient JavaScript Unit Testing, March 2013Efficient JavaScript Unit Testing, March 2013
Efficient JavaScript Unit Testing, March 2013
 
Beginning Android Flash Development - GTUG Edition
Beginning Android Flash Development - GTUG EditionBeginning Android Flash Development - GTUG Edition
Beginning Android Flash Development - GTUG Edition
 
DukeScript
DukeScriptDukeScript
DukeScript
 
JCrete Embedded Java Workshop
JCrete Embedded Java WorkshopJCrete Embedded Java Workshop
JCrete Embedded Java Workshop
 

Ähnlich wie JavaFX 2.0 With Alternative Languages - JavaOne 2011

JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
Kiyotaka Oku
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo
 

Ähnlich wie JavaFX 2.0 With Alternative Languages - JavaOne 2011 (20)

JavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesJavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative Languages
 
JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]
 
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
 
JavaFX Your Way - Devoxx Version
JavaFX Your Way - Devoxx VersionJavaFX Your Way - Devoxx Version
JavaFX Your Way - Devoxx Version
 
Groovy's Builder
Groovy's BuilderGroovy's Builder
Groovy's Builder
 
Greach, GroovyFx Workshop
Greach, GroovyFx WorkshopGreach, GroovyFx Workshop
Greach, GroovyFx Workshop
 
Mini-curso JavaFX Aula1
Mini-curso JavaFX Aula1Mini-curso JavaFX Aula1
Mini-curso JavaFX Aula1
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Don't panic in Fortaleza - ScalaFX
Don't panic in Fortaleza - ScalaFXDon't panic in Fortaleza - ScalaFX
Don't panic in Fortaleza - ScalaFX
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Groovy
GroovyGroovy
Groovy
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 

Mehr von Stephen Chin

Mehr von Stephen Chin (20)

DevOps Tools for Java Developers v2
DevOps Tools for Java Developers v2DevOps Tools for Java Developers v2
DevOps Tools for Java Developers v2
 
10 Ways Everyone Can Support the Java Community
10 Ways Everyone Can Support the Java Community10 Ways Everyone Can Support the Java Community
10 Ways Everyone Can Support the Java Community
 
Java Clients and JavaFX: The Definitive Guide
Java Clients and JavaFX: The Definitive GuideJava Clients and JavaFX: The Definitive Guide
Java Clients and JavaFX: The Definitive Guide
 
DevOps Tools for Java Developers
DevOps Tools for Java DevelopersDevOps Tools for Java Developers
DevOps Tools for Java Developers
 
Java Clients and JavaFX - Presented to LJC
Java Clients and JavaFX - Presented to LJCJava Clients and JavaFX - Presented to LJC
Java Clients and JavaFX - Presented to LJC
 
RetroPi Handheld Raspberry Pi Gaming Console
RetroPi Handheld Raspberry Pi Gaming ConsoleRetroPi Handheld Raspberry Pi Gaming Console
RetroPi Handheld Raspberry Pi Gaming Console
 
JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)
 
Confessions of a Former Agile Methodologist (JFrog Edition)
Confessions of a Former Agile Methodologist (JFrog Edition)Confessions of a Former Agile Methodologist (JFrog Edition)
Confessions of a Former Agile Methodologist (JFrog Edition)
 
Devoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopDevoxx4Kids Lego Workshop
Devoxx4Kids Lego Workshop
 
Raspberry Pi with Java (JJUG)
Raspberry Pi with Java (JJUG)Raspberry Pi with Java (JJUG)
Raspberry Pi with Java (JJUG)
 
Confessions of a Former Agile Methodologist
Confessions of a Former Agile MethodologistConfessions of a Former Agile Methodologist
Confessions of a Former Agile Methodologist
 
Internet of Things Magic Show
Internet of Things Magic ShowInternet of Things Magic Show
Internet of Things Magic Show
 
Zombie Time - JSR 310 for the Undead
Zombie Time - JSR 310 for the UndeadZombie Time - JSR 310 for the Undead
Zombie Time - JSR 310 for the Undead
 
Oracle IoT Kids Workshop
Oracle IoT Kids WorkshopOracle IoT Kids Workshop
Oracle IoT Kids Workshop
 
OpenJFX on Android and Devices
OpenJFX on Android and DevicesOpenJFX on Android and Devices
OpenJFX on Android and Devices
 
Java on Raspberry Pi Lab
Java on Raspberry Pi LabJava on Raspberry Pi Lab
Java on Raspberry Pi Lab
 
Java 8 for Tablets, Pis, and Legos
Java 8 for Tablets, Pis, and LegosJava 8 for Tablets, Pis, and Legos
Java 8 for Tablets, Pis, and Legos
 
Devoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopDevoxx4Kids NAO Workshop
Devoxx4Kids NAO Workshop
 
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
 
Raspberry Pi Gaming 4 Kids - Dutch Version
Raspberry Pi Gaming 4 Kids - Dutch VersionRaspberry Pi Gaming 4 Kids - Dutch Version
Raspberry Pi Gaming 4 Kids - Dutch Version
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Kürzlich hochgeladen (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 

JavaFX 2.0 With Alternative Languages - JavaOne 2011

  • 1. JavaFX 2.0 With Alternative Languages Stephen Chin Chief Agile Methodologist, GXS steveonjava@gmail.com tweet: @steveonjava Dean Iverson VTTI deanriverson@gmail.com tweet: @deanriverson
  • 2. Meet the Presenters Stephen Chin Dean Iverson Family Man Family Man Motorcyclist Geek
  • 3. Disclaimer: This is Code-Heavy THE FOLLOWING IS INTENDED TO STIMULATE CREATIVE USE OF JVM LANGUAGES. AFTER WATCHING THIS PRESENTATION YOU MAY FEEL COMPELLED TO START LEARNING A NEW JVM LANGUAGE. THE PRESENTERS ARE NOT LIABLE FOR ANY INNOVATION, BREAKTHROUGHS, OR NP-COMPLETE SOLUTIONS THAT MAY RESULT.
  • 5. Programming Languages JavaFX 2.0 APIs are now in Java Pure Java APIs for all of JavaFX Bindingand Sequences exposed as Java APIs FXML Markup for tooling Embrace all JVM languages Groovy, Scala, Clojure, JRuby Fantom, Mira, Gosu, Jython, etc. JavaFX Script is no longer supported by Oracle Existing JavaFX Script based applications will continue to run Visageis the open-source successor to the JavaFX Script language
  • 6. JavaFX in Java JavaFX API uses an enhanced JavaBeans pattern Similar in feel to other UI toolkits (Swing, Apache Pivot, etc.) Uses builder pattern to minimize boilerplate
  • 7. Example Application public class HelloStage extends Application { @Override public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setWidth(600); stage.setHeight(450); Group root = new Group(); Scene scene = new Scene(root); scene.setFill(Color.LIGHTGREEN); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(HelloStage.class, args); } }
  • 8. Example Application Using Builders public class HelloStage extends Application { @Override public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setScene(SceneBuilder.create() .fill(Color.LIGHTGREEN) .width(600) .height(450) .build()); stage.show(); } public static void main(String[] args) { launch(HelloStage.class, args); } }
  • 9. Binding Unquestionably the biggest JavaFX Script innovation Supported via a PropertyBindingclass Lazy invocation for high performance Static construction syntax for simple cases e.g.: bind(<property>), bindBiDirectional(<property>)
  • 10. Observable Pseudo-Properties Supports watching for changes to properties Implemented via anonymous inner classes Will take advantage of closures in the future
  • 11. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { });
  • 12. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { }); The property we want to watch
  • 13. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { }); Only one listener used with generics to specify the data type
  • 14. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean value) { } }); Refers to the Rectangle.hoverProperty()
  • 15. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean value) { rect.setFill(rect.isHover() ? Color.GREEN : Color.RED); } });
  • 16. 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 also has an Observable Map
  • 18. Features of Groovy Modern language Closures AST Transforms Strongly typed dynamic language Tight integration with Java Very easy to port from Java to Groovy Declarative syntax with GroovyFX Builders Familiar to Groovy and JavaFX Script developers
  • 19. Java vs. GroovyFX DSL public class HelloStage extends Application { public void start(Stage 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); scene.setRoot(new Group(rect)); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(HelloStage.class, args); } } GroovyFX.start { stage -> def sg = new SceneGraphBuilder(stage) sg.stage(title: “Hello Stage”, width: 600, height: 450) { scene(fill: groovyblue) { rectangle(x: 25, y: 40, width: 100, height: 50, fill: red) } } } 19 8 Lines 180 Characters 21 Lines 430 Characters
  • 20. def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } } 20
  • 21. 21 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } } Builder for GroovyFX scene graphs
  • 22. 22 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } } Declarative Stage definition
  • 23. 23 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } } Inline property definitions
  • 24. 24 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } } Bind to properties
  • 25. 25 def sg = new SceneGraphBuilder() def hc = { hover -> hover ? 4 : 0 } sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } } Sequence Creation Via Loop
  • 26. Properties in Java public class Person { private StringPropertyfirstName; public void setFirstName(Stringval) { firstNameProperty().set(val); } public String getFirstName() { return firstNameProperty().get(); } public StringPropertyfirstNameProperty() { if (firstName == null) firstName = new SimpleStringProperty(this, "firstName"); return firstName; } private StringPropertylastName; public void setLastName(String value) { lastNameProperty().set(value); } public String getLastName() { return lastNameProperty().get(); } public StringPropertylastNameProperty() { if (lastName == null) // etc. } } 26
  • 27. Properties in GroovyFX public class Person { @FXBindable String firstName; @FXBindable String lastName; } 27
  • 28. public class Person { @FXBindable String firstName; @FXBindable String lastName= “Smith”; } Properties in GroovyFX 28 Optional initializers
  • 29. public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”; } def p = new Person() def last = p.lastName p.firstName = “Agent” Properties in GroovyFX 29 Get and set values
  • 30. public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”; } def p = new Person() def last = p.lastName p.firstName = “Agent” textField(text: bind(p.lastNameProperty())) Properties in GroovyFX 30 Access underlying property for binding
  • 31. Binding in GroovyFX @FXBindable class Time { Integer hours Integer minutes Integer seconds Double hourAngle Double minuteAngle Double secondAngle public Time() { // bind the angle properties to the clock time hourAngleProperty().bind((hoursProperty() * 30.0) + (minutesProperty() * 0.5)) minuteAngleProperty().bind(minutesProperty() * 6.0) secondAngleProperty().bind(secondsProperty() * 6.0) } } 31
  • 32. Animation in GroovyFX timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { at (1000.ms) { change(rect1, 'x') to 200 tweenease_both change rect2.yProperty() to 200 tween linear } }.play() 32
  • 33. timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { at (1000.ms) { change(rect1, 'x') to 200 tweenease_both change rect2.yProperty() to 200 tween linear } }.play() Animation in GroovyFX 33 Easy animation syntax: at (duration) {keyframes}
  • 34. timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { at (1000.ms) { change(rect1, 'x') to 200 change rect2.yProperty() to 200 } }.play() Animation in GroovyFX 34 Key frame DSL
  • 35. timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { at (1000.ms) { change(rect1, 'x') to 200 tweenease_both change rect2.yProperty() to 200tween linear } }.play() Animation in GroovyFX 35 Optional easing
  • 36. Event Listeners in GroovyFX 36 Supported using the built-in Closure syntax Optional arguments for event objects onMouseClicked { e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play() }
  • 37. Event Listeners in GroovyFX Supported using the built-in Closure syntax Optional arguments for event objects 37 onMouseClicked {MouseEvente -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play() } Compact syntax {body}
  • 38. Event Listeners in GroovyFX Supported using the built-in Closure syntax Optional arguments for event objects 38 Optional event parameter {event -> body} onMouseClicked { MouseEvente -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play() }
  • 39. TableView in Java 39 ObservableList<Person> items = ... TableView<Person> tableView = new TableView<Person>(items); TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name"); firstNameCol.setCellValueFactory( new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() { public ObservableValue<String> call(CellDataFeatures<Person, String> p) { return p.getValue().firstNameProperty(); } }); tableView.getColumns().add(firstNameCol);
  • 40. TableView in GroovyFX 40 def dateFormat = new SimpleDateFormat("yyyy-MM-dd"); tableView(items: persons) { tableColumn(property: "name", text: "Name", prefWidth: 150) tableColumn(property: "age", text: "Age", prefWidth: 50) tableColumn(property: "gender", text: "Gender", prefWidth: 150) tableColumn(property: "dob", text: "Birth", prefWidth: 150, type: Date, converter: { from -> return dateFormat.format(from) }) }
  • 41. Layout in Java 41 TextFieldurlField = new TextField(“http://www.google.com”); HBox.setHgrow(urlField, Priority.ALWAYS); HBoxhbox = new HBox(); hbox.getChildren().add(urlField); WebViewwebView = new WebView(); VBox.setVgrow(webView, Priority.ALWAYS); VBoxvbox = new VBox(); vbox.getChildren().addAll(hbox, webView);
  • 42. Layout in GroovyFX 42 sg.stage(title: "GroovyFXWebView Demo", show: true) { scene(fill: groovyblue, width: 1024, height: 800) { vbox{ hbox(padding: 10, spacing: 5) { textField(“http://www.yahoo.com”, hgrow: "always") button("Go”) } webView(vgrow: "always") } } }
  • 44. Layout in GroovyFX 44 gridPane(hgap: 5, vgap: 10, padding: 25) { columnConstraints(minWidth: 50, halignment: "right") columnConstraints(prefWidth: 250) label("Send Us Your Feedback", font: "24pt sanserif", row: 0, columnSpan: GridPane.REMAINING, halignment: "center", margin: [0, 0, 10]) label("Name: ", row: 1, column: 0) textField(promptText: "Your name", row: 1, column: 1, hgrow: 'always') label("Email:", row: 2, column: 0) textField(promptText: "Your email", row: 2, column: 1, hgrow: 'always') label("Message:", row: 3, column: 0, valignment: "baseline") textArea(row: 3, column: 1, hgrow: "always", vgrow: "always") button("Send Message", row: 4, column: 1, halignment: "right") }
  • 48. 48 JavaFX With Clojure Artwork by Augusto Sellhorn http://sellmic.com/
  • 49. 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! 49 (def hello (fn [] "Hello world")) (hello)
  • 50. Clojure Syntax in One Slide Symbols numbers – 2.178 ratios – 355/113 strings – “clojure”, “rocks” characters – 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} 50 (plus macros that are syntactic sugar wrapping the above)
  • 51. Clojure GUI Example (defnjavafxapp [] (let [stage (Stage. "JavaFX Stage") scene (Scene.)] (.setFill scene Color/LIGHTGREEN) (.setWidth stage 600) (.setHeight stage 450) (.setScene stage scene) (.setVisible stage true))) (javafxapp) 51
  • 52. Refined Clojure GUI Example (defnjavafxapp [] (doto (Stage. "JavaFX Stage") (.setWidth600) (.setHeight450) (.setScene (doto (Scene.) (.setFillColor/LIGHTGREEN) (.setContent (list (doto (Rectangle.) (.setX25) (.setY40) (.setWidth100) (.setHeight50) (.setFillColor/RED)))))) (.setVisibletrue))) (javafxapp) 52
  • 53. Refined Clojure GUI Example (defnjavafxapp [] (doto (Stage. "JavaFX Stage") (.setWidth 600) (.setHeight 450) (.setScene (doto (Scene.) (.setFillColor/LIGHTGREEN) (.setContent (list (doto (Rectangle.) (.setX 25) (.setY 40) (.setWidth 100) (.setHeight 50) (.setFillColor/RED)))))) (.setVisible true))) (javafxapp) 53 Doto allows nested data structures
  • 54. Closures in Clojure 54 Inner classes can be created using proxy (.addListenerhoverProperty (proxy [ChangeListener] [] (handle [p, o, v] (.setFillrect (if (.isHoverrect) Color/GREEN Color/RED)))))
  • 55. Closures in Clojure Inner classes can be created using proxy 55 Proxy form: (proxy [class] [args] fs+) f => (name [params*] body) (.addListenerhoverProperty (proxy[ChangeListener][] (handle [p, o, v] (.setFillrect (if (.isHoverrect) Color/GREEN Color/RED)))))
  • 56. 56 JavaFX With Scala
  • 57. What is Scala Started in 2001 by Martin Odersky Compiles to Java bytecodes Pure object-oriented language Also a functional programming language 57
  • 58. 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 Type Safe DSLs! Implicit Conversions – type safe class extension Operator Overloading – with standard precedence rules DelayedInit / @specialized – advanced language features 58
  • 59. Java vs. Scala DSL public class HelloStage extends Application { public void start(Stage 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); scene.setRoot(new Group(rect)); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(HelloStage.class, args); } } object HelloJavaFX extends JFXApp { stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = LIGHTGREEN content = Seq(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = RED }) } } } 59 21 Lines 430 Characters 17 Lines 177 Characters
  • 60. object DisappearingCirclesextends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } 60
  • 61. 61 object DisappearingCirclesextends JFXApp{ stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } Base class for JavaFX applications
  • 62. 62 object DisappearingCirclesextends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } Declarative Stage definition
  • 63. 63 object DisappearingCirclesextends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } Inline property definitions
  • 64. 64 object DisappearingCirclesextends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } Sequence Creation Via Loop
  • 65. Binding in Scala Infix Addition/Subtraction/Multiplication/Division: height <== rect1.height + rect2.height Aggregate Operators: width <== max(rect1.width, rect2.width, rect3.width) Conditional Expressions: strokeWidth <== when (hover) then 4 otherwise 0 Compound Expressions: text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled" 65
  • 66. Animation in Scala valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); 66
  • 67. valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); Animation in Scala 67 JavaFX Script-like animation syntax: at (duration) {keyframes}
  • 68. valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); Animation in Scala 68 Operator overloading for animation syntax
  • 69. valtimeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX-> random * stage.widthtween EASE_BOTH, circle.centerY-> random * stage.heighttween EASE_IN ) } } timeline.play(); Animation in Scala 69 Optional tween syntax
  • 70. Event Listeners in Scala 70 Supported using the built-in Closure syntax Optional arguments for event objects 100% type-safe onMouseClicked= { Timeline(at(3 s){radius->0}).play() }
  • 71. Event Listeners in Scala Supported using the built-in Closure syntax Optional arguments for event objects 100% type-safe 71 onMouseClicked= { Timeline(at(3 s){radius->0}).play() } Compact syntax {body}
  • 72. Event Listeners in Scala Supported using the built-in Closure syntax Optional arguments for event objects 100% type-safe 72 Optional event parameter {(event) => body} onMouseClicked= { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() }
  • 73. Other JVM Languages to Try JRuby Faithful to Ruby language with the power of the JVM Gosu Up and coming language created at GuideWire Easy to enhance libraries and create DSLs Mirah Invented by Charles Nutter Local Type Inference, Static and Dynamic Typing Fantom Created by Brian and Andy Frank Portable to Java and .NET Local Type Inference, Static and Dynamic Typing 73
  • 74. 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 } 74
  • 75. 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 75 Fantom has a built-in Duration type And also supports operator overloading
  • 76.
  • 77. How about JavaFX on… Visage Stage { title: "Hello Stage" width: 600 height: 450 scene: Scene { fill: Color.LIGHTGREEN content: Rectangle { x: 25 y: 40 width: 100 height: 50 fill: Color.RED } } } 77
  • 78. How about JavaFX on… Visage Stage { title: "Hello Stage" width: 600 height: 450 scene: Scene { fill: Color.LIGHTGREEN content: Rectangle { x: 25 y: 40 width: 100 height: 50 fill: Color.RED } } } 78
  • 79. 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 } } } 79
  • 80. Visage is JavaFX Script++ Default Parameters New Literal Syntax For: Angles – 35deg, 4rad, 1turn Colors –#DDCCBB, #AA33AA|CC Lengths – 5px, 2pt, 3in, 4sp Null-check Dereference var width = rect.!width Built-in Bindable Maps (coming soon!) varfruitMap = ["red" : apple, "yellow" : banana] var fruit = bind fruitMap["red"] 80
  • 81. Visage and JavaFX 2.0 are made for each other… Enhanced Binding Retains lazy evaluation properties with additional expressive power Integrated Collections Sequences and Maps automatically convert between JavaFX Observable Lists/Maps Built-in Animation Syntax Ties into JavaFX animation subsystem Provides consistent, clean APIs 81
  • 82. Conclusion You can write JavaFX applications in pure Java JavaFX is also usable in alternate languages You can get improved support using DSL libraries GroovyFX ScalaFX Or a dedicated UI JVM Language Visage
  • 83. Pro JavaFX 2 Platform Coming Soon! Coming 4th quarter this year All examples rewritten in Java Covers the new JavaFX 2.0 APIs Will includes ScalaFX, GroovyFX, and Visage 83
  • 84. 84 Stephen Chin steveonjava@gmail.com tweet: @steveonjava Dean Iverson dean@pleasingsoftware.com tweet: @deanriverson

Hinweis der Redaktion

  1. Stage.add??