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 (20)

Sql and Sql commands
Sql and Sql commandsSql and Sql commands
Sql and Sql commands
 
Css font properties
Css font propertiesCss font properties
Css font properties
 
Java I/o streams
Java I/o streamsJava I/o streams
Java I/o streams
 
Hash table in java
Hash table in javaHash table in java
Hash table in java
 
MySQL for beginners
MySQL for beginnersMySQL for beginners
MySQL for beginners
 
Images and Tables in HTML
Images and Tables in HTMLImages and Tables in HTML
Images and Tables in HTML
 
Html forms
Html formsHtml forms
Html forms
 
Java Foundations: Methods
Java Foundations: MethodsJava Foundations: Methods
Java Foundations: Methods
 
Sql ppt
Sql pptSql ppt
Sql ppt
 
CSS Introduction
CSS IntroductionCSS Introduction
CSS Introduction
 
css.ppt
css.pptcss.ppt
css.ppt
 
Stored procedure
Stored procedureStored procedure
Stored procedure
 
MongoDB, E-commerce and Transactions
MongoDB, E-commerce and TransactionsMongoDB, E-commerce and Transactions
MongoDB, E-commerce and Transactions
 
Javascript arrays
Javascript arraysJavascript arrays
Javascript arrays
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
MySql slides (ppt)
MySql slides (ppt)MySql slides (ppt)
MySql slides (ppt)
 
PHP and Mysql
PHP and MysqlPHP and Mysql
PHP and Mysql
 
[OOP - Lec 18] Static Data Member
[OOP - Lec 18] Static Data Member[OOP - Lec 18] Static Data Member
[OOP - Lec 18] Static Data Member
 
Database connectivity in python
Database connectivity in pythonDatabase connectivity in python
Database connectivity in python
 
Java Method, Static Block
Java Method, Static BlockJava Method, Static Block
Java Method, Static Block
 

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

Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
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
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 

Último (20)

Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
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
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 

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