Your SlideShare is downloading. ×
JavaFX 2.0 With Alternative Languages - JavaOne 2011
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

JavaFX 2.0 With Alternative Languages - JavaOne 2011

7,666
views

Published on

JavaFX 2.0 With Alternative Langauges Talk Given at JavaOne 2011 with Dean Iverson. …

JavaFX 2.0 With Alternative Langauges Talk Given at JavaOne 2011 with Dean Iverson.

Covers ScalaFX, GroovyFX, Visage, and Clojure

Published in: Technology, Education

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,666
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
37
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Stage.add??
  • Transcript

    • 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.
    • 4. JavaFX With Java
    • 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
    • 17. JavaFX With Groovy
    • 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")
      }
      }
      }
    • 43. Layout in GroovyFX
      43
    • 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")
      }
    • 45. Layout in GroovyFX
      45
    • 46. GroovyFX Supports…
      46
    • 47. GroovyFX Supports…
      47
    • 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 – 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}
      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. About Project Visage
      76
      • “Visage is a domain specific language (DSL) designed for the express purpose of writing user interfaces.”
      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/
    • 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