SlideShare una empresa de Scribd logo
1 de 46
JavaFX and Scala – Like Milk and Cookies
    Stephen Chin                Luc Duponcheel
    JavaFX Evangelist, Oracle   Independent, ImagineJ
    steveonjava@gmail.com       luc.duponcheel@gmail.com
    tweet: @steveonjava         tweet: @LucDup
Meet the Presenters

        Stephen Chin                 Luc Duponcheel


  Family Man




                 Motorcyclist                    BeJUG


                                Researcher
JavaFX 2.0 Platform
Immersive Application Experience
>   Cross-platform
    Animation, Video, Charting
>   Integrate Java, JavaScript, and
    HTML5 in the same application
>   New graphics stack takes
    advantage of hardware
    acceleration for 2D and 3D
    applications
>   Use your favorite IDE:
    NetBeans, Eclipse, IntelliJ, etc.
JavaFX




Scala




                 4
JavaFX With Java
JavaFX in Java
>   JavaFX API uses an enhanced JavaBeans
    pattern
>   Similar in feel to other UI toolkits (Swing,
    Pivot, etc.)
>   Uses builder pattern to minimize boilerplate
Vanishing Circles




                    7
Application Skeleton
public class VanishingCircles extends Application {
  public static void main(String[] args) {
    Application.launch(args);
  }
  @Override
  public void start(Stage primaryStage) {
    primaryStage.setTitle("Vanishing Circles");
    Group root = new Group();
    Scene scene = new Scene(root, 800, 600, Color.BLACK);
    [create the circles…]
    root.getChildren().addAll(circles);
    primaryStage.setScene(scene);
    primaryStage.show();
    [begin the animation…]
  }
}
Create the Circles
List<Circle> circles = new ArrayList<Circle>();
for (int i = 0; i < 50; i++) {
  final Circle circle = new Circle(150);
  circle.setCenterX(Math.random() * 800);
  circle.setCenterY(Math.random() * 600);
  circle.setFill(new Color(Math.random(), Math.random(),
                           Math.random(), .2));
  circle.setEffect(new BoxBlur(10, 10, 3));
  circle.setStroke(Color.WHITE);
  [setup binding…]
  [setup event listeners…]
  circles.add(circle);
}


                                                      9
Setup Binding
circle.strokeWidthProperty().bind(Bindings
   .when(circle.hoverProperty())
   .then(4)
   .otherwise(0)
);




                                             10
Setup Event Listeners
circle.addEventHandler(MouseEvent.MOUSE_CLICKED,
                        new EventHandler<MouseEvent>() {
  public void handle(MouseEvent t) {
    KeyValue collapse = new KeyValue(circle.radiusProperty(), 0);
    new Timeline(new KeyFrame(Duration.seconds(3),
                              collapse)).play();
  }
});




                                                                    11
Begin the Animation
Timeline moveCircles = new Timeline();
for (Circle circle : circles) {
  KeyValue moveX = new KeyValue(circle.centerXProperty(),
                                Math.random() * 800);
  KeyValue moveY = new KeyValue(circle.centerYProperty(),
                                Math.random() * 600);
  moveCircles.getKeyFrames().add(new KeyFrame(Duration.seconds(40),
                                              moveX, moveY));
}
moveCircles.play();




                                                                  12
JavaFX With Scala




               13
Java vs. Scala DSL
public class VanishingCircles extends Application {                                   object VanishingCircles extends JFXApp {
                                                                                        var circles: Seq[Circle] = null
    public static void main(String[] args) {                                            stage = new Stage {
      Application.launch(args);                                                           title = "Vanishing Circles"
    }                                                                                     width = 800
                                                                                          height = 600
    @Override                                                                             scene = new Scene {
    public void start(Stage primaryStage) {                                                 fill = BLACK
      primaryStage.setTitle("Vanishing Circles");                                           circles = for (i <- 0 until 50) yield new Circle {
      Group root = new Group();                                                               centerX = random * 800
      Scene scene = new Scene(root, 800, 600, Color.BLACK);                                   centerY = random * 600
      List<Circle> circles = new ArrayList<Circle>();                                         radius = 150
      for (int i = 0; i < 50; i++) {                                                          fill = color(random, random, random, .2)
        final Circle circle = new Circle(150);                                                effect = new BoxBlur(10, 10, 3)

               40 Lines
        circle.setCenterX(Math.random() * 800);
        circle.setCenterY(Math.random() * 600);
        circle.setFill(new Color(Math.random(), Math.random(), Math.random(), .2));
        circle.setEffect(new BoxBlur(10, 10, 3));
                                                                                                     33 Lines
                                                                                              strokeWidth <== when (hover) then 4 otherwise 0
                                                                                              stroke = WHITE
                                                                                              onMouseClicked = {
                                                                                                Timeline(at (3 s) {radius -> 0}).play()


               1299 Characters
        circle.addEventHandler(MouseEvent.MOUSE_CLICKED, new
        EventHandler<MouseEvent>() {
          public void handle(MouseEvent t) {
            KeyValue collapse = new KeyValue(circle.radiusProperty(), 0);                 }
                                                                                            }
                                                                                              }
                                                                                                     591 Characters
                                                                                            content = circles

            new Timeline(new KeyFrame(Duration.seconds(3), collapse)).play();           }
          }
        });                                                                               new Timeline {
        circle.setStroke(Color.WHITE);                                                      cycleCount = INDEFINITE
        circle.strokeWidthProperty().bind(Bindings.when(circle.hoverProperty())             autoReverse = true
          .then(4)                                                                          keyFrames = for (circle <- circles) yield at (40 s) {
          .otherwise(0));                                                                     Set(
        circles.add(circle);                                                                    circle.centerX -> random * stage.width,
      }                                                                                         circle.centerY -> random * stage.height
      root.getChildren().addAll(circles);                                                     )
      primaryStage.setScene(scene);                                                         }
      primaryStage.show();                                                                }.play();
                                                                                      }
        Timeline moveCircles = new Timeline();
        for (Circle circle : circles) {
          KeyValue moveX = new KeyValue(circle.centerXProperty(), Math.random() *
          800);
          KeyValue moveY = new KeyValue(circle.centerYProperty(), Math.random() *
          600);
          moveCircles.getKeyFrames().add(new KeyFrame(Duration.seconds(40), moveX,
          moveY));
        }
        moveCircles.play();
    }
}



                                                                                                                                                    14
object VanishingCircles extends JFXApp {
  stage = new Stage {
    title = "Disappearing Circles"
    width = 800
    height = 600
    scene = new Scene {
      fill = BLACK
      content = for (i <- 0 until 50) yield new Circle {
        centerX = random * 800
        centerY = random * 600
        radius = 150
        fill = color(random, random, random, 0.2)
        effect = new BoxBlur(10, 10, 3)
      }
    }
  }
}

                                                           15
object VanishingCircles extends JFXApp {
  stage = new Stage {
    title = "Disappearing Circles"
    width = 800
    height = 600 class for JavaFX
            Base
                 applications
    scene = new Scene {
      fill = BLACK
      content = for (i <- 0 until 50) yield new Circle {
        centerX = random * 800
        centerY = random * 600
        radius = 150
        fill = color(random, random, random, 0.2)
        effect = new BoxBlur(10, 10, 3)
      }
    }
  }
}

                                                           16
object VanishingCircles extends JFXApp {
  stage = new Stage {
    title = "Disappearing Circles"
    width = 800
    height = 600                      Declarative Stage
    scene = new Scene {
      fill = BLACK
                                          definition
      content = for (i <- 0 until 50) yield new Circle {
        centerX = random * 800
        centerY = random * 600
        radius = 150
        fill = color(random, random, random, 0.2)
        effect = new BoxBlur(10, 10, 3)
      }
    }
  }
}

                                                           17
object VanishingCircles extends JFXApp {
  stage = new Stage {
    title = "Disappearing Circles"
    width = 800
                                          Inline property
    height = 600                            definitions
    scene = new Scene {
      fill = BLACK
      content = for (i <- 0 until 50) yield new Circle {
        centerX = random * 800
        centerY = random * 600
        radius = 150
        fill = color(random, random, random, 0.2)
        effect = new BoxBlur(10, 10, 3)
      }
    }
  }
}

                                                            18
object VanishingCircles extends JFXApp {
  stage = new Stage {
    title = "Disappearing Circles"
    width = 800                      Sequence Creation Via
    height = 600                              Loop
    scene = new Scene {
      fill = BLACK
      content = for (i <- 0 until 50) yield new Circle {
        centerX = random * 800
        centerY = random * 600
        radius = 150
        fill = color(random, random, random, 0.2)
        effect = new BoxBlur(10, 10, 3)
      }
    }
  }
}

                                                         19
Binding in Scala
Infix Addition/Subtraction/Multiplication/Division:
height <== rect1.height + rect2.height
Aggregate Operators:
width <== max(rect1.width, rect2.width,
  rect3.width)
Conditional Expressions:
strokeWidth <== when (hover) then 4 otherwise 0
Compound Expressions:
text <== when (rect.hover || circle.hover &&
  !disabled) then textField.text + " is enabled"
  otherwise "disabled"


                                                      20
Animation in Scala
val timeline = new Timeline {
  cycleCount = INDEFINITE
  autoReverse = true
  keyFrames = for (circle <- circles) yield
  at (40 s) {
    Set(
      circle.centerX -> random * stage.width,
      circle.centerY -> random * stage.height
    )
  }
}
timeline.play();
                                                21
JavaFX Script-like animation
Animation in Scala       syntax: at (duration) {keyframes}

val timeline = new Timeline {
  cycleCount = INDEFINITE
  autoReverse = true
  keyFrames = for (circle <- circles) yield at (40 s) {
    Set(
      circle.centerX -> random * stage.width,
      circle.centerY -> random * stage.height
    )
  }
}
timeline.play();




                                                             22
Animation in Scala
val timeline = new Timeline {
  cycleCount = INDEFINITE
  autoReverse = true
  keyFrames = for (circle <- circles) yield at (40 s) {
    Set(
      circle.centerX -> random * stage.width,
      circle.centerY -> random * stage.height
    )
  }
}
timeline.play();
                            Operator overloading for
                               animation syntax


                                                       23
Animation in Scala
val timeline = new Timeline {
  cycleCount = INDEFINITE
  autoReverse = true
  keyFrames = for (circle <- circles) yield at (40 s) {
    Set(
 circle.centerX -> random * stage.width tween EASE_BOTH,
 circle.centerY -> random * stage.height tween EASE_IN
    )
  }
}
timeline.play();
                           Optional
                         tween syntax


                                                     24
Event Listeners in Scala
>   Supported using the built-in Closure syntax
>   Arguments for event objects
>   100% type-safe


    onMouseClicked = { (e: MouseEvent) =>
      Timeline(at(3 s){radius->0}).play()
    }


                                                  25
Event Listeners in Scala
>   Supported using the built-in Closure syntax
>   Arguments for event objects          Optional event
>   100% type-safe                        parameter
                                        {(event) => body}

    onMouseClicked = { (e: MouseEvent) =>
      Timeline(at(3 s){radius->0}).play()
    }


                                                            26
Jumping Frogs Puzzle




Image by renwest: http://www.flickr.com/photos/19941963@N00/438340463
                                                                        27
Jumping Frogs Puzzle
>   My first ScalaFX program
>   Similar to (but more concise as) my version using
    JavaFX 1.2
>   After a few JavaFX 1.2 to ScalaFX translation
    iterations it just worked
>   After some MVC rethinking and a few refactoring
    iterations it worked even better (e.g. it is possible
    to click on a jumping frog)



                                                            28
Application
object JumpingFrogsPuzzle extends JFXApp {
  stage = new Stage {
    title = TITLE
    scene = new Scene {
    content =
      theShapes.canvasShape ::
        theShapes.stoneShapes :::
        theView.frogShapes
    }
  }
}
                                             29
Frog
trait   Frog {
  def   movesToRight: Boolean
  def   movesToLeft: Boolean
}
class   LeftFrog() extends Frog {
  def   movesToRight = true
  def   movesToLeft = false
}
class   RightFrog() extends Frog {
  def   movesToRight = false
  def   movesToLeft = true
}

                                     30
Model (frogMap)
var frogMap: Map[Int, Frog] = _

private val frogAtPosition = (i: Int) =>
  frogMap(i)

val positionOf = (frog: Frog) => (for {
  (i, `frog`) <- frogMap
} yield i) head


                                           31
Model (move)
private val move =
  (next: Int => Int) => (frog: Frog) =>
  frogMap = (for {
    entry@(_, aFrog) <- frogMap
    if (aFrog != frog)
  } yield {
    entry
  }) + (next(positionOf(frog)) -> frog)


                                          32
View (jump)
private val jump =
  (length: Int) =>
  (direction: (Double, Double) => Double) =>
  (frogShape: FrogShape) => {
    // ...
    Timeline(Seq(
      at(midTime) { frogShape.centerX -> midCenterX
},
      at(midTime) { frogShape.centerY -> midCenterY
},
      at(endTime) { frogShape.centerX -> endCenterX
},
      at(endTime) { frogShape.centerY -> endCenterY }
  )).play()
}

                                                        33
View (control)
private val control: Unit => Unit = { _ =>
  view.frogShapes.foreach {
    frogShape => frogShape.onMouseClicked = {
      (_: MouseEvent) =>
        val frog = frogShape.frog
        if (model.canMoveOneRight(frog)) {
          view.jumpOneRight(frogShape)
          model.moveOneRight(frog)
        } else if (model.canMoveTwoRight(frog)) {
          view.jumpTwoRight(frogShape)
          model.moveTwoRight(frog)
                                                    34
ScalaFX Internals
 a.k.a. How to Write Your Own Scala DSL




With quotes from Stephen Colebourne (@jodastephen) to help
us keep our sanity!
Disclaimer: Statements taken from http://blog.joda.org and may not accurately reflect his opinion or viewpoint.
                                                                                                                  35
Application Initialization
>   JavaFX Requires all UI code executed on the
    Application Thread
>   But our ScalaFX Application has no start method:

object VanishingCircles extends JFXApp {
  stage = new Stage {
    …
  }
}

    How Does This Code Work?!?
                                                       36
DelayedInit
>    Introduced in Scala 2.9
>    How to Use It:
1.    Extend a special trait called DelayedInit
2.    Implement a method of type:
         def delayedInit(x: => Unit): Unit
3.       Store off the init closure and call it on the
         Application Thread

          Joda says…

          For me, Scala didn't throw enough away and added too much - a lethal
          combination.
                                                                                 37
Hierarchical Implicit Conversions
>   ScalaFX defines a set of proxies that mirror the
    JavaFX hierarchy
>   JavaFX classes are "implicitly" wrapped when you
    call a ScalaFX API
>   But Scala implicit priority ignores type hierarchy!

     JFXNode                              SFXNode



               JFXShape    ?                        SFXShape



                          JFXCircle   !                        SFXCircle

                                                                           38
N-Level Implicit Precedence
>   Scala throws an exception if two implicits have the
    same precedence
>   Classes that are extended have 1 lower
    precedence:
object HighPriorityIncludes extends LowerPriorityIncludes {…}
trait LowerPriorityIncludes {…}

>   You can stack extended traits n-levels deep to
    reduce precision by n
      Joda says…

      Well, it may be type safe, but its also silent and very deadly.

                                                                        39
Properties
>   JavaFX supports properties of type Boolean,
    Integer, Long, Float, Double, String, and Object
>   Properties use Generics for type safety
>   But generics don't support primitives…

>   JavaFX solves this with 20 interfaces and 44
    classes for all the type/readable/writable
    combinations.

>   Can we do better?
                                                       40
@specialized
>   Special annotation that generates primitive
    variants of the class
>   Improves performance by avoiding
    boxing/unboxing
      trait ObservableValue[@specialized(Int, Long,
      Float, Double, Boolean) T, J]
>   Cuts down on code duplication (ScalaFX only has
    18 property/value classes total)
      Joda says…

      Whatever the problem, the type system is bound to be part of the solution.

                                                                                   41
Bindings
>    How does Scala know what order to evaluate this
     in?

text <== when (rect.hover || circle.hover
&& !disabled) then textField.text + " is
enabled" otherwise "disabled



    And why the funky bind operator?!?

                                                       42
Operator Precedence Rules
>   First Character Determines Precedence
    Lowest Precedence
       10. (all   letters)     Exception Assignment
       9. |
                               Operators, which are
       8. ^                    even lower…
       7. &
       6. < >                  11. Assignment   Operators
       5. = !
                               end with equal
       4. :
                               > But don't start with equal
       3. + *
                               > And cannot be one of:
                                     <=
       2. / %
                                     >=
       1. (all other special
                                     !=
       characters)
    Highest Precedence                                        43
Operator Precedence

text <== when (rect.hover || circle.hover
            11       10                               9

&& !disabled) then textField.text + " is
7   5                          10                                    3

enabled" otherwise "disabled"
                          10



    Joda says…

        Personally, I find the goal of the open and flexible syntax (arbitrary DSLs) to
        be not worth the pain
                                                                                      44
Conclusion
>   You can use Scala and JavaFX together.
>   ScalaFX provides cleaner APIs that are tailor
    designed for Scala.
>   Try using ScalaFX today and help contribute APIs
    for our upcoming 1.0 release!


    http://code.google.com/p/scalafx/
Stephen Chin
                     steveonjava@gmail.com
                     tweet: @steveonjava



Pro JavaFX 2 Platform Available Now!
                                             46

Más contenido relacionado

La actualidad más candente

Java FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's GuideJava FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's GuideStephen Chin
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the CloudStephen Chin
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189Mahmoud Samir Fayed
 
Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Ralph Schindler
 
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Howard Lewis Ship
 
The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196Mahmoud Samir Fayed
 
Gazr
GazrGazr
Gazrkuro7
 
Beyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCodeBeyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCodeAijaz Ansari
 
PHP and MySQL Tips and tricks, DC 2007
PHP and MySQL Tips and tricks, DC 2007PHP and MySQL Tips and tricks, DC 2007
PHP and MySQL Tips and tricks, DC 2007Damien Seguy
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210Mahmoud Samir Fayed
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 33 of 196
The Ring programming language version 1.7 book - Part 33 of 196The Ring programming language version 1.7 book - Part 33 of 196
The Ring programming language version 1.7 book - Part 33 of 196Mahmoud Samir Fayed
 
The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84Mahmoud Samir Fayed
 

La actualidad más candente (20)

Java FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's GuideJava FX 2.0 - A Developer's Guide
Java FX 2.0 - A Developer's Guide
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the Cloud
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189
 
Clojure Deep Dive
Clojure Deep DiveClojure Deep Dive
Clojure Deep Dive
 
Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2
 
Xm lparsers
Xm lparsersXm lparsers
Xm lparsers
 
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)
 
The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196The Ring programming language version 1.7 book - Part 57 of 196
The Ring programming language version 1.7 book - Part 57 of 196
 
Gazr
GazrGazr
Gazr
 
Beyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCodeBeyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCode
 
PHP and MySQL Tips and tricks, DC 2007
PHP and MySQL Tips and tricks, DC 2007PHP and MySQL Tips and tricks, DC 2007
PHP and MySQL Tips and tricks, DC 2007
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84
 
Alternate JVM Languages
Alternate JVM LanguagesAlternate JVM Languages
Alternate JVM Languages
 
The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212
 
The Ring programming language version 1.7 book - Part 33 of 196
The Ring programming language version 1.7 book - Part 33 of 196The Ring programming language version 1.7 book - Part 33 of 196
The Ring programming language version 1.7 book - Part 33 of 196
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84
 

Destacado

JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)Stephen Chin
 
Curso de Scala: Trabajando con variables
Curso de Scala: Trabajando con variablesCurso de Scala: Trabajando con variables
Curso de Scala: Trabajando con variablesGary Briceño
 
Scala - just good for Java shops?
Scala - just good for Java shops?Scala - just good for Java shops?
Scala - just good for Java shops?Sarah Mount
 
Scala+swing
Scala+swingScala+swing
Scala+swingperneto
 
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)Stephen Chin
 
Confessions of a Former Agile Methodologist (JFrog Edition)
Confessions of a Former Agile Methodologist (JFrog Edition)Confessions of a Former Agile Methodologist (JFrog Edition)
Confessions of a Former Agile Methodologist (JFrog Edition)Stephen Chin
 
Oracle IoT Kids Workshop
Oracle IoT Kids WorkshopOracle IoT Kids Workshop
Oracle IoT Kids WorkshopStephen Chin
 
Devoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopDevoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopStephen Chin
 
Devoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopDevoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopStephen Chin
 

Destacado (18)

JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 
Pf con scala
Pf con scalaPf con scala
Pf con scala
 
Scala en la Practica
Scala en la PracticaScala en la Practica
Scala en la Practica
 
Introducción a Scala
Introducción a ScalaIntroducción a Scala
Introducción a Scala
 
Programación Funcional en Scala
Programación Funcional en ScalaProgramación Funcional en Scala
Programación Funcional en Scala
 
Curso de Scala: Trabajando con variables
Curso de Scala: Trabajando con variablesCurso de Scala: Trabajando con variables
Curso de Scala: Trabajando con variables
 
Scala - just good for Java shops?
Scala - just good for Java shops?Scala - just good for Java shops?
Scala - just good for Java shops?
 
Baño
BañoBaño
Baño
 
Introducción a scala
Introducción a scalaIntroducción a scala
Introducción a scala
 
Koreference
KoreferenceKoreference
Koreference
 
Scala+swing
Scala+swingScala+swing
Scala+swing
 
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
 
Confessions of a Former Agile Methodologist (JFrog Edition)
Confessions of a Former Agile Methodologist (JFrog Edition)Confessions of a Former Agile Methodologist (JFrog Edition)
Confessions of a Former Agile Methodologist (JFrog Edition)
 
Oracle IoT Kids Workshop
Oracle IoT Kids WorkshopOracle IoT Kids Workshop
Oracle IoT Kids Workshop
 
Devoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopDevoxx4Kids NAO Workshop
Devoxx4Kids NAO Workshop
 
Devoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopDevoxx4Kids Lego Workshop
Devoxx4Kids Lego Workshop
 
4 Introducción al lenguaje Scala
4 Introducción al lenguaje Scala4 Introducción al lenguaje Scala
4 Introducción al lenguaje Scala
 
Scala
ScalaScala
Scala
 

Similar a JavaFX and Scala - Like Milk and Cookies

Raspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFXRaspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFXStephen Chin
 
JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]Stephen Chin
 
Create a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdfCreate a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdfarihantmobileselepun
 
ECMAScript 6 major changes
ECMAScript 6 major changesECMAScript 6 major changes
ECMAScript 6 major changeshayato
 
ARTDM 170, Week 13: Text Elements + Arrays
ARTDM 170, Week 13: Text Elements + ArraysARTDM 170, Week 13: Text Elements + Arrays
ARTDM 170, Week 13: Text Elements + ArraysGilbert Guerrero
 
Javascript Arrays
Javascript ArraysJavascript Arrays
Javascript Arraysshaheenakv
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
The Ring programming language version 1.5.1 book - Part 63 of 180
The Ring programming language version 1.5.1 book - Part 63 of 180The Ring programming language version 1.5.1 book - Part 63 of 180
The Ring programming language version 1.5.1 book - Part 63 of 180Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 69 of 189
The Ring programming language version 1.6 book - Part 69 of 189The Ring programming language version 1.6 book - Part 69 of 189
The Ring programming language version 1.6 book - Part 69 of 189Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 73 of 202
The Ring programming language version 1.8 book - Part 73 of 202The Ring programming language version 1.8 book - Part 73 of 202
The Ring programming language version 1.8 book - Part 73 of 202Mahmoud Samir Fayed
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with SpockAlexander Tarlinder
 
package chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfpackage chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfKARTIKINDIA
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 71 of 196
The Ring programming language version 1.7 book - Part 71 of 196The Ring programming language version 1.7 book - Part 71 of 196
The Ring programming language version 1.7 book - Part 71 of 196Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.4 book - Part 16 of 30
The Ring programming language version 1.4 book - Part 16 of 30The Ring programming language version 1.4 book - Part 16 of 30
The Ring programming language version 1.4 book - Part 16 of 30Mahmoud Samir Fayed
 
Advance features of C++
Advance features of C++Advance features of C++
Advance features of C++vidyamittal
 

Similar a JavaFX and Scala - Like Milk and Cookies (20)

Raspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFXRaspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFX
 
JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]
 
Create a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdfCreate a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdf
 
ECMAScript 6 major changes
ECMAScript 6 major changesECMAScript 6 major changes
ECMAScript 6 major changes
 
ARTDM 170, Week 13: Text Elements + Arrays
ARTDM 170, Week 13: Text Elements + ArraysARTDM 170, Week 13: Text Elements + Arrays
ARTDM 170, Week 13: Text Elements + Arrays
 
Javascript Arrays
Javascript ArraysJavascript Arrays
Javascript Arrays
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
The Ring programming language version 1.5.1 book - Part 63 of 180
The Ring programming language version 1.5.1 book - Part 63 of 180The Ring programming language version 1.5.1 book - Part 63 of 180
The Ring programming language version 1.5.1 book - Part 63 of 180
 
The Ring programming language version 1.6 book - Part 69 of 189
The Ring programming language version 1.6 book - Part 69 of 189The Ring programming language version 1.6 book - Part 69 of 189
The Ring programming language version 1.6 book - Part 69 of 189
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
The Ring programming language version 1.8 book - Part 73 of 202
The Ring programming language version 1.8 book - Part 73 of 202The Ring programming language version 1.8 book - Part 73 of 202
The Ring programming language version 1.8 book - Part 73 of 202
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
 
ES6(ES2015) is beautiful
ES6(ES2015) is beautifulES6(ES2015) is beautiful
ES6(ES2015) is beautiful
 
package chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfpackage chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdf
 
The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196The Ring programming language version 1.7 book - Part 72 of 196
The Ring programming language version 1.7 book - Part 72 of 196
 
The Ring programming language version 1.7 book - Part 71 of 196
The Ring programming language version 1.7 book - Part 71 of 196The Ring programming language version 1.7 book - Part 71 of 196
The Ring programming language version 1.7 book - Part 71 of 196
 
The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202The Ring programming language version 1.8 book - Part 74 of 202
The Ring programming language version 1.8 book - Part 74 of 202
 
Canvas al ajillo
Canvas al ajilloCanvas al ajillo
Canvas al ajillo
 
The Ring programming language version 1.4 book - Part 16 of 30
The Ring programming language version 1.4 book - Part 16 of 30The Ring programming language version 1.4 book - Part 16 of 30
The Ring programming language version 1.4 book - Part 16 of 30
 
Advance features of C++
Advance features of C++Advance features of C++
Advance features of C++
 

Más de Stephen Chin

DevOps Tools for Java Developers v2
DevOps Tools for Java Developers v2DevOps Tools for Java Developers v2
DevOps Tools for Java Developers v2Stephen Chin
 
10 Ways Everyone Can Support the Java Community
10 Ways Everyone Can Support the Java Community10 Ways Everyone Can Support the Java Community
10 Ways Everyone Can Support the Java CommunityStephen Chin
 
Java Clients and JavaFX: The Definitive Guide
Java Clients and JavaFX: The Definitive GuideJava Clients and JavaFX: The Definitive Guide
Java Clients and JavaFX: The Definitive GuideStephen Chin
 
DevOps Tools for Java Developers
DevOps Tools for Java DevelopersDevOps Tools for Java Developers
DevOps Tools for Java DevelopersStephen Chin
 
Java Clients and JavaFX - Presented to LJC
Java Clients and JavaFX - Presented to LJCJava Clients and JavaFX - Presented to LJC
Java Clients and JavaFX - Presented to LJCStephen Chin
 
RetroPi Handheld Raspberry Pi Gaming Console
RetroPi Handheld Raspberry Pi Gaming ConsoleRetroPi Handheld Raspberry Pi Gaming Console
RetroPi Handheld Raspberry Pi Gaming ConsoleStephen Chin
 
JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)Stephen Chin
 
Raspberry Pi with Java (JJUG)
Raspberry Pi with Java (JJUG)Raspberry Pi with Java (JJUG)
Raspberry Pi with Java (JJUG)Stephen Chin
 
Confessions of a Former Agile Methodologist
Confessions of a Former Agile MethodologistConfessions of a Former Agile Methodologist
Confessions of a Former Agile MethodologistStephen Chin
 
Internet of Things Magic Show
Internet of Things Magic ShowInternet of Things Magic Show
Internet of Things Magic ShowStephen Chin
 
Zombie Time - JSR 310 for the Undead
Zombie Time - JSR 310 for the UndeadZombie Time - JSR 310 for the Undead
Zombie Time - JSR 310 for the UndeadStephen Chin
 
JCrete Embedded Java Workshop
JCrete Embedded Java WorkshopJCrete Embedded Java Workshop
JCrete Embedded Java WorkshopStephen Chin
 
OpenJFX on Android and Devices
OpenJFX on Android and DevicesOpenJFX on Android and Devices
OpenJFX on Android and DevicesStephen Chin
 
Java on Raspberry Pi Lab
Java on Raspberry Pi LabJava on Raspberry Pi Lab
Java on Raspberry Pi LabStephen Chin
 
Java 8 for Tablets, Pis, and Legos
Java 8 for Tablets, Pis, and LegosJava 8 for Tablets, Pis, and Legos
Java 8 for Tablets, Pis, and LegosStephen Chin
 
Raspberry Pi Gaming 4 Kids - Dutch Version
Raspberry Pi Gaming 4 Kids - Dutch VersionRaspberry Pi Gaming 4 Kids - Dutch Version
Raspberry Pi Gaming 4 Kids - Dutch VersionStephen Chin
 
Raspberry pi gaming 4 kids
Raspberry pi gaming 4 kidsRaspberry pi gaming 4 kids
Raspberry pi gaming 4 kidsStephen Chin
 
LUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi HackingLUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi HackingStephen Chin
 
Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Stephen Chin
 

Más de Stephen Chin (20)

DevOps Tools for Java Developers v2
DevOps Tools for Java Developers v2DevOps Tools for Java Developers v2
DevOps Tools for Java Developers v2
 
10 Ways Everyone Can Support the Java Community
10 Ways Everyone Can Support the Java Community10 Ways Everyone Can Support the Java Community
10 Ways Everyone Can Support the Java Community
 
Java Clients and JavaFX: The Definitive Guide
Java Clients and JavaFX: The Definitive GuideJava Clients and JavaFX: The Definitive Guide
Java Clients and JavaFX: The Definitive Guide
 
DevOps Tools for Java Developers
DevOps Tools for Java DevelopersDevOps Tools for Java Developers
DevOps Tools for Java Developers
 
Java Clients and JavaFX - Presented to LJC
Java Clients and JavaFX - Presented to LJCJava Clients and JavaFX - Presented to LJC
Java Clients and JavaFX - Presented to LJC
 
RetroPi Handheld Raspberry Pi Gaming Console
RetroPi Handheld Raspberry Pi Gaming ConsoleRetroPi Handheld Raspberry Pi Gaming Console
RetroPi Handheld Raspberry Pi Gaming Console
 
JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)JavaFX on Mobile (by Johan Vos)
JavaFX on Mobile (by Johan Vos)
 
Raspberry Pi with Java (JJUG)
Raspberry Pi with Java (JJUG)Raspberry Pi with Java (JJUG)
Raspberry Pi with Java (JJUG)
 
Confessions of a Former Agile Methodologist
Confessions of a Former Agile MethodologistConfessions of a Former Agile Methodologist
Confessions of a Former Agile Methodologist
 
Internet of Things Magic Show
Internet of Things Magic ShowInternet of Things Magic Show
Internet of Things Magic Show
 
Zombie Time - JSR 310 for the Undead
Zombie Time - JSR 310 for the UndeadZombie Time - JSR 310 for the Undead
Zombie Time - JSR 310 for the Undead
 
JCrete Embedded Java Workshop
JCrete Embedded Java WorkshopJCrete Embedded Java Workshop
JCrete Embedded Java Workshop
 
OpenJFX on Android and Devices
OpenJFX on Android and DevicesOpenJFX on Android and Devices
OpenJFX on Android and Devices
 
Java on Raspberry Pi Lab
Java on Raspberry Pi LabJava on Raspberry Pi Lab
Java on Raspberry Pi Lab
 
Java 8 for Tablets, Pis, and Legos
Java 8 for Tablets, Pis, and LegosJava 8 for Tablets, Pis, and Legos
Java 8 for Tablets, Pis, and Legos
 
DukeScript
DukeScriptDukeScript
DukeScript
 
Raspberry Pi Gaming 4 Kids - Dutch Version
Raspberry Pi Gaming 4 Kids - Dutch VersionRaspberry Pi Gaming 4 Kids - Dutch Version
Raspberry Pi Gaming 4 Kids - Dutch Version
 
Raspberry pi gaming 4 kids
Raspberry pi gaming 4 kidsRaspberry pi gaming 4 kids
Raspberry pi gaming 4 kids
 
LUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi HackingLUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi Hacking
 
Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5
 

Último

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 

Último (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 

JavaFX and Scala - Like Milk and Cookies

  • 1. JavaFX and Scala – Like Milk and Cookies Stephen Chin Luc Duponcheel JavaFX Evangelist, Oracle Independent, ImagineJ steveonjava@gmail.com luc.duponcheel@gmail.com tweet: @steveonjava tweet: @LucDup
  • 2. Meet the Presenters Stephen Chin Luc Duponcheel Family Man Motorcyclist BeJUG Researcher
  • 3. JavaFX 2.0 Platform Immersive Application Experience > Cross-platform Animation, Video, Charting > Integrate Java, JavaScript, and HTML5 in the same application > New graphics stack takes advantage of hardware acceleration for 2D and 3D applications > Use your favorite IDE: NetBeans, Eclipse, IntelliJ, etc.
  • 6. JavaFX in Java > JavaFX API uses an enhanced JavaBeans pattern > Similar in feel to other UI toolkits (Swing, Pivot, etc.) > Uses builder pattern to minimize boilerplate
  • 8. Application Skeleton public class VanishingCircles extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Vanishing Circles"); Group root = new Group(); Scene scene = new Scene(root, 800, 600, Color.BLACK); [create the circles…] root.getChildren().addAll(circles); primaryStage.setScene(scene); primaryStage.show(); [begin the animation…] } }
  • 9. Create the Circles List<Circle> circles = new ArrayList<Circle>(); for (int i = 0; i < 50; i++) { final Circle circle = new Circle(150); circle.setCenterX(Math.random() * 800); circle.setCenterY(Math.random() * 600); circle.setFill(new Color(Math.random(), Math.random(), Math.random(), .2)); circle.setEffect(new BoxBlur(10, 10, 3)); circle.setStroke(Color.WHITE); [setup binding…] [setup event listeners…] circles.add(circle); } 9
  • 10. Setup Binding circle.strokeWidthProperty().bind(Bindings .when(circle.hoverProperty()) .then(4) .otherwise(0) ); 10
  • 11. Setup Event Listeners circle.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { public void handle(MouseEvent t) { KeyValue collapse = new KeyValue(circle.radiusProperty(), 0); new Timeline(new KeyFrame(Duration.seconds(3), collapse)).play(); } }); 11
  • 12. Begin the Animation Timeline moveCircles = new Timeline(); for (Circle circle : circles) { KeyValue moveX = new KeyValue(circle.centerXProperty(), Math.random() * 800); KeyValue moveY = new KeyValue(circle.centerYProperty(), Math.random() * 600); moveCircles.getKeyFrames().add(new KeyFrame(Duration.seconds(40), moveX, moveY)); } moveCircles.play(); 12
  • 14. Java vs. Scala DSL public class VanishingCircles extends Application { object VanishingCircles extends JFXApp { var circles: Seq[Circle] = null public static void main(String[] args) { stage = new Stage { Application.launch(args); title = "Vanishing Circles" } width = 800 height = 600 @Override scene = new Scene { public void start(Stage primaryStage) { fill = BLACK primaryStage.setTitle("Vanishing Circles"); circles = for (i <- 0 until 50) yield new Circle { Group root = new Group(); centerX = random * 800 Scene scene = new Scene(root, 800, 600, Color.BLACK); centerY = random * 600 List<Circle> circles = new ArrayList<Circle>(); radius = 150 for (int i = 0; i < 50; i++) { fill = color(random, random, random, .2) final Circle circle = new Circle(150); effect = new BoxBlur(10, 10, 3) 40 Lines circle.setCenterX(Math.random() * 800); circle.setCenterY(Math.random() * 600); circle.setFill(new Color(Math.random(), Math.random(), Math.random(), .2)); circle.setEffect(new BoxBlur(10, 10, 3)); 33 Lines strokeWidth <== when (hover) then 4 otherwise 0 stroke = WHITE onMouseClicked = { Timeline(at (3 s) {radius -> 0}).play() 1299 Characters circle.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { public void handle(MouseEvent t) { KeyValue collapse = new KeyValue(circle.radiusProperty(), 0); } } } 591 Characters content = circles new Timeline(new KeyFrame(Duration.seconds(3), collapse)).play(); } } }); new Timeline { circle.setStroke(Color.WHITE); cycleCount = INDEFINITE circle.strokeWidthProperty().bind(Bindings.when(circle.hoverProperty()) autoReverse = true .then(4) keyFrames = for (circle <- circles) yield at (40 s) { .otherwise(0)); Set( circles.add(circle); circle.centerX -> random * stage.width, } circle.centerY -> random * stage.height root.getChildren().addAll(circles); ) primaryStage.setScene(scene); } primaryStage.show(); }.play(); } Timeline moveCircles = new Timeline(); for (Circle circle : circles) { KeyValue moveX = new KeyValue(circle.centerXProperty(), Math.random() * 800); KeyValue moveY = new KeyValue(circle.centerYProperty(), Math.random() * 600); moveCircles.getKeyFrames().add(new KeyFrame(Duration.seconds(40), moveX, moveY)); } moveCircles.play(); } } 14
  • 15. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } 15
  • 16. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 class for JavaFX Base applications scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } 16
  • 17. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 Declarative Stage scene = new Scene { fill = BLACK definition content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } 17
  • 18. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 Inline property height = 600 definitions scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } 18
  • 19. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 Sequence Creation Via height = 600 Loop scene = new Scene { fill = BLACK content = for (i <- 0 until 50) yield new Circle { centerX = random * 800 centerY = random * 600 radius = 150 fill = color(random, random, random, 0.2) effect = new BoxBlur(10, 10, 3) } } } } 19
  • 20. Binding in Scala Infix Addition/Subtraction/Multiplication/Division: height <== rect1.height + rect2.height Aggregate Operators: width <== max(rect1.width, rect2.width, rect3.width) Conditional Expressions: strokeWidth <== when (hover) then 4 otherwise 0 Compound Expressions: text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled" 20
  • 21. Animation in Scala val timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); 21
  • 22. JavaFX Script-like animation Animation in Scala syntax: at (duration) {keyframes} val timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); 22
  • 23. Animation in Scala val timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width, circle.centerY -> random * stage.height ) } } timeline.play(); Operator overloading for animation syntax 23
  • 24. Animation in Scala val timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width tween EASE_BOTH, circle.centerY -> random * stage.height tween EASE_IN ) } } timeline.play(); Optional tween syntax 24
  • 25. Event Listeners in Scala > Supported using the built-in Closure syntax > Arguments for event objects > 100% type-safe onMouseClicked = { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() } 25
  • 26. Event Listeners in Scala > Supported using the built-in Closure syntax > Arguments for event objects Optional event > 100% type-safe parameter {(event) => body} onMouseClicked = { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() } 26
  • 27. Jumping Frogs Puzzle Image by renwest: http://www.flickr.com/photos/19941963@N00/438340463 27
  • 28. Jumping Frogs Puzzle > My first ScalaFX program > Similar to (but more concise as) my version using JavaFX 1.2 > After a few JavaFX 1.2 to ScalaFX translation iterations it just worked > After some MVC rethinking and a few refactoring iterations it worked even better (e.g. it is possible to click on a jumping frog) 28
  • 29. Application object JumpingFrogsPuzzle extends JFXApp { stage = new Stage { title = TITLE scene = new Scene { content = theShapes.canvasShape :: theShapes.stoneShapes ::: theView.frogShapes } } } 29
  • 30. Frog trait Frog { def movesToRight: Boolean def movesToLeft: Boolean } class LeftFrog() extends Frog { def movesToRight = true def movesToLeft = false } class RightFrog() extends Frog { def movesToRight = false def movesToLeft = true } 30
  • 31. Model (frogMap) var frogMap: Map[Int, Frog] = _ private val frogAtPosition = (i: Int) => frogMap(i) val positionOf = (frog: Frog) => (for { (i, `frog`) <- frogMap } yield i) head 31
  • 32. Model (move) private val move = (next: Int => Int) => (frog: Frog) => frogMap = (for { entry@(_, aFrog) <- frogMap if (aFrog != frog) } yield { entry }) + (next(positionOf(frog)) -> frog) 32
  • 33. View (jump) private val jump = (length: Int) => (direction: (Double, Double) => Double) => (frogShape: FrogShape) => { // ... Timeline(Seq( at(midTime) { frogShape.centerX -> midCenterX }, at(midTime) { frogShape.centerY -> midCenterY }, at(endTime) { frogShape.centerX -> endCenterX }, at(endTime) { frogShape.centerY -> endCenterY } )).play() } 33
  • 34. View (control) private val control: Unit => Unit = { _ => view.frogShapes.foreach { frogShape => frogShape.onMouseClicked = { (_: MouseEvent) => val frog = frogShape.frog if (model.canMoveOneRight(frog)) { view.jumpOneRight(frogShape) model.moveOneRight(frog) } else if (model.canMoveTwoRight(frog)) { view.jumpTwoRight(frogShape) model.moveTwoRight(frog) 34
  • 35. ScalaFX Internals a.k.a. How to Write Your Own Scala DSL With quotes from Stephen Colebourne (@jodastephen) to help us keep our sanity! Disclaimer: Statements taken from http://blog.joda.org and may not accurately reflect his opinion or viewpoint. 35
  • 36. Application Initialization > JavaFX Requires all UI code executed on the Application Thread > But our ScalaFX Application has no start method: object VanishingCircles extends JFXApp { stage = new Stage { … } } How Does This Code Work?!? 36
  • 37. DelayedInit > Introduced in Scala 2.9 > How to Use It: 1. Extend a special trait called DelayedInit 2. Implement a method of type:  def delayedInit(x: => Unit): Unit 3. Store off the init closure and call it on the Application Thread Joda says… For me, Scala didn't throw enough away and added too much - a lethal combination. 37
  • 38. Hierarchical Implicit Conversions > ScalaFX defines a set of proxies that mirror the JavaFX hierarchy > JavaFX classes are "implicitly" wrapped when you call a ScalaFX API > But Scala implicit priority ignores type hierarchy! JFXNode SFXNode JFXShape ? SFXShape JFXCircle ! SFXCircle 38
  • 39. N-Level Implicit Precedence > Scala throws an exception if two implicits have the same precedence > Classes that are extended have 1 lower precedence: object HighPriorityIncludes extends LowerPriorityIncludes {…} trait LowerPriorityIncludes {…} > You can stack extended traits n-levels deep to reduce precision by n Joda says… Well, it may be type safe, but its also silent and very deadly. 39
  • 40. Properties > JavaFX supports properties of type Boolean, Integer, Long, Float, Double, String, and Object > Properties use Generics for type safety > But generics don't support primitives… > JavaFX solves this with 20 interfaces and 44 classes for all the type/readable/writable combinations. > Can we do better? 40
  • 41. @specialized > Special annotation that generates primitive variants of the class > Improves performance by avoiding boxing/unboxing trait ObservableValue[@specialized(Int, Long, Float, Double, Boolean) T, J] > Cuts down on code duplication (ScalaFX only has 18 property/value classes total) Joda says… Whatever the problem, the type system is bound to be part of the solution. 41
  • 42. Bindings > How does Scala know what order to evaluate this in? text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled And why the funky bind operator?!? 42
  • 43. Operator Precedence Rules > First Character Determines Precedence Lowest Precedence 10. (all letters) Exception Assignment 9. | Operators, which are 8. ^ even lower… 7. & 6. < > 11. Assignment Operators 5. = ! end with equal 4. : > But don't start with equal 3. + * > And cannot be one of:  <= 2. / %  >= 1. (all other special  != characters) Highest Precedence 43
  • 44. Operator Precedence text <== when (rect.hover || circle.hover 11 10 9 && !disabled) then textField.text + " is 7 5 10 3 enabled" otherwise "disabled" 10 Joda says… Personally, I find the goal of the open and flexible syntax (arbitrary DSLs) to be not worth the pain 44
  • 45. Conclusion > You can use Scala and JavaFX together. > ScalaFX provides cleaner APIs that are tailor designed for Scala. > Try using ScalaFX today and help contribute APIs for our upcoming 1.0 release! http://code.google.com/p/scalafx/
  • 46. Stephen Chin steveonjava@gmail.com tweet: @steveonjava Pro JavaFX 2 Platform Available Now! 46

Notas del editor

  1. Stage.add??