JavaFX 2.0 With Alternative Languages<br />Stephen Chin<br />Chief Agile Methodologist, GXS<br />steveonjava@gmail.com<br ...
Meet the Presenters<br />Stephen Chin<br />Dean Iverson<br />Family Man<br />Family Man<br />Motorcyclist<br />Geek<br />
Disclaimer: This is Code-Heavy<br />THE FOLLOWING IS INTENDED TO STIMULATE CREATIVE USE OF JVM LANGUAGES. AFTER WATCHING T...
JavaFX With Java<br />
Programming Languages<br />JavaFX 2.0 APIs are now in Java<br />Pure Java APIs for all of JavaFX<br />Bindingand Sequences...
JavaFX in Java<br />JavaFX API uses an enhanced JavaBeans pattern<br />Similar in feel to other UI toolkits (Swing, Apache...
Example Application<br />public class HelloStage extends Application {<br />  @Override public void start(Stage stage) {<b...
Example Application Using Builders<br />public class HelloStage extends Application {<br />  @Override public void start(S...
Binding<br />Unquestionably the biggest JavaFX Script innovation<br />Supported via a PropertyBindingclass<br />Lazy invoc...
Observable Pseudo-Properties<br />Supports watching for changes to properties<br />Implemented via anonymous inner classes...
Observable Pseudo-Properties<br />final Rectangle rect = new Rectangle();<br />rect.setX(40);<br />rect.setY(40);<br />rec...
Observable Pseudo-Properties<br />final Rectangle rect = new Rectangle();<br />rect.setX(40);<br />rect.setY(40);<br />rec...
Observable Pseudo-Properties<br />final Rectangle rect = new Rectangle();<br />rect.setX(40);<br />rect.setY(40);<br />rec...
Observable Pseudo-Properties<br />final Rectangle rect = new Rectangle();<br />rect.setX(40);<br />rect.setY(40);<br />rec...
Observable Pseudo-Properties<br />final Rectangle rect = new Rectangle();<br />rect.setX(40);<br />rect.setY(40);<br />rec...
Sequences in Java<br />Replaced with an Observable List<br />Public API is based on JavaFX sequences<br />Internal code ca...
JavaFX With Groovy<br />
Features of Groovy<br />Modern language<br />Closures<br />AST Transforms<br />Strongly typed dynamic language<br />Tight ...
Java vs. GroovyFX DSL<br />public class HelloStage extends Application {<br />  public void start(Stage stage) {<br />stag...
def sg = new SceneGraphBuilder()<br />def hc = { hover -> hover ? 4 : 0 }<br />sg.stage(title: 'Vanishing Circles', show: ...
21<br />def sg = new SceneGraphBuilder()<br />def hc = { hover -> hover ? 4 : 0 }<br />sg.stage(title: 'Vanishing Circles'...
22<br />def sg = new SceneGraphBuilder()<br />def hc = { hover -> hover ? 4 : 0 }<br />sg.stage(title: 'Vanishing Circles'...
23<br />def sg = new SceneGraphBuilder()<br />def hc = { hover -> hover ? 4 : 0 }<br />sg.stage(title: 'Vanishing Circles'...
24<br />def sg = new SceneGraphBuilder()<br />def hc = { hover -> hover ? 4 : 0 }<br />sg.stage(title: 'Vanishing Circles'...
25<br />def sg = new SceneGraphBuilder()<br />def hc = { hover -> hover ? 4 : 0 }<br />sg.stage(title: 'Vanishing Circles'...
Properties in Java<br />public class Person {<br />  private StringPropertyfirstName;<br />  public void setFirstName(Stri...
Properties in GroovyFX<br />public class Person {<br />  @FXBindable String firstName; <br />  @FXBindable String lastName...
public class Person {<br />  @FXBindable String firstName; <br />  @FXBindable String lastName= “Smith”;<br />}<br />Prope...
public class Person {<br />  @FXBindable String firstName; <br />  @FXBindable String lastName = “Smith”;<br />}<br />def ...
public class Person {<br />  @FXBindable String firstName; <br />  @FXBindable String lastName = “Smith”;<br />}<br />def ...
Binding in GroovyFX<br />@FXBindable<br />class Time {<br />  Integer hours<br />  Integer minutes<br />  Integer seconds<...
Animation in GroovyFX<br />timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {<br />  at (1000.ms) {<br />    c...
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {<br />at (1000.ms) {<br />    change(rect1, 'x') to 200 twee...
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {<br />  at (1000.ms) {<br />change(rect1, 'x') to 200<br /> ...
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {<br />  at (1000.ms) {<br />    change(rect1, 'x') to 200 tw...
Event Listeners in GroovyFX<br />36<br />Supported using the built-in Closure syntax<br />Optional arguments for event obj...
Event Listeners in GroovyFX<br />Supported using the built-in Closure syntax<br />Optional arguments for event objects<br ...
Event Listeners in GroovyFX<br />Supported using the built-in Closure syntax<br />Optional arguments for event objects<br ...
TableView in Java<br />39<br />ObservableList<Person> items = ...<br />TableView<Person> tableView = new TableView<Person>...
TableView in GroovyFX<br />40<br />def dateFormat = new SimpleDateFormat("yyyy-MM-dd");<br />tableView(items: persons) {<b...
Layout in Java<br />41<br />TextFieldurlField = new TextField(“http://www.google.com”);<br />HBox.setHgrow(urlField, Prior...
Layout in GroovyFX<br />42<br />sg.stage(title: "GroovyFXWebView Demo", show: true) {<br />scene(fill: groovyblue, width: ...
Layout in GroovyFX<br />43<br />
Layout in GroovyFX<br />44<br />gridPane(hgap: 5, vgap: 10, padding: 25) {<br />columnConstraints(minWidth: 50, halignment...
Layout in GroovyFX<br />45<br />
GroovyFX Supports…<br />46<br />
GroovyFX Supports…<br />47<br />
48<br />JavaFX With Clojure<br />Artwork by Augusto Sellhorn<br />http://sellmic.com/<br />
A Little About      Clojure<br />Started in 2007 by Rich Hickey<br />Functional Programming Language<br />Derived from LIS...
Clojure Syntax in One Slide<br />Symbols<br />numbers – 2.178<br />ratios – 355/113<br />strings – “clojure”, “rocks”<br /...
Clojure GUI Example<br />(defnjavafxapp []<br />  (let [stage (Stage. "JavaFX Stage")<br />        scene (Scene.)]<br />  ...
Refined Clojure GUI Example<br />(defnjavafxapp []<br />  (doto (Stage. "JavaFX Stage")<br />    (.setWidth600)<br />    (...
Refined Clojure GUI Example<br />(defnjavafxapp []<br />  (doto (Stage. "JavaFX Stage")<br />    (.setWidth 600)<br />    ...
Closures in Clojure<br />54<br />Inner classes can be created using proxy<br />(.addListenerhoverProperty<br />  (proxy [C...
Closures in Clojure<br />Inner classes can be created using proxy<br />55<br />Proxy form:<br />(proxy [class] [args] fs+)...
56<br />JavaFX With Scala<br />
What is Scala<br />Started in 2001 by Martin Odersky<br />Compiles to Java bytecodes<br />Pure object-oriented language<br...
Why Scala?<br />Shares many language features with JavaFX Script that make GUI programming easier:<br />Static Type Checki...
Java vs. Scala DSL<br />public class HelloStage extends Application {<br />  public void start(Stage stage) {<br />    sta...
object DisappearingCirclesextends JFXApp {<br />  stage = new Stage {<br />    title = "Disappearing Circles"<br />    wid...
61<br />object DisappearingCirclesextends JFXApp{<br />  stage = new Stage {<br />    title = "Disappearing Circles"<br />...
62<br />object DisappearingCirclesextends JFXApp {<br />  stage = new Stage {<br />    title = "Disappearing Circles"<br /...
63<br />object DisappearingCirclesextends JFXApp {<br />  stage = new Stage {<br />    title = "Disappearing Circles"<br /...
64<br />object DisappearingCirclesextends JFXApp {<br />  stage = new Stage {<br />    title = "Disappearing Circles"<br /...
Binding in Scala<br />Infix Addition/Subtraction/Multiplication/Division:<br />height <== rect1.height + rect2.height<br /...
Animation in Scala<br />valtimeline = new Timeline {<br />cycleCount = INDEFINITE<br />autoReverse = true<br />keyFrames =...
valtimeline = new Timeline {<br />cycleCount = INDEFINITE<br />autoReverse = true<br />keyFrames = for (circle <- circles)...
valtimeline = new Timeline {<br />cycleCount = INDEFINITE<br />autoReverse = true<br />keyFrames = for (circle <- circles)...
valtimeline = new Timeline {<br />cycleCount = INDEFINITE<br />autoReverse = true<br />keyFrames = for (circle <- circles)...
Event Listeners in Scala<br />70<br />Supported using the built-in Closure syntax<br />Optional arguments for event object...
Event Listeners in Scala<br />Supported using the built-in Closure syntax<br />Optional arguments for event objects<br />1...
Event Listeners in Scala<br />Supported using the built-in Closure syntax<br />Optional arguments for event objects<br />1...
Other JVM Languages to Try<br />JRuby<br />Faithful to Ruby language with the power of the JVM<br />Gosu<br />Up and comin...
Fantom Code Example<br />Void main() {<br />  Stage {<br />    title= "Hello Stage"<br />    width= 600<br />    height= 4...
timeline := Timeline {<br />  repeatCount = Timeline.INDEFINITE<br />  autoReverse = true<br />KeyFrame {<br />   time = 5...
About Project Visage<br />76<br /><ul><li>“Visage is a domain specific language (DSL) designed for the express purpose of ...
How about JavaFX on…  Visage<br />Stage {<br />  title: "Hello Stage"<br />  width: 600<br />  height: 450<br /> scene: Sc...
How about JavaFX on…  Visage<br />Stage {<br />  title: "Hello Stage"<br />  width: 600<br />  height: 450<br />scene: Sce...
How about JavaFX on…  Visage<br />Stage {<br />  title: "Hello Stage"<br />  width: 600<br />  height: 450<br /> Scene {<b...
Visage is JavaFX Script++<br />Default Parameters<br />New Literal Syntax For:<br />Angles – 35deg, 4rad, 1turn<br />Color...
Visage and JavaFX 2.0 are made for each other…<br />Enhanced Binding<br />Retains lazy evaluation properties with addition...
Conclusion<br />You can write JavaFX applications in pure Java<br />JavaFX is also usable in alternate languages<br />You ...
Pro JavaFX 2 Platform Coming Soon!<br />Coming 4th quarter this year<br />All examples rewritten in Java<br />Covers the n...
84<br />Stephen Chin<br />steveonjava@gmail.com<br />tweet: @steveonjava<br />Dean Iverson<br />dean@pleasingsoftware.com<...
Upcoming SlideShare
Loading in...5
×

JavaFX 2.0 With Alternative Languages - JavaOne 2011

7,902

Published on

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,902
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
38
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • Stage.add??
  • Transcript of "JavaFX 2.0 With Alternative Languages - JavaOne 2011"

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

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

    ×