JavaFX 2.0 With Alternative Languages [Portuguese]
1. Plataforma JavaFX 2.0,
GroovyFX, ScalaFX e Visage
Stephen Chin
Chefe de metodologias Ageis, GXS
steveonjava@gmail.com
tweet: @steveonjava
Translated by Marcelo Quinta
2. Conheca o palestrante
Stephen Chin
http://steveonjava.com/
• Java Champion
• Autor
Family Man • Pro JavaFX Platform
• Pro Android Flash
• Fundador de projetos Open
Motorcyclist Source
• JFXtras
• ScalaFX
• WidgetFX
• Visage
3. A plataforma JavaFX 2.0
Experiencia imersiva Desktop combinando o
melhor do JavaFX e HTML5
> Use seus conhecimentos Java com as
modernas APIs JavaFX
> Integre Java, JavaScript e HTML5 na mesma
aplicacao
> Nova gama de graficos usa as vantagens de
aceleracao de hardware para aplicacoes 2D e
3D
> Use sua IDE favorita:
NetBeans, Eclipse, IntelliJ, etc.
4. JavaFX agora e Open Source!
Parte do projeto OpenJDK
Controles disponiveis agora
codigo adicional adicionado
incrementalmente
Pagina do projeto:
> http://openjdk.java.net/projects/openjfx/
4
5. E vai rodar nos Tablets!
> iPad (iOS)
> Linux
(plataforma
popular que
executa algo
semelhante a
Java)
Nenhuma data de release foi anunciada
5
6. Construindo Aplicacoes JavaFX
> Pode ser executada no navegador ou no Desktop
> Inclui builders para construcoes declarativas
> Linguagens alternativas tambem podem ser utilizadas para
simplificar a criacao da interface de usuario
GroovyFX
ScalaFX
Visage
6
7. Ola JUG (Versao Java)
public class HelloJUG extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Ola JUG");
Group root = new Group();
Scene scene = new Scene(root, 400, 250, Color.ALICEBLUE);
Text text = new Text();
text.setX(105);
text.setY(120);
text.setFont(new Font(30));
text.setText("Ola JUG");
root.getChildren().add(text);
primaryStage.setScene(scene);
primaryStage.show();
}
}
7
8. Ola JUG (Versao com o Builder)
public void start(Stage primaryStage) {
primaryStage.setTitle("Ola JUG");
primaryStage.setScene(SceneBuilder.create()
.width(400)
.height(250)
.fill(Color.ALICEBLUE)
.root(
GroupBuilder.create().children(
TextBuilder.create()
.x(105)
.y(120)
.text("Ola JUG")
.font(new Font(30))
.build()
).build()
)
.build());
primaryStage.show();
}
8
10. Ola JUG (Versao JavaFX)
object HelloJUG extends JFXApp {
stage = new Stage {
title = "Ola JUG"
width = 400
height = 250
scene = new Scene {
fill = BLUE
Text {
x = 105
y = 120
text = "Ola JUG"
font = Font(size: 30)
}
}
}
}
10
11. Ola JUG (Versao Visage)
Stage {
title: "Ola JUG"
width: 400
height: 250
scene: Scene {
fill: BLUE
content: Text {
x: 105
y: 120
text: "Ola JUG"
font: Font {size: 30pt}
}
}
}
11
12. Mostrando HTML no JavaFX
public class WebViewTest extends Application {
public static void main(String[] args) {
launch(WebViewTest.class, args);
}
@Override public void start(Stage stage) {
WebView webView = new WebView();
webView.getEngine().load("http://google.com");
Scene scene = new Scene(webView);
stage.setScene(scene);
stage.setTitle("Web Test");
stage.show();
}}
12
15. Respondendo a eventos do browser
Eventos suportados:
> Alert/Confirm/Prompt:
Responda funcoes do Javascript de interacao do usuario
> Resize:
Web page move-se ou rearranja ao tamanho da janela
> Status
Web page muda o texto do status
> Visibility
Esconde ou mostra algum objeto da janela
> Popup
Cria uma segunda janela
15
18. Features of Groovy
> Linguagem moderna
Closures
Transforms AST
Linguagem fortemente tipada
> Grande integracao com Java
Muito facil fazer a portabilidade de Java para Groovy
> Sintaxe declarativa com builders GroovyFX
Familiar aos desenvolvedores Groovy e JavaFX Script
19. Java vs. GroovyFX DSL
public class HelloStage extends Application { GroovyFX.start { stage ->
def sg = new SceneGraphBuilder(stage)
public void start(Stage stage) {
stage.setTitle("Hello Stage"); sg.stage(title: “Hello Stage”, width: 600, height: 450) {
stage.setWidth(600); scene(fill: groovyblue) {
stage.setHeight(450); rectangle(x: 25, y: 40, width: 100, height: 50, fill:
Scene scene = new Scene(); red)
scene.setFill(Color.LIGHTGREEN); }
21 Linhas
Rectangle rect = new Rectangle();
rect.setX(25); }
} 8 Linhas
rect.setY(40);
430 Caracteres
rect.setWidth(100);
rect.setHeight(50);
180 Caracteres
rect.setFill(Color.RED);
scene.setRoot(new Group(rect));
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(HelloStage.class, args);
}
}
19
28. Propriedades em GroovyFX
public class Person {
@FXBindable String firstName;
@FXBindable String lastName = “Smith”;
}
Inicializadores opcionais
28
29. Propriedades em GroovyFX
public class Person {
@FXBindable String firstName;
@FXBindable String lastName = “Smith”;
}
Valores get and set
def p = new Person()
def last = p.lastName
p.firstName = “Agent”
29
30. Propriedades em GroovyFX
public class Person {
@FXBindable String firstName;
@FXBindable String lastName = “Smith”;
}
def p = new Person()
def last = p.lastName Acesso a propriedades
p.firstName = “Agent” embutidas para binding
textField(text: bind(p.lastNameProperty()))
30
31. Binding em GroovyFX
@FXBindable
class Time {
Integer hours
Integer minutes
Integer seconds
Double hourAngle
Double minuteAngle
Double secondAngle
public Time() {
// bind the angle properties to the clock time
hourAngleProperty().bind((hoursProperty() * 30.0) + (minutesProperty() * 0.5))
minuteAngleProperty().bind(minutesProperty() * 6.0)
secondAngleProperty().bind(secondsProperty() * 6.0)
}
}
31
32. Animation em GroovyFX
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {
at (1000.ms) {
change(rect1, 'x') to 200 tween ease_both
change rect2.yProperty() to 200 tween linear
}
}.play()
32
33. Animation em GroovyFX
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {
at (1000.ms) {
change(rect1, 'x') to 200 tween ease_both
change rect2.yProperty() to 200 tween linear
}
}.play()
Sintaxe facil para animacoes:
at (duration) {keyframes}
33
34. Animation em GroovyFX
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {
at (1000.ms) {
change(rect1, 'x') to 200
change rect2.yProperty() to 200
}
}.play()
Key frame DSL
34
35. Animation em GroovyFX
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {
at (1000.ms) {
change(rect1, 'x') to 200 tween ease_both
change rect2.yProperty() to 200 tween linear
}
}.play()
Controle de velocidade opcional
35
36. Event Listeners em GroovyFX
> Sintaxe para Closure usando controles embutidos
> Argumentos opcionais para eventos
onMouseClicked { e ->
timeline {
at(3.s) { change e.source.radiusProperty() to 0 }
}.play()
}
36
37. Event Listeners em GroovyFX
> Sintaxe para Closure usando controles embutidos
> Argumentos opcionais para eventos
onMouseClicked { MouseEvent e ->
timeline {
at(3.s) { change e.source.radiusProperty() to 0 }
}.play()
}
Sintaxe compacta
{body}
37
38. Event Listeners em GroovyFX
> Sintaxe para Closure usando controles embutidos
Parametros opcionais para
> Argumentos opcionais para eventos eventos
{event -> body}
onMouseClicked { MouseEvent e ->
timeline {
at(3.s) { change e.source.radiusProperty() to 0 }
}.play()
}
38
39. TableView em Java
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);
39
49. O Que e Scala
2001 2006
• Scala Comecou • Scala v2.0
2003/2004 2011
• Scala v1.0 • Scala 2.9.0 (ultima)
> Comecou em 2001 by Martin Odersky
> Compila para bytecodes Java
> Linguagem puramente orientada a objetos
> Tambem para programacao declarativa
49
50. Por que Scala?
> Compartilha muitas funcionalidades do JavaFX Script que fazem a
programacao de interfaces mais facil:
Checagem estatica de tipos – Encontre seus erros em tempo de
compilacao
Closures – Misture os comportamentos e passe-os como referencia
Declarativa – Expresse a interface como ela deve aparecer
> Scala tambem suporta Type Safe DSLs!
Conversoes implicitas – extensao de classes typesafe
Overloading de operadores – com regras de precedencia
DelayedInit / @specialized – funcionalides avancadas da linguagem
50
51. Java vs. Scala DSL
public class HelloStage extends Application { object HelloJavaFX extends JFXApp {
stage = new Stage {
public void start(Stage stage) { title = "Hello Stage"
stage.setTitle("Hello Stage"); width = 600
stage.setWidth(600); height = 450
stage.setHeight(450); scene = new Scene {
Scene scene = new Scene(); fill = LIGHTGREEN
scene.setFill(Color.LIGHTGREEN); content = Seq(new Rectangle {
21 Linhas
Rectangle rect = new Rectangle();
rect.setX(25); 17 Linhas
x = 25
y = 40
rect.setY(40); width = 100
430 Caracteres
rect.setWidth(100);
rect.setHeight(50);
177 Caracteres
height = 50
fill = RED
rect.setFill(Color.RED); })
scene.setRoot(new Group(rect)); }
stage.setScene(scene); }
stage.show(); }
}
public static void main(String[] args) {
launch(HelloStage.class, args);
}
}
51
52. object DisappearingCircles 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)
}
}
}
}
52
53. object DisappearingCircles extends JFXApp {
stage = new Stage {
title = "Disappearing Circles"
width = 800
height = 600
Classe base para aplicacoes JavaFX
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)
}
}
}
}
53
54. object DisappearingCircles extends JFXApp {
stage = new Stage {
title = "Disappearing Circles"
width = 800
height = 600
scene = new Scene { Definicao declarativa do Stage
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)
}
}
}
}
54
55. object DisappearingCircles extends JFXApp {
stage = new Stage {
title = "Disappearing Circles" Definicoes de propriedades
width = 800
height = 600 embutidas
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)
}
}
}
}
55
56. object DisappearingCircles extends JFXApp {
stage = new Stage {
title = "Disappearing Circles"
width = 800
height = 600 Criacao de sequencias via
scene = new Scene { Loop
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)
}
}
}
}
56
57. Binding em 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"
57
58. Animation em 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();
58
59. Animacoes JavaFX Script-like
Animation em 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();
59
60. 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
)
}
}
overloading de operadores para
timeline.play();
sintaxe da animacao
60
61. 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(); Controle de
velocidade opcional
61
62. Event Listeners em Scala
> Suportado usando sintaxe Closure embutida
> Argumentos opcionais para tratamento de eventos
> 100% tipagem forte
onMouseClicked = {
Timeline(at(3 s){radius->0}).play()
}
62
63. Event Listeners em Scala
> Suportado usando sintaxe Closure embutida
> Argumentos opcionais para tratamento de eventos
> 100% tipagem forte
onMouseClicked = {
Timeline(at(3 s){radius->0}).play()
}
Sintaxe compacta
{body}
63
64. Event Listeners em Scala
> Suportado usando sintaxe Closure embutida
> Argumentos opcionais para tratamento de eventos
Evento = parametro opcional
> 100% tipagem forte {(event) => body}
onMouseClicked = { (e: MouseEvent) =>
Timeline(at(3 s){radius->0}).play()
}
64
65. Sobre o projeto Visage
> “Visage e uma domain specific language (DSL) projetada para
suportar a funcao de construcao de interfaces.”
> Metas do projeto Visage:
Compila para JavaFX Java APIs
Envolve toda a linguagem (Annotations, Maps, etc.)
Suporta outros Toolkits
> Venha participar do time!
> Para mais informacoes: http://visage-lang.org/
65
66. E sobre o JavaFX no… Visage
Stage {
title: "Hello Stage"
width: 600
height: 450
scene: Scene {
fill: Color.LIGHTGREEN
content: Rectangle {
x: 25
y: 40
width: 100
height: 50
fill: Color.RED
}
}
}
66
67. E sobre o JavaFX no… Visage
Stage {
title: "Hello Stage"
width: 600
height: 450
scene: Scene {
fill: Color.LIGHTGREEN
content: Rectangle {
x: 25
y: 40
width: 100
height: 50
fill: Color.RED
}
}
}
67
68. E sobre o JavaFX no… Visage
Stage {
title: "Hello Stage"
width: 600
height: 450
Scene {
fill: Color.LIGHTGREEN
Rectangle {
x: 25
y: 40
width: 100
height: 50
fill: Color.RED
}
}
}
68
69. Visage e um JavaFX Script++
> Parametros padrao
> Nova sintaxe para:
Angulos – 35deg, 4rad, 1turn
Cores – #DDCCBB, #AA33AA|CC
Medidas – 5px, 2pt, 3in, 4sp
> Checagem de null-reference
var width = rect!.width
> Bindable Maps embutida (Em breve!)
var fruitMap = ["red" : apple, "yellow" : banana]
var fruit = bind fruitMap["red"]
69
70. Visage e JavaFX 2.0 foram feitos um para o outro…
> Binding melhorado
Retem a avaliacao tardia de variaveis com um poder expressivo
adicional
> Colecoes integradas
Sequencias e mapas automaticamente convertidos entre JavaFX
Observable Lists/Maps
> Sintaxe de animacoes embutida
Coloca o JavaFX em um subsistema de animacoes
Prove uma API mais limpa e consistente
70
71. Conclusao
> Voce pode escrever aplicacoes JavaFX com Java puro
> JavaFX tambem e utilizavel por linguagens alternativas
> Voce pode ter o suporte melhorado utilizando bibliotecas
DSL
GroovyFX
ScalaFX
> Ou uma linguagem de interfaces que roda na JVM
Visage
72. Pro JavaFX 2 Platform em breve!
> Primeiro trimestre de 2012
> Todos os exemplos reescritos em Java
> Cobre as novas bibliotecas da versao
2.0
> Incluira ScalaFX, GroovyFX e Visage
72