SlideShare uma empresa Scribd logo
1 de 52
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

Mais conteúdo relacionado

Mais procurados

Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020Matt Raible
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorVMware Tanzu
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency InjectionAnuj Singh Rajput
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교JungWoon Lee
 
Kostas Kloudas - Extending Flink's Streaming APIs
Kostas Kloudas - Extending Flink's Streaming APIsKostas Kloudas - Extending Flink's Streaming APIs
Kostas Kloudas - Extending Flink's Streaming APIsVerverica
 
Scaling containers with KEDA
Scaling containers with KEDAScaling containers with KEDA
Scaling containers with KEDANilesh Gule
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolvedtrxcllnt
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101Will Button
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life CycleXinchen Hui
 
How to create a multi tenancy for an interactive data analysis with jupyter h...
How to create a multi tenancy for an interactive data analysis with jupyter h...How to create a multi tenancy for an interactive data analysis with jupyter h...
How to create a multi tenancy for an interactive data analysis with jupyter h...Tiago Simões
 
Defending against Java Deserialization Vulnerabilities
 Defending against Java Deserialization Vulnerabilities Defending against Java Deserialization Vulnerabilities
Defending against Java Deserialization VulnerabilitiesLuca Carettoni
 
Spring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsSpring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsGuy Nir
 
Removing performance bottlenecks with Kafka Monitoring and topic configuration
Removing performance bottlenecks with Kafka Monitoring and topic configurationRemoving performance bottlenecks with Kafka Monitoring and topic configuration
Removing performance bottlenecks with Kafka Monitoring and topic configurationKnoldus Inc.
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryMauro Rocco
 
Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S...
 Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S... Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S...
Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S...HostedbyConfluent
 
Pwning mobile apps without root or jailbreak
Pwning mobile apps without root or jailbreakPwning mobile apps without root or jailbreak
Pwning mobile apps without root or jailbreakAbraham Aranguren
 

Mais procurados (20)

Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency Injection
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교
 
Kostas Kloudas - Extending Flink's Streaming APIs
Kostas Kloudas - Extending Flink's Streaming APIsKostas Kloudas - Extending Flink's Streaming APIs
Kostas Kloudas - Extending Flink's Streaming APIs
 
Scaling containers with KEDA
Scaling containers with KEDAScaling containers with KEDA
Scaling containers with KEDA
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
 
How to create a multi tenancy for an interactive data analysis with jupyter h...
How to create a multi tenancy for an interactive data analysis with jupyter h...How to create a multi tenancy for an interactive data analysis with jupyter h...
How to create a multi tenancy for an interactive data analysis with jupyter h...
 
Defending against Java Deserialization Vulnerabilities
 Defending against Java Deserialization Vulnerabilities Defending against Java Deserialization Vulnerabilities
Defending against Java Deserialization Vulnerabilities
 
Spring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsSpring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topics
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Removing performance bottlenecks with Kafka Monitoring and topic configuration
Removing performance bottlenecks with Kafka Monitoring and topic configurationRemoving performance bottlenecks with Kafka Monitoring and topic configuration
Removing performance bottlenecks with Kafka Monitoring and topic configuration
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
 
Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S...
 Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S... Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S...
Walking through the Spring Stack for Apache Kafka with Soby Chacko | Kafka S...
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Pwning mobile apps without root or jailbreak
Pwning mobile apps without root or jailbreakPwning mobile apps without root or jailbreak
Pwning mobile apps without root or jailbreak
 

Destaque

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
 

Destaque (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
 

Semelhante a 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
 

Semelhante a 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
 

Mais 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
 
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
 

Mais 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
 
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
 

Último

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
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
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
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
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
 
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
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
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
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
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
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
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
 

Último (20)

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
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
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
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
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
 
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
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
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
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
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
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
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
 

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

Notas do Editor

  1. Stage.add??