53
Raspberry Pi à la GroovyFX Stephen Chin (@steveonjava) Java Technology Ambassador JavaOne Content Chair

Raspberry Pi à la GroovyFX

Embed Size (px)

DESCRIPTION

Presentation on Raspberry Pi and GroovyFX given at the GR8Conf conference in Copenhagen, Denmark.

Citation preview

Page 1: Raspberry Pi à la GroovyFX

Raspberry Pi à la GroovyFXStephen Chin (@steveonjava)Java Technology AmbassadorJavaOne Content Chair

Page 2: Raspberry Pi à la GroovyFX

What Runs Java?

Example of devices powered by JavaSMALL

RFID Readers Parking Meters Intelligent Power

Module Smart Meters

LARGE

Multi Function Printers ATMs POS Systems In-Flight Entertainment Systems Electronic Voting Systems Medical Imaging Systems

MEDIUM

Routers & Switches Storage Appliances Network Management

Systems Factory Automation Systems Security Systems

Page 3: Raspberry Pi à la GroovyFX

Java and 3G in a Tiny Package

> Cinterion EHS5

Page 4: Raspberry Pi à la GroovyFX

Really Tiny…

27.6mm

18.8

mm

Page 5: Raspberry Pi à la GroovyFX

http://upload.wikimedia.org/wikipedia/commons/3/3d/Cloud_forest_Ecuador.jpg

Page 6: Raspberry Pi à la GroovyFX

=

Have Java With Your Dessert

Page 7: Raspberry Pi à la GroovyFX

http://elinux.org/File:Raspi-Model-AB-Mono-2-699x1024.png

Page 8: Raspberry Pi à la GroovyFX

And what are these for?

http://i.imgur.com/k0Puu.jpg

Page 9: Raspberry Pi à la GroovyFX

I2C Hardware via Pi4J

3.3V/GND

MPU-9150

Page 10: Raspberry Pi à la GroovyFX

Chalkboard Electronics Touchscreen

10" or 7" Form Factor

Connects via HDMI/USB

Tested with JavaFX 8

10% Exclusive Discount:

G1F0U796Z083

Page 11: Raspberry Pi à la GroovyFX

How to Setup Your Pi

> Step 1: Install Linux

http://steveonjava.com/javafx-on-raspberry-pi-3-easy-steps/

Page 12: Raspberry Pi à la GroovyFX

How to Setup Your Pi

> Step 2: Download/Copy Java 8 for ARM EA

http://steveonjava.com/javafx-on-raspberry-pi-3-easy-steps/

Page 13: Raspberry Pi à la GroovyFX

How to Setup Your Pi

> Step 3: Deploy and Run JavaFX Apps

http://steveonjava.com/javafx-on-raspberry-pi-3-easy-steps/

Page 14: Raspberry Pi à la GroovyFX

JavaFX With Groovy

Page 15: Raspberry Pi à la GroovyFX

JavaFX 2.0 Platform

Immersive Application Experience

Leverage your Java skills with modern JavaFX APIs

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

Page 16: Raspberry Pi à la GroovyFX

16

Vanishing Circles

Page 17: Raspberry Pi à la GroovyFX

Vanishing Circles in Javapublic 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); 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.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(); } }); circle.setStroke(Color.WHITE); circle.strokeWidthProperty().bind(Bindings.when(circle.hoverProperty()) .then(4) .otherwise(0)); circles.add(circle); } root.getChildren().addAll(circles); primaryStage.setScene(scene); primaryStage.show(); 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(); }}

17

40 Lines1299 Characters

Page 18: Raspberry Pi à la GroovyFX

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…] }}

Page 19: Raspberry Pi à la GroovyFX

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

19

Page 20: Raspberry Pi à la GroovyFX

Setup Binding

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

20

Page 21: Raspberry Pi à la GroovyFX

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

21

Page 22: Raspberry Pi à la GroovyFX

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

22

Page 23: Raspberry Pi à la GroovyFX

Features of Groovy

> Modern language Closures AST Transforms Strongly typed dynamic language

> Tight integration with Java Very easy to port from Java to Groovy

> Declarative syntax with GroovyFX Builders Familiar to Groovy and JavaFX Script developers

Page 24: Raspberry Pi à la GroovyFX

Java vs. GroovyFX DSLpublic 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); 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.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(); } }); circle.setStroke(Color.WHITE); circle.strokeWidthProperty().bind(Bindings.when(circle.hoverProperty()) .then(4) .otherwise(0)); circles.add(circle); } root.getChildren().addAll(circles); primaryStage.setScene(scene); primaryStage.show(); 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(); }}

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) onMouseClicked { e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 } }.play() } } } }

timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { circles.each { circle -> at (40.s) { change circle.centerXProperty() to rand(800) change circle.centerYProperty() to rand(600) } } }.play() }}

24

40 Lines1299 Characters

29 Lines671 Characters

Page 25: Raspberry Pi à la GroovyFX

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) {

fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } }}

25

Page 26: Raspberry Pi à la GroovyFX

26

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } }}

Builder for GroovyFX scene graphs

Page 27: Raspberry Pi à la GroovyFX

27

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) {

fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } }}

Declarative Stage definition

Page 28: Raspberry Pi à la GroovyFX

28

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) {

fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } }}

Inline property definitions

Page 29: Raspberry Pi à la GroovyFX

29

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) {

fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } }}

Bind to properties

Page 30: Raspberry Pi à la GroovyFX

30

GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() def rand = new Random().&nextInt def circles = []

sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circles << circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: {val -> val ? 4 : 0})) {

fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } } }}

Sequence Creation Via Loop

Page 31: Raspberry Pi à la GroovyFX

Animation in GroovyFX

timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { circles.each { circle -> at (40.s) { change circle.centerXProperty() to rand(800) change circle.centerYProperty() to rand(600) } }}.play()

31

Page 32: Raspberry Pi à la GroovyFX

timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { circles.each { circle -> at (40.s) { change circle.centerXProperty() to rand(800) change circle.centerYProperty() to rand(600) } }}.play()

Animation in GroovyFX

32

Easy animation syntax: at (duration) {keyframes}

Page 33: Raspberry Pi à la GroovyFX

timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { circles.each { circle -> at (40.s) { change circle.centerXProperty() to rand(800) change circle.centerYProperty() to rand(600) } }}.play()

Animation in GroovyFX

33

Key frame DSL

Page 34: Raspberry Pi à la GroovyFX

timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) { circles.each { circle -> at (40.s) { tween ease_both change circle.centerYProperty() to rand(600) tween linear } }}.play()

Animation in GroovyFX

34

Optional easing

Page 35: Raspberry Pi à la GroovyFX

Event Listeners in GroovyFX

35

> Supported using the built-in Closure syntax> Optional arguments for event objects

onMouseClicked { e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 }

}.play()}

Page 36: Raspberry Pi à la GroovyFX

Event Listeners in GroovyFX

> Supported using the built-in Closure syntax> Optional arguments for event objects

36

Compact syntax{body}

onMouseClicked { MouseEvent e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 }

}.play()}

Page 37: Raspberry Pi à la GroovyFX

Event Listeners in GroovyFX

> Supported using the built-in Closure syntax> Optional arguments for event objects

37

Optional event parameter{event -> body}

onMouseClicked { MouseEvent e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 }

}.play()}

Page 38: Raspberry Pi à la GroovyFX

38

But wait, there is more Grooviness…

Page 39: Raspberry Pi à la GroovyFX

Properties in Java

public class Person { private StringProperty firstName; public void setFirstName(String val) { firstNameProperty().set(val); } public String getFirstName() { return firstNameProperty().get(); } public StringProperty firstNameProperty() { if (firstName == null) firstName = new SimpleStringProperty(this, "firstName"); return firstName; } private StringProperty lastName; public void setLastName(String value) { lastNameProperty().set(value); } public String getLastName() { return lastNameProperty().get(); } public StringProperty lastNameProperty() { if (lastName == null) // etc. } }

39

Page 40: Raspberry Pi à la GroovyFX

Properties in GroovyFX

public class Person { @FXBindable String firstName; @FXBindable String lastName;}

40

Page 41: Raspberry Pi à la GroovyFX

public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”;}

Properties in GroovyFX

41

Optional initializers

Page 42: Raspberry Pi à la GroovyFX

TableView in Java

42

ObservableList<Person> items = ...TableView<Person> tableView = new TableView<Person>(items); TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");

firstNameCol.setCellValueFactory( new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() { public ObservableValue<String> call(CellDataFeatures<Person, String> p) { return p.getValue().firstNameProperty(); }}); tableView.getColumns().add(firstNameCol);

Page 43: Raspberry Pi à la GroovyFX

TableView in GroovyFX

43

def dateFormat = new SimpleDateFormat("yyyy-MM-dd");

tableView(items: persons) { tableColumn(property: "name", text: "Name", prefWidth: 150) tableColumn(property: "age", text: "Age", prefWidth: 50) tableColumn(property: "gender", text: "Gender", prefWidth: 150) tableColumn(property: "dob", text: "Birth", prefWidth: 150, type: Date, converter: { from -> return dateFormat.format(from) })}

Page 44: Raspberry Pi à la GroovyFX

Layout in Java

44

TextField urlField = new TextField(“http://www.google.com”);HBox.setHgrow(urlField, Priority.ALWAYS);

HBox hbox = new HBox();hbox.getChildren().add(urlField);

WebView webView = new WebView();VBox.setVgrow(webView, Priority.ALWAYS);

VBox vbox = new VBox();vbox.getChildren().addAll(hbox, webView);

Page 45: Raspberry Pi à la GroovyFX

Layout in GroovyFX

45

sg.stage(title: "GroovyFX WebView Demo", show: true) { scene(fill: groovyblue, width: 1024, height: 800) { vbox { hbox(padding: 10, spacing: 5) { textField(“http://www.yahoo.com”, hgrow: "always") button("Go”) } webView(vgrow: "always") } }}

Page 46: Raspberry Pi à la GroovyFX

Layout in GroovyFX

46

Page 47: Raspberry Pi à la GroovyFX

Layout in GroovyFX

47

gridPane(hgap: 5, vgap: 10, padding: 25) { columnConstraints(minWidth: 50, halignment: "right") columnConstraints(prefWidth: 250) label("Send Us Your Feedback", font: "24pt sanserif", row: 0, columnSpan: GridPane.REMAINING, halignment: "center", margin: [0, 0, 10])

label("Name: ", row: 1, column: 0) textField(promptText: "Your name", row: 1, column: 1, hgrow: 'always')

label("Email:", row: 2, column: 0) textField(promptText: "Your email", row: 2, column: 1, hgrow: 'always')

label("Message:", row: 3, column: 0, valignment: "baseline") textArea(row: 3, column: 1, hgrow: "always", vgrow: "always")

button("Send Message", row: 4, column: 1, halignment: "right")}

Page 48: Raspberry Pi à la GroovyFX

Layout in GroovyFX

48

Page 49: Raspberry Pi à la GroovyFX

GroovyFX Supports…

49

Page 50: Raspberry Pi à la GroovyFX

And you can do cool stuff like this…

https://bitbucket.org/stephanj/tweetwall

Page 51: Raspberry Pi à la GroovyFX

Conclusion

JavaFX enables graphically rich, fast performing apps

Visually create applications using Scene Builder

Run on Raspberry Pi today!

Page 52: Raspberry Pi à la GroovyFX

Stephen Chintweet: @steveonjavablog: http://steveonjava.com

nighthacking.com

Real GeeksLive Hacking

NightHacking Tour

Page 53: Raspberry Pi à la GroovyFX

The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.