SlideShare a Scribd company logo
1 of 52
Download to read offline
JavaFX 2.0 and Scala, Like Milk
and Cookies      Stephen Chin
                  Chief Agile
                  Methodologist, GXS
                  steveonjava@gmail.com
                  tweet: @steveonjava
Meet the Presenter

        Stephen Chin
                                >   Chief Agile
                                    Methodologist, GXS
  Family Man                    >   Java Champion
                                >   Open Source Hacker
                                       JFXtras
                 Motorcyclist          ScalaFX
                                       Visage
                                >   User Group Leader
                                       Silicon Valley JavaFX User
                                        Group
                                       Streamed Live!
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.
Programming Languages
>   JavaFX Script is no longer supported by Oracle
       Existing JavaFX Script based applications will
        continue to run
       Visage is the open-source successor to the JavaFX
        Script language
>   JavaFX 2.0 APIs are now in Java
       Pure Java APIs for all of JavaFX
       Binding and Sequences exposed as Java APIs
       FXML Markup for tooling
JavaFX




Scala




                 5
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
Example Application
public class HelloStage extends Application {
    @Override public void start(Stage stage) {
      stage.setTitle("Hello Stage");
      stage.setWidth(600);
      stage.setHeight(450);
        Group root = new Group();
        Scene scene = new Scene(root);
        scene.setFill(Color.LIGHTGREEN);
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {
      Application.launch(args);
    }
}
Example Application Using Builders
public class HelloStage extends Application {

    @Override public void start(Stage stage) {
      stage.setTitle("Hello Stage");
      stage.setScene(SceneBuilder.create()
        .fill(Color.LIGHTGREEN)
        .width(600)
        .height(450)
      .build());
      stage.show();
    }

    public static void main(String[] args) {
      Application.launch(args);
    }
}
Observable Properties
>   Supports watching for changes to
    properties
>   Implemented via anonymous inner
    classes
>   Will take advantage of closures in the
    future
Observable Pseudo-Properties
final Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setHeight(200);


rect.hoverProperty().addListener(new ChangeListener<Boolean>() {




});
Observable Pseudo-Properties
final Rectangle rect = new Rectangle();
rect.setX(40);                      The   property we want to watch
rect.setY(40);
rect.setWidth(100);
rect.setHeight(200);


rect.hoverProperty().addListener(new ChangeListener<Boolean>() {




});
Observable Pseudo-Properties
final Rectangle rect = new Rectangle();
rect.setX(40);                          Only one listener used with
rect.setY(40);                       generics to specify the data type
rect.setWidth(100);
rect.setHeight(200);


rect.hoverProperty().addListener(new ChangeListener<Boolean>() {




});
Observable Pseudo-Properties
final Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setHeight(200);


rect.hoverProperty().addListener(new ChangeListener<Boolean>() {
  public void changed(ObservableValue<? extends Boolean> property,
                      Boolean oldValue, Boolean value) {

  }
});


              Refers to the
        Rectangle.hoverProperty()
Observable Pseudo-Properties
final Rectangle rect = new Rectangle();
rect.setX(40);
rect.setY(40);
rect.setWidth(100);
rect.setHeight(200);


rect.hoverProperty().addListener(new ChangeListener<Boolean>() {
  public void changed(ObservableValue<? extends Boolean> property,
                      Boolean oldValue, Boolean value) {
    rect.setFill(rect.isHover() ? Color.GREEN : Color.RED);
  }
});
Binding
>   Unquestionably the biggest JavaFX
    Script innovation
>   Supported via a PropertyBinding class
>   Lazy invocation for high performance
>   Static construction syntax for simple
    cases
       e.g.: bind(<property>),
        bindBiDirectional(<property>)
Sequences in Java
>   Replaced with an Observable List

>   Public API is based on JavaFX sequences

>   Internal code can use lighter collections API

>   JavaFX 2.0 also has an Observable Map
Vanishing Circles




                    18
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);
}


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




                                             21
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();
  }
});




                                                                    22
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();




                                                                  23
JavaFX With Scala




               24
What is Scala
                                                                    2012
    2001                             2006                           • Scala 2.9.1-1
    • Scala Started                  • Scala v2.0                     (latest)




                      2003/2004                     2011
                      • Scala v1.0                  • Scala 2.9.1




>   Started in 2001 by Martin Odersky
>   Compiles to Java bytecodes
>   Pure object-oriented language
>   Also a functional programming language
                                                                                      25
Why Scala?
>   Shares many language features with JavaFX Script
    that make GUI programming easier:
       Static Type Checking – Catch your errors at compile
        time
       Closures – Wrap behavior and pass it by reference
       Declarative – Express the UI by describing what it
        should look like

>   Scala also supports Type Safe DSLs!
       Implicit Conversions – type safe class extension
       Operator Overloading – with standard precedence rules

                                                                26
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();
    }
}



                                                                                                                                                    27
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)
      }
    }
  }
}

                                                           28
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)
      }
    }
  }
}

                                                           29
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)
      }
    }
  }
}

                                                           30
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)
      }
    }
  }
}

                                                            31
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)
      }
    }
  }
}

                                                         32
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"


                                                      33
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();
                                                34
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();




                                                             35
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


                                                       36
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


                                                     37
Event Listeners in Scala
>   Supported using the built-in Closure syntax
>   Optional arguments for event objects
>   100% type-safe


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


                                                  38
Event Listeners in Scala
>   Supported using the built-in Closure syntax
>   Optional arguments for event objects
>   100% type-safe


    onMouseClicked = {
      Timeline(at(3 s){radius->0}).play()
    }
                 Compact syntax
                    {body}
                                                  39
Event Listeners in Scala
>   Supported using the built-in Closure syntax
>   Optional arguments for event objects Optional event
>   100% type-safe                        parameter
                                        {(event) => body}

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


                                                            40
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.
                                                                                                                  41
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?!?
                                                       42
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.
                                                                                 43
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

                                                                           44
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.

                                                                        45
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?
                                                       46
@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.

                                                                                   47
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?!?

                                                       48
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                                        49
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
                                                                                      50
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!
                                             52

More Related Content

What's hot

ABAP Open SQL & Internal Table
ABAP Open SQL & Internal TableABAP Open SQL & Internal Table
ABAP Open SQL & Internal Tablesapdocs. info
 
REST vs. GraphQL: Critical Look
REST vs. GraphQL: Critical LookREST vs. GraphQL: Critical Look
REST vs. GraphQL: Critical LookNordic APIs
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondKaushal Dhruw
 
Apache Flink Adoption at Shopify
Apache Flink Adoption at ShopifyApache Flink Adoption at Shopify
Apache Flink Adoption at ShopifyYaroslav Tkachenko
 
Introduction to GraphQL: Mobile Week SF
Introduction to GraphQL: Mobile Week SFIntroduction to GraphQL: Mobile Week SF
Introduction to GraphQL: Mobile Week SFAmazon Web Services
 
An Introduction To Oracle Database
An Introduction To Oracle DatabaseAn Introduction To Oracle Database
An Introduction To Oracle DatabaseMeysam Javadi
 
REST vs GraphQL
REST vs GraphQLREST vs GraphQL
REST vs GraphQLSquareboat
 
HTML5--The 30,000' View (A fast-paced overview of HTML5)
HTML5--The 30,000' View (A fast-paced overview of HTML5)HTML5--The 30,000' View (A fast-paced overview of HTML5)
HTML5--The 30,000' View (A fast-paced overview of HTML5)Peter Lubbers
 
Amazon S3 Best Practice and Tuning for Hadoop/Spark in the Cloud
Amazon S3 Best Practice and Tuning for Hadoop/Spark in the CloudAmazon S3 Best Practice and Tuning for Hadoop/Spark in the Cloud
Amazon S3 Best Practice and Tuning for Hadoop/Spark in the CloudNoritaka Sekiyama
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design PatternsLilia Sfaxi
 
Spark SQL Deep Dive @ Melbourne Spark Meetup
Spark SQL Deep Dive @ Melbourne Spark MeetupSpark SQL Deep Dive @ Melbourne Spark Meetup
Spark SQL Deep Dive @ Melbourne Spark MeetupDatabricks
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.boyney123
 
Module 1: Overview of Rational Team Concert
Module 1: Overview of Rational Team ConcertModule 1: Overview of Rational Team Concert
Module 1: Overview of Rational Team ConcertIBM Rational software
 

What's hot (20)

ABAP Open SQL & Internal Table
ABAP Open SQL & Internal TableABAP Open SQL & Internal Table
ABAP Open SQL & Internal Table
 
REST vs. GraphQL: Critical Look
REST vs. GraphQL: Critical LookREST vs. GraphQL: Critical Look
REST vs. GraphQL: Critical Look
 
Internal Hive
Internal HiveInternal Hive
Internal Hive
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & Beyond
 
Apache Flink Adoption at Shopify
Apache Flink Adoption at ShopifyApache Flink Adoption at Shopify
Apache Flink Adoption at Shopify
 
Introduction to GraphQL: Mobile Week SF
Introduction to GraphQL: Mobile Week SFIntroduction to GraphQL: Mobile Week SF
Introduction to GraphQL: Mobile Week SF
 
An Introduction To Oracle Database
An Introduction To Oracle DatabaseAn Introduction To Oracle Database
An Introduction To Oracle Database
 
Introduction to es6
Introduction to es6Introduction to es6
Introduction to es6
 
REST vs GraphQL
REST vs GraphQLREST vs GraphQL
REST vs GraphQL
 
Expressjs
ExpressjsExpressjs
Expressjs
 
HTML5--The 30,000' View (A fast-paced overview of HTML5)
HTML5--The 30,000' View (A fast-paced overview of HTML5)HTML5--The 30,000' View (A fast-paced overview of HTML5)
HTML5--The 30,000' View (A fast-paced overview of HTML5)
 
Amazon S3 Best Practice and Tuning for Hadoop/Spark in the Cloud
Amazon S3 Best Practice and Tuning for Hadoop/Spark in the CloudAmazon S3 Best Practice and Tuning for Hadoop/Spark in the Cloud
Amazon S3 Best Practice and Tuning for Hadoop/Spark in the Cloud
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Spark SQL Deep Dive @ Melbourne Spark Meetup
Spark SQL Deep Dive @ Melbourne Spark MeetupSpark SQL Deep Dive @ Melbourne Spark Meetup
Spark SQL Deep Dive @ Melbourne Spark Meetup
 
Restful api
Restful apiRestful api
Restful api
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
 
Module 1: Overview of Rational Team Concert
Module 1: Overview of Rational Team ConcertModule 1: Overview of Rational Team Concert
Module 1: Overview of Rational Team Concert
 
React Hooks
React HooksReact Hooks
React Hooks
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
 

Viewers also liked

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
 
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...Kai Wähner
 
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
 
Devoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopDevoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopStephen Chin
 
Devoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopDevoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopStephen Chin
 

Viewers also liked (6)

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
 
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
 
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
Raspberry Pi Gaming 4 Kids (Devoxx4Kids)
 
Devoxx4Kids Lego Workshop
Devoxx4Kids Lego WorkshopDevoxx4Kids Lego Workshop
Devoxx4Kids Lego Workshop
 
Devoxx4Kids NAO Workshop
Devoxx4Kids NAO WorkshopDevoxx4Kids NAO Workshop
Devoxx4Kids NAO Workshop
 

Similar to JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)

Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chinjaxconf
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage
Hacking JavaFX with Groovy, Clojure, Scala, and VisageHacking JavaFX with Groovy, Clojure, Scala, and Visage
Hacking JavaFX with Groovy, Clojure, Scala, and VisageStephen 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
 
JavaFX and Scala - Like Milk and Cookies
JavaFX and Scala - Like Milk and CookiesJavaFX and Scala - Like Milk and Cookies
JavaFX and Scala - Like Milk and CookiesStephen Chin
 
Don't panic in Fortaleza - ScalaFX
Don't panic in Fortaleza - ScalaFXDon't panic in Fortaleza - ScalaFX
Don't panic in Fortaleza - ScalaFXAlain Béarez
 
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesJavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesStephen Chin
 
Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)Stephen 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
 
JavaFX Your Way - Devoxx Version
JavaFX Your Way - Devoxx VersionJavaFX Your Way - Devoxx Version
JavaFX Your Way - Devoxx VersionStephen Chin
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Practical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsPractical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsRichard Bair
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011Stephen Chin
 
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...Stephen Chin
 
JavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesJavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesStephen Chin
 
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...Stephen Chin
 
Scala introduction
Scala introductionScala introduction
Scala introductionvito jeng
 
Web components with java by Haijian Wang
Web components with java by Haijian WangWeb components with java by Haijian Wang
Web components with java by Haijian WangGWTcon
 
JavaFX and Scala in the Cloud: Stephen Chin
JavaFX and Scala in the Cloud: Stephen ChinJavaFX and Scala in the Cloud: Stephen Chin
JavaFX and Scala in the Cloud: Stephen Chinjaxconf
 
Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Jiayun Zhou
 

Similar to JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees) (20)

Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage
Hacking JavaFX with Groovy, Clojure, Scala, and VisageHacking JavaFX with Groovy, Clojure, Scala, and Visage
Hacking JavaFX with Groovy, Clojure, Scala, and Visage
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the Cloud
 
JavaFX and Scala - Like Milk and Cookies
JavaFX and Scala - Like Milk and CookiesJavaFX and Scala - Like Milk and Cookies
JavaFX and Scala - Like Milk and Cookies
 
Don't panic in Fortaleza - ScalaFX
Don't panic in Fortaleza - ScalaFXDon't panic in Fortaleza - ScalaFX
Don't panic in Fortaleza - ScalaFX
 
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesJavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
 
Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)Mary Had a Little λ (QCon)
Mary Had a Little λ (QCon)
 
JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]JavaFX 2.0 With Alternative Languages [Portuguese]
JavaFX 2.0 With Alternative Languages [Portuguese]
 
JavaFX Your Way - Devoxx Version
JavaFX Your Way - Devoxx VersionJavaFX Your Way - Devoxx Version
JavaFX Your Way - Devoxx Version
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Practical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsPractical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich Clients
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011
 
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
 
JavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative LanguagesJavaFX 2.0 and Alternative Languages
JavaFX 2.0 and Alternative Languages
 
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
JavaFX 2.0 With Alternative Languages - Groovy, Clojure, Scala, Fantom, and V...
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Web components with java by Haijian Wang
Web components with java by Haijian WangWeb components with java by Haijian Wang
Web components with java by Haijian Wang
 
JavaFX introduction
JavaFX introductionJavaFX introduction
JavaFX introduction
 
JavaFX and Scala in the Cloud: Stephen Chin
JavaFX and Scala in the Cloud: Stephen ChinJavaFX and Scala in the Cloud: Stephen Chin
JavaFX and Scala in the Cloud: Stephen Chin
 
Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015
 

More from 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
 
Raspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFXRaspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFXStephen Chin
 
LUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi HackingLUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi HackingStephen Chin
 

More from 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
 
Raspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFXRaspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFX
 
LUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi HackingLUGOD Raspberry Pi Hacking
LUGOD Raspberry Pi Hacking
 

Recently uploaded

Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?Rustici Software
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
QMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfQMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfROWELL MARQUINA
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Why Agile? - A handbook behind Agile Evolution
Why Agile? - A handbook behind Agile EvolutionWhy Agile? - A handbook behind Agile Evolution
Why Agile? - A handbook behind Agile EvolutionDEEPRAJ PATHAK
 
Dynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientationDynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientationBuild Intuit
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Recently uploaded (20)

Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
QMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdfQMMS Lesson 2 - Using MS Excel Formula.pdf
QMMS Lesson 2 - Using MS Excel Formula.pdf
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Why Agile? - A handbook behind Agile Evolution
Why Agile? - A handbook behind Agile EvolutionWhy Agile? - A handbook behind Agile Evolution
Why Agile? - A handbook behind Agile Evolution
 
Dynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientationDynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientation
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)

  • 1. JavaFX 2.0 and Scala, Like Milk and Cookies Stephen Chin Chief Agile Methodologist, GXS steveonjava@gmail.com tweet: @steveonjava
  • 2. Meet the Presenter Stephen Chin > Chief Agile Methodologist, GXS Family Man > Java Champion > Open Source Hacker  JFXtras Motorcyclist  ScalaFX  Visage > User Group Leader  Silicon Valley JavaFX User Group  Streamed Live!
  • 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.
  • 4. Programming Languages > JavaFX Script is no longer supported by Oracle  Existing JavaFX Script based applications will continue to run  Visage is the open-source successor to the JavaFX Script language > JavaFX 2.0 APIs are now in Java  Pure Java APIs for all of JavaFX  Binding and Sequences exposed as Java APIs  FXML Markup for tooling
  • 7. 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. Example Application public class HelloStage extends Application { @Override public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setWidth(600); stage.setHeight(450); Group root = new Group(); Scene scene = new Scene(root); scene.setFill(Color.LIGHTGREEN); stage.setScene(scene); stage.show(); } public static void main(String[] args) { Application.launch(args); } }
  • 9. Example Application Using Builders public class HelloStage extends Application { @Override public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setScene(SceneBuilder.create() .fill(Color.LIGHTGREEN) .width(600) .height(450) .build()); stage.show(); } public static void main(String[] args) { Application.launch(args); } }
  • 10. Observable Properties > Supports watching for changes to properties > Implemented via anonymous inner classes > Will take advantage of closures in the future
  • 11. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { });
  • 12. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); The property we want to watch rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { });
  • 13. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); Only one listener used with rect.setY(40); generics to specify the data type rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { });
  • 14. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean value) { } }); Refers to the Rectangle.hoverProperty()
  • 15. Observable Pseudo-Properties final Rectangle rect = new Rectangle(); rect.setX(40); rect.setY(40); rect.setWidth(100); rect.setHeight(200); rect.hoverProperty().addListener(new ChangeListener<Boolean>() { public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean value) { rect.setFill(rect.isHover() ? Color.GREEN : Color.RED); } });
  • 16. Binding > Unquestionably the biggest JavaFX Script innovation > Supported via a PropertyBinding class > Lazy invocation for high performance > Static construction syntax for simple cases  e.g.: bind(<property>), bindBiDirectional(<property>)
  • 17. Sequences in Java > Replaced with an Observable List > Public API is based on JavaFX sequences > Internal code can use lighter collections API > JavaFX 2.0 also has an Observable Map
  • 19. 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…] } }
  • 20. 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); } 20
  • 21. Setup Binding circle.strokeWidthProperty().bind(Bindings .when(circle.hoverProperty()) .then(4) .otherwise(0) ); 21
  • 22. 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(); } }); 22
  • 23. 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(); 23
  • 25. What is Scala 2012 2001 2006 • Scala 2.9.1-1 • Scala Started • Scala v2.0 (latest) 2003/2004 2011 • Scala v1.0 • Scala 2.9.1 > Started in 2001 by Martin Odersky > Compiles to Java bytecodes > Pure object-oriented language > Also a functional programming language 25
  • 26. Why Scala? > Shares many language features with JavaFX Script that make GUI programming easier:  Static Type Checking – Catch your errors at compile time  Closures – Wrap behavior and pass it by reference  Declarative – Express the UI by describing what it should look like > Scala also supports Type Safe DSLs!  Implicit Conversions – type safe class extension  Operator Overloading – with standard precedence rules 26
  • 27. 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(); } } 27
  • 28. 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) } } } } 28
  • 29. 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) } } } } 29
  • 30. 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) } } } } 30
  • 31. 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) } } } } 31
  • 32. 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) } } } } 32
  • 33. 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" 33
  • 34. 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(); 34
  • 35. 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(); 35
  • 36. 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 36
  • 37. 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 37
  • 38. Event Listeners in Scala > Supported using the built-in Closure syntax > Optional arguments for event objects > 100% type-safe onMouseClicked = { Timeline(at(3 s){radius->0}).play() } 38
  • 39. Event Listeners in Scala > Supported using the built-in Closure syntax > Optional arguments for event objects > 100% type-safe onMouseClicked = { Timeline(at(3 s){radius->0}).play() } Compact syntax {body} 39
  • 40. Event Listeners in Scala > Supported using the built-in Closure syntax > Optional arguments for event objects Optional event > 100% type-safe parameter {(event) => body} onMouseClicked = { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() } 40
  • 41. 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. 41
  • 42. 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?!? 42
  • 43. 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. 43
  • 44. 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 44
  • 45. 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. 45
  • 46. 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? 46
  • 47. @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. 47
  • 48. 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?!? 48
  • 49. 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 49
  • 50. 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 50
  • 51. 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/
  • 52. Stephen Chin steveonjava@gmail.com tweet: @steveonjava Pro JavaFX 2 Platform Available Now! 52

Editor's Notes

  1. Stage.add??