SlideShare a Scribd company logo
JavaFX 2.0 With Alternative LanguagesStephen ChinChief Agile Methodologist, GXSsteveonjava@gmail.comtweet: @steveonjavaDean IversonVTTIdeanriverson@gmail.comtweet: @deanriverson
Meet the PresentersStephen ChinDean IversonFamily ManFamily ManMotorcyclistGeek
Disclaimer: This is Code-HeavyTHE 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 LanguagesJavaFX 2.0 APIs are now in JavaPure Java APIs for all of JavaFXBindingand Sequences exposed as Java APIsFXML Markup for toolingEmbrace all JVM languagesGroovy, Scala, Clojure, JRubyFantom, Mira, Gosu, Jython, etc.JavaFX Script is no longer supported by OracleExisting JavaFX Script based applications will continue to runVisageis the open-source successor to the JavaFX Script language
JavaFX in JavaJavaFX API uses an enhanced JavaBeans patternSimilar in feel to other UI toolkits (Swing, Apache Pivot, etc.)Uses builder pattern to minimize boilerplate
Example Applicationpublic 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 Builderspublic 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);  }}
BindingUnquestionably the biggest JavaFX Script innovationSupported via a PropertyBindingclassLazy invocation for high performanceStatic construction syntax for simple casese.g.: bind(<property>), bindBiDirectional(<property>)
Observable Pseudo-PropertiesSupports watching for changes to propertiesImplemented via anonymous inner classesWill take advantage of closures in the future
Observable Pseudo-Propertiesfinal Rectangle rect = new Rectangle();rect.setX(40);rect.setY(40);rect.setWidth(100);rect.setHeight(200);rect.hoverProperty().addListener(new ChangeListener<Boolean>() {});
Observable Pseudo-Propertiesfinal 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-Propertiesfinal 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-Propertiesfinal 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-Propertiesfinal 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 JavaReplaced with an Observable ListPublic API is based on JavaFX sequencesInternal code can use lighter collections APIJavaFX 2.0 also has an Observable Map
JavaFX With Groovy
Features of GroovyModern languageClosuresAST TransformsStrongly typed dynamic languageTight integration with JavaVery easy to port from Java to GroovyDeclarative syntax with GroovyFX BuildersFamiliar to Groovy and JavaFX Script developers
Java vs. GroovyFX DSLpublic 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)    }  }}198 Lines180 Characters21 Lines430 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
21def 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
22def 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
23def 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
24def 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
25def 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 Javapublic 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 GroovyFXpublic class Person {  @FXBindable String firstName;   @FXBindable String lastName;}27
public class Person {  @FXBindable String firstName;   @FXBindable String lastName= “Smith”;}Properties in GroovyFX28Optional initializers
public class Person {  @FXBindable String firstName;   @FXBindable String lastName = “Smith”;}def p = new Person()def last = p.lastNamep.firstName = “Agent”Properties in GroovyFX29Get and set values
public class Person {  @FXBindable String firstName;   @FXBindable String lastName = “Smith”;}def p = new Person()def last = p.lastNamep.firstName = “Agent”textField(text: bind(p.lastNameProperty()))Properties in GroovyFX30Access underlying property for binding
Binding in GroovyFX@FXBindableclass Time {  Integer hours  Integer minutes  Integer seconds  Double hourAngle  Double minuteAngle  Double secondAngle  public Time() {    // bind the angle properties to the clock timehourAngleProperty().bind((hoursProperty() * 30.0) + (minutesProperty() * 0.5))minuteAngleProperty().bind(minutesProperty() * 6.0)secondAngleProperty().bind(secondsProperty() * 6.0)  }}31
Animation in GroovyFXtimeline(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 GroovyFX33Easy 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 GroovyFX34Key frame DSL
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {  at (1000.ms) {    change(rect1, 'x') to 200 tweenease_bothchange rect2.yProperty() to 200tween linear  }}.play()Animation in GroovyFX35Optional easing
Event Listeners in GroovyFX36Supported using the built-in Closure syntaxOptional arguments for event objectsonMouseClicked { e ->  timeline {    at(3.s) { change e.source.radiusProperty() to 0 }  }.play()}
Event Listeners in GroovyFXSupported using the built-in Closure syntaxOptional arguments for event objects37onMouseClicked {MouseEvente ->  timeline {    at(3.s) { change e.source.radiusProperty() to 0 }  }.play()}Compact syntax{body}
Event Listeners in GroovyFXSupported using the built-in Closure syntaxOptional arguments for event objects38Optional event parameter{event -> body}onMouseClicked { MouseEvente ->  timeline {    at(3.s) { change e.source.radiusProperty() to 0 }  }.play()}
TableView in Java39ObservableList<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 GroovyFX40def 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 Java41TextFieldurlField = 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 GroovyFX42sg.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 GroovyFX43
Layout in GroovyFX44gridPane(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 GroovyFX45
GroovyFX Supports…46
GroovyFX Supports…47
48JavaFX With ClojureArtwork by Augusto Sellhornhttp://sellmic.com/
A Little About      ClojureStarted in 2007 by Rich HickeyFunctional Programming LanguageDerived from LISPOptimized for High Concurrency… and looks nothing like Java!49(def hello (fn [] "Hello world"))(hello)
Clojure Syntax in One SlideSymbolsnumbers – 2.178ratios – 355/113strings – “clojure”, “rocks”characters – \a \b \c \dsymbols – a b c dkeywords – :alpha :betaboolean – true, falsenull - nilCollections(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)53Doto allows nested data structures
Closures in Clojure54Inner classes can be created using proxy(.addListenerhoverProperty  (proxy [ChangeListener] []    (handle [p, o, v]      (.setFillrect        (if (.isHoverrect) Color/GREEN Color/RED)))))
Closures in ClojureInner classes can be created using proxy55Proxy form:(proxy [class] [args] fs+) f => (name [params*] body)(.addListenerhoverProperty  (proxy[ChangeListener][]    (handle [p, o, v]      (.setFillrect        (if (.isHoverrect) Color/GREEN Color/RED)))))
56JavaFX With Scala
What is ScalaStarted in 2001 by Martin OderskyCompiles to Java bytecodesPure object-oriented languageAlso a functional programming language57
Why Scala?Shares many language features with JavaFX Script that make GUI programming easier:Static Type Checking – Catch your errors at compile timeClosures – Wrap behavior and pass it by referenceDeclarative – Express the UI by describing what it should look likeScala also supports Type Safe DSLs!Implicit Conversions – type safe class extensionOperator Overloading – with standard precedence rulesDelayedInit / @specialized – advanced language features58
Java vs. Scala DSLpublic 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      })    }  }}5921 Lines430 Characters17 Lines177 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 * 800centerY = random * 600        radius = 150        fill = color(random, random, random, 0.2)        effect = new BoxBlur(10, 10, 3)      }    }  }}60
61object 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 * 800centerY = random * 600        radius = 150        fill = color(random, random, random, 0.2)        effect = new BoxBlur(10, 10, 3)      }    }  }}Base class for JavaFX applications
62object 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 * 800centerY = random * 600        radius = 150        fill = color(random, random, random, 0.2)        effect = new BoxBlur(10, 10, 3)      }    }  }}Declarative Stage definition
63object 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 * 800centerY = random * 600        radius = 150        fill = color(random, random, random, 0.2)        effect = new BoxBlur(10, 10, 3)      }    }  }}Inline property definitions
64object 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 * 800centerY = random * 600        radius = 150        fill = color(random, random, random, 0.2)        effect = new BoxBlur(10, 10, 3)      }    }  }}Sequence Creation Via Loop
Binding in ScalaInfix Addition/Subtraction/Multiplication/Division:height <== rect1.height + rect2.heightAggregate Operators:width <== max(rect1.width, rect2.width, rect3.width)Conditional Expressions:strokeWidth <== when (hover) then 4 otherwise 0Compound Expressions:text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled"65
Animation in Scalavaltimeline = new Timeline {cycleCount = INDEFINITEautoReverse = truekeyFrames = 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 = INDEFINITEautoReverse = truekeyFrames = for (circle <- circles) yield at (40 s) {Set(circle.centerX -> random * stage.width,circle.centerY -> random * stage.height)}}timeline.play();Animation in Scala67JavaFX Script-like animation syntax: at (duration) {keyframes}
valtimeline = new Timeline {cycleCount = INDEFINITEautoReverse = truekeyFrames = for (circle <- circles) yield at (40 s) {Set(circle.centerX -> random * stage.width,circle.centerY -> random * stage.height)}}timeline.play();Animation in Scala68Operator overloading for animation syntax
valtimeline = new Timeline {cycleCount = INDEFINITEautoReverse = truekeyFrames = 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 Scala69Optional tween syntax
Event Listeners in Scala70Supported using the built-in Closure syntaxOptional arguments for event objects100% type-safeonMouseClicked= {  Timeline(at(3 s){radius->0}).play()}
Event Listeners in ScalaSupported using the built-in Closure syntaxOptional arguments for event objects100% type-safe71onMouseClicked= {Timeline(at(3 s){radius->0}).play()}Compact syntax{body}
Event Listeners in ScalaSupported using the built-in Closure syntaxOptional arguments for event objects100% type-safe72Optional event parameter{(event) => body}onMouseClicked= { (e: MouseEvent) =>Timeline(at(3 s){radius->0}).play()}
Other JVM Languages to TryJRubyFaithful to Ruby language with the power of the JVMGosuUp and coming language created at GuideWireEasy to enhance libraries and create DSLsMirahInvented by Charles NutterLocal Type Inference, Static and Dynamic TypingFantomCreated by Brian and Andy FrankPortable to Java and .NETLocal Type Inference, Static and Dynamic Typing73
Fantom Code ExampleVoid 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 = trueKeyFrame {   time = 50msKeyValue(rect1.x()-> 300),    KeyValue(rect2.y() -> 500),    KeyValue(rect2.width() -> 150)}}Animation in Fantom75Fantom has a built-in Duration typeAnd also supports operator overloading
About Project Visage76“Visage is a domain specific language (DSL) designed for the express purpose of writing user interfaces.”Visage project goals:Compile to JavaFX Java APIsEvolve the Language (Annotations, Maps, etc.)Support Other ToolkitsCome join the team!For more info: http://visage-lang.org/
How about JavaFX on…  VisageStage {  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…  VisageStage {  title: "Hello Stage"  width: 600  height: 450scene: Scene {    fill: Color.LIGHTGREENcontent: Rectangle {      x: 25      y: 40      width: 100      height: 50      fill: Color.RED    }  }}78
How about JavaFX on…  VisageStage {  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 ParametersNew Literal Syntax For:Angles – 35deg, 4rad, 1turnColors –#DDCCBB, #AA33AA|CCLengths – 5px, 2pt, 3in, 4spNull-check Dereferencevar width = rect.!widthBuilt-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 BindingRetains lazy evaluation properties with additional expressive powerIntegrated CollectionsSequences and Maps automatically convert between JavaFX Observable Lists/MapsBuilt-in Animation SyntaxTies into JavaFX animation subsystemProvides consistent, clean APIs81
ConclusionYou can write JavaFX applications in pure JavaJavaFX is also usable in alternate languagesYou can get improved support using DSL librariesGroovyFXScalaFXOr a dedicated UI JVM LanguageVisage
Pro JavaFX 2 Platform Coming Soon!Coming 4th quarter this yearAll examples rewritten in JavaCovers the new JavaFX 2.0 APIsWill includes ScalaFX, GroovyFX, and Visage83
84Stephen Chinsteveonjava@gmail.comtweet: @steveonjavaDean Iversondean@pleasingsoftware.comtweet: @deanriverson

More Related Content

PPTX
Hacking JavaFX with Groovy, Clojure, Scala, and Visage
PPTX
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
PPT
Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
PPTX
JavaFX and Scala - Like Milk and Cookies
PDF
Mary Had a Little λ (QCon)
PDF
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
PPTX
ScalaDays 2014 - Reactive Scala 3D Game Engine
PPTX
Moving from JFreeChart to JavaFX with JavaFX Chart Extensions
Hacking JavaFX with Groovy, Clojure, Scala, and Visage
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
JavaFX and Scala - Like Milk and Cookies
Mary Had a Little λ (QCon)
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
ScalaDays 2014 - Reactive Scala 3D Game Engine
Moving from JFreeChart to JavaFX with JavaFX Chart Extensions

What's hot (16)

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

Viewers also liked (7)

PPTX
Visage Android - Cleaner APIs, Cleaner UIs
PPTX
JavaFX and Scala in the Cloud
PDF
Orishas mitos-y-leyendas
PDF
Efficient JavaScript Unit Testing, March 2013
PPTX
Beginning Android Flash Development - GTUG Edition
PDF
DukeScript
PPTX
JCrete Embedded Java Workshop
Visage Android - Cleaner APIs, Cleaner UIs
JavaFX and Scala in the Cloud
Orishas mitos-y-leyendas
Efficient JavaScript Unit Testing, March 2013
Beginning Android Flash Development - GTUG Edition
DukeScript
JCrete Embedded Java Workshop
Ad

Similar to JavaFX 2.0 With Alternative Languages - JavaOne 2011 (20)

PPTX
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
ODP
Java Fx Overview Tech Tour
PPTX
JavaFX 2.0 and Alternative Languages
PPT
Intro to JavaFX & Widget FX
PDF
JavaFX Overview
ODP
JavaFX introduction
PDF
Greach, GroovyFx Workshop
PPTX
The Java Fx Platform – A Java Developer’S Guide
PPTX
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
PDF
Groovy's Builder
PPTX
JavaFX 2.0 With Alternative Languages [Portuguese]
PDF
PPTX
JavaFX Your Way - Devoxx Version
PPTX
Raspberry Pi à la GroovyFX
ODP
JavaFXScript
PDF
Javafx Overview 90minutes
PDF
Javafx Overview 90minutes
PDF
Javafx Overview 90minutes
PDF
Don't panic in Fortaleza - ScalaFX
PDF
Java Fx Ajaxworld Rags V1
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
Java Fx Overview Tech Tour
JavaFX 2.0 and Alternative Languages
Intro to JavaFX & Widget FX
JavaFX Overview
JavaFX introduction
Greach, GroovyFx Workshop
The Java Fx Platform – A Java Developer’S Guide
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
Groovy's Builder
JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX Your Way - Devoxx Version
Raspberry Pi à la GroovyFX
JavaFXScript
Javafx Overview 90minutes
Javafx Overview 90minutes
Javafx Overview 90minutes
Don't panic in Fortaleza - ScalaFX
Java Fx Ajaxworld Rags V1

More from Stephen Chin (20)

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

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PDF
Machine learning based COVID-19 study performance prediction
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Cloud computing and distributed systems.
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Electronic commerce courselecture one. Pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Approach and Philosophy of On baking technology
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
cuic standard and advanced reporting.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Empathic Computing: Creating Shared Understanding
PDF
NewMind AI Weekly Chronicles - August'25 Week I
Teaching material agriculture food technology
Machine learning based COVID-19 study performance prediction
Per capita expenditure prediction using model stacking based on satellite ima...
Diabetes mellitus diagnosis method based random forest with bat algorithm
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Cloud computing and distributed systems.
20250228 LYD VKU AI Blended-Learning.pptx
Electronic commerce courselecture one. Pdf
Encapsulation_ Review paper, used for researhc scholars
Approach and Philosophy of On baking technology
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Chapter 3 Spatial Domain Image Processing.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Spectral efficient network and resource selection model in 5G networks
“AI and Expert System Decision Support & Business Intelligence Systems”
cuic standard and advanced reporting.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Empathic Computing: Creating Shared Understanding
NewMind AI Weekly Chronicles - August'25 Week I

JavaFX 2.0 With Alternative Languages - JavaOne 2011

  • 1. JavaFX 2.0 With Alternative LanguagesStephen ChinChief Agile Methodologist, GXSsteveonjava@gmail.comtweet: @steveonjavaDean IversonVTTIdeanriverson@gmail.comtweet: @deanriverson
  • 2. Meet the PresentersStephen ChinDean IversonFamily ManFamily ManMotorcyclistGeek
  • 3. Disclaimer: This is Code-HeavyTHE 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 LanguagesJavaFX 2.0 APIs are now in JavaPure Java APIs for all of JavaFXBindingand Sequences exposed as Java APIsFXML Markup for toolingEmbrace all JVM languagesGroovy, Scala, Clojure, JRubyFantom, Mira, Gosu, Jython, etc.JavaFX Script is no longer supported by OracleExisting JavaFX Script based applications will continue to runVisageis the open-source successor to the JavaFX Script language
  • 6. JavaFX in JavaJavaFX API uses an enhanced JavaBeans patternSimilar in feel to other UI toolkits (Swing, Apache Pivot, etc.)Uses builder pattern to minimize boilerplate
  • 7. Example Applicationpublic 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 Builderspublic 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. BindingUnquestionably the biggest JavaFX Script innovationSupported via a PropertyBindingclassLazy invocation for high performanceStatic construction syntax for simple casese.g.: bind(<property>), bindBiDirectional(<property>)
  • 10. Observable Pseudo-PropertiesSupports watching for changes to propertiesImplemented via anonymous inner classesWill take advantage of closures in the future
  • 11. Observable Pseudo-Propertiesfinal 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-Propertiesfinal 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-Propertiesfinal 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-Propertiesfinal 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-Propertiesfinal 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 JavaReplaced with an Observable ListPublic API is based on JavaFX sequencesInternal code can use lighter collections APIJavaFX 2.0 also has an Observable Map
  • 18. Features of GroovyModern languageClosuresAST TransformsStrongly typed dynamic languageTight integration with JavaVery easy to port from Java to GroovyDeclarative syntax with GroovyFX BuildersFamiliar to Groovy and JavaFX Script developers
  • 19. Java vs. GroovyFX DSLpublic 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) } }}198 Lines180 Characters21 Lines430 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. 21def 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. 22def 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. 23def 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. 24def 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. 25def 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 Javapublic 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 GroovyFXpublic class Person { @FXBindable String firstName; @FXBindable String lastName;}27
  • 28. public class Person { @FXBindable String firstName; @FXBindable String lastName= “Smith”;}Properties in GroovyFX28Optional initializers
  • 29. public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”;}def p = new Person()def last = p.lastNamep.firstName = “Agent”Properties in GroovyFX29Get and set values
  • 30. public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”;}def p = new Person()def last = p.lastNamep.firstName = “Agent”textField(text: bind(p.lastNameProperty()))Properties in GroovyFX30Access underlying property for binding
  • 31. Binding in GroovyFX@FXBindableclass Time { Integer hours Integer minutes Integer seconds Double hourAngle Double minuteAngle Double secondAngle public Time() { // bind the angle properties to the clock timehourAngleProperty().bind((hoursProperty() * 30.0) + (minutesProperty() * 0.5))minuteAngleProperty().bind(minutesProperty() * 6.0)secondAngleProperty().bind(secondsProperty() * 6.0) }}31
  • 32. Animation in GroovyFXtimeline(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 GroovyFX33Easy 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 GroovyFX34Key frame DSL
  • 35. timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { at (1000.ms) { change(rect1, 'x') to 200 tweenease_bothchange rect2.yProperty() to 200tween linear }}.play()Animation in GroovyFX35Optional easing
  • 36. Event Listeners in GroovyFX36Supported using the built-in Closure syntaxOptional arguments for event objectsonMouseClicked { e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play()}
  • 37. Event Listeners in GroovyFXSupported using the built-in Closure syntaxOptional arguments for event objects37onMouseClicked {MouseEvente -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play()}Compact syntax{body}
  • 38. Event Listeners in GroovyFXSupported using the built-in Closure syntaxOptional arguments for event objects38Optional event parameter{event -> body}onMouseClicked { MouseEvente -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play()}
  • 39. TableView in Java39ObservableList<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 GroovyFX40def 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 Java41TextFieldurlField = 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 GroovyFX42sg.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 GroovyFX44gridPane(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. 48JavaFX With ClojureArtwork by Augusto Sellhornhttp://sellmic.com/
  • 49. A Little About ClojureStarted in 2007 by Rich HickeyFunctional Programming LanguageDerived from LISPOptimized for High Concurrency… and looks nothing like Java!49(def hello (fn [] "Hello world"))(hello)
  • 50. Clojure Syntax in One SlideSymbolsnumbers – 2.178ratios – 355/113strings – “clojure”, “rocks”characters – \a \b \c \dsymbols – a b c dkeywords – :alpha :betaboolean – true, falsenull - nilCollections(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)53Doto allows nested data structures
  • 54. Closures in Clojure54Inner classes can be created using proxy(.addListenerhoverProperty (proxy [ChangeListener] [] (handle [p, o, v] (.setFillrect (if (.isHoverrect) Color/GREEN Color/RED)))))
  • 55. Closures in ClojureInner classes can be created using proxy55Proxy form:(proxy [class] [args] fs+) f => (name [params*] body)(.addListenerhoverProperty (proxy[ChangeListener][] (handle [p, o, v] (.setFillrect (if (.isHoverrect) Color/GREEN Color/RED)))))
  • 57. What is ScalaStarted in 2001 by Martin OderskyCompiles to Java bytecodesPure object-oriented languageAlso a functional programming language57
  • 58. Why Scala?Shares many language features with JavaFX Script that make GUI programming easier:Static Type Checking – Catch your errors at compile timeClosures – Wrap behavior and pass it by referenceDeclarative – Express the UI by describing what it should look likeScala also supports Type Safe DSLs!Implicit Conversions – type safe class extensionOperator Overloading – with standard precedence rulesDelayedInit / @specialized – advanced language features58
  • 59. Java vs. Scala DSLpublic 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 }) } }}5921 Lines430 Characters17 Lines177 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 * 800centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } }}60
  • 61. 61object 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 * 800centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } }}Base class for JavaFX applications
  • 62. 62object 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 * 800centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } }}Declarative Stage definition
  • 63. 63object 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 * 800centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } }}Inline property definitions
  • 64. 64object 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 * 800centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } }}Sequence Creation Via Loop
  • 65. Binding in ScalaInfix Addition/Subtraction/Multiplication/Division:height <== rect1.height + rect2.heightAggregate Operators:width <== max(rect1.width, rect2.width, rect3.width)Conditional Expressions:strokeWidth <== when (hover) then 4 otherwise 0Compound Expressions:text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled"65
  • 66. Animation in Scalavaltimeline = new Timeline {cycleCount = INDEFINITEautoReverse = truekeyFrames = 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 = INDEFINITEautoReverse = truekeyFrames = for (circle <- circles) yield at (40 s) {Set(circle.centerX -> random * stage.width,circle.centerY -> random * stage.height)}}timeline.play();Animation in Scala67JavaFX Script-like animation syntax: at (duration) {keyframes}
  • 68. valtimeline = new Timeline {cycleCount = INDEFINITEautoReverse = truekeyFrames = for (circle <- circles) yield at (40 s) {Set(circle.centerX -> random * stage.width,circle.centerY -> random * stage.height)}}timeline.play();Animation in Scala68Operator overloading for animation syntax
  • 69. valtimeline = new Timeline {cycleCount = INDEFINITEautoReverse = truekeyFrames = 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 Scala69Optional tween syntax
  • 70. Event Listeners in Scala70Supported using the built-in Closure syntaxOptional arguments for event objects100% type-safeonMouseClicked= { Timeline(at(3 s){radius->0}).play()}
  • 71. Event Listeners in ScalaSupported using the built-in Closure syntaxOptional arguments for event objects100% type-safe71onMouseClicked= {Timeline(at(3 s){radius->0}).play()}Compact syntax{body}
  • 72. Event Listeners in ScalaSupported using the built-in Closure syntaxOptional arguments for event objects100% type-safe72Optional event parameter{(event) => body}onMouseClicked= { (e: MouseEvent) =>Timeline(at(3 s){radius->0}).play()}
  • 73. Other JVM Languages to TryJRubyFaithful to Ruby language with the power of the JVMGosuUp and coming language created at GuideWireEasy to enhance libraries and create DSLsMirahInvented by Charles NutterLocal Type Inference, Static and Dynamic TypingFantomCreated by Brian and Andy FrankPortable to Java and .NETLocal Type Inference, Static and Dynamic Typing73
  • 74. Fantom Code ExampleVoid 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 = trueKeyFrame { time = 50msKeyValue(rect1.x()-> 300), KeyValue(rect2.y() -> 500), KeyValue(rect2.width() -> 150)}}Animation in Fantom75Fantom has a built-in Duration typeAnd also supports operator overloading
  • 76. About Project Visage76“Visage is a domain specific language (DSL) designed for the express purpose of writing user interfaces.”Visage project goals:Compile to JavaFX Java APIsEvolve the Language (Annotations, Maps, etc.)Support Other ToolkitsCome join the team!For more info: http://visage-lang.org/
  • 77. How about JavaFX on… VisageStage { 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… VisageStage { title: "Hello Stage" width: 600 height: 450scene: Scene { fill: Color.LIGHTGREENcontent: Rectangle { x: 25 y: 40 width: 100 height: 50 fill: Color.RED } }}78
  • 79. How about JavaFX on… VisageStage { 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 ParametersNew Literal Syntax For:Angles – 35deg, 4rad, 1turnColors –#DDCCBB, #AA33AA|CCLengths – 5px, 2pt, 3in, 4spNull-check Dereferencevar width = rect.!widthBuilt-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 BindingRetains lazy evaluation properties with additional expressive powerIntegrated CollectionsSequences and Maps automatically convert between JavaFX Observable Lists/MapsBuilt-in Animation SyntaxTies into JavaFX animation subsystemProvides consistent, clean APIs81
  • 82. ConclusionYou can write JavaFX applications in pure JavaJavaFX is also usable in alternate languagesYou can get improved support using DSL librariesGroovyFXScalaFXOr a dedicated UI JVM LanguageVisage
  • 83. Pro JavaFX 2 Platform Coming Soon!Coming 4th quarter this yearAll examples rewritten in JavaCovers the new JavaFX 2.0 APIsWill includes ScalaFX, GroovyFX, and Visage83
  • 84. 84Stephen Chinsteveonjava@gmail.comtweet: @steveonjavaDean Iversondean@pleasingsoftware.comtweet: @deanriverson

Editor's Notes