Upload
stephen-chin
View
113
Download
4
Embed Size (px)
DESCRIPTION
JavaFX 2.0 With Alternative Languages talk given at JavaOne Brazil and translated to Portuguese by Marcelo Quinta.
Citation preview
Plataforma JavaFX 2.0, GroovyFX, ScalaFX e Visage
Stephen ChinChefe de metodologias Ageis, [email protected]: @steveonjava
Translated by Marcelo Quinta
Conheca o palestranteStephen Chin
http://steveonjava.com/
Motorcyclist
Family Man
• Java Champion• Autor
• Pro JavaFX Platform• Pro Android Flash
• Fundador de projetos Open Source
• JFXtras• ScalaFX• WidgetFX• Visage
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.
JavaFX agora e Open Source!
Parte do projeto OpenJDK
Controles disponiveis agoracodigo adicional adicionado
incrementalmente
Pagina do projeto:> http://openjdk.java.net/projects/openjfx/
4
E vai rodar nos Tablets!
5
> iPad (iOS)>Linux
(plataforma popular que executa algo semelhante a Java)
Nenhuma data de release foi anunciada
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(); }}
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();}
9
Ola JUG (Versao GroovyFX)GroovyFX.start { primaryStage -> def sg = new SceneGraphBuilder() sg.stage( title: 'Ola JUG', show: true) { scene( fill: aliceblue, width: 400, height: 250) { text( x: 105, y: 120, text: "Ola JUG" font: "30pt") } }}
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) } } }}
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} } }}
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
Mostrando HTML no JavaFX
13
Chamando Javascript pelo JavaFX
String script = "alert('Aooo Goiania!');”;eng.executeScript(script);
14
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 janela15
Demo de integracao HTML5/JavaFX
16
JavaFX com Groovy
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
Java vs. GroovyFX DSLpublic class HelloStage extends Application {
public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setWidth(600); stage.setHeight(450); Scene scene = new Scene(); scene.setFill(Color.LIGHTGREEN); Rectangle rect = new Rectangle(); rect.setX(25); rect.setY(40); rect.setWidth(100); rect.setHeight(50); rect.setFill(Color.RED); scene.setRoot(new Group(rect)); stage.setScene(scene); stage.show(); }
public static void main(String[] args) { launch(HelloStage.class, args); }}
GroovyFX.start { stage -> def sg = new SceneGraphBuilder(stage)
sg.stage(title: “Hello Stage”, width: 600, height: 450) {
scene(fill: groovyblue) { rectangle(x: 25, y: 40, width: 100, height: 50,
fill: red) } }}
19
21 Linhas430 Caracteres
8 Linhas180 Caracteres
def sg = new SceneGraphBuilder()def hc = { hover -> hover ? 4 : 0 }
sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3)
} } }}
20
21
def sg = new SceneGraphBuilder()def hc = { hover -> hover ? 4 : 0 }
sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3) } } }}
Builder para Scene Graphs do GroovyFX
22
def sg = new SceneGraphBuilder()def hc = { hover -> hover ? 4 : 0 }
sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3)
} } }}
Definicao declarativa do Stage
23
def sg = new SceneGraphBuilder()def hc = { hover -> hover ? 4 : 0 }
sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3)
} } }}
Definicao de propriedades embutdidas
24
def sg = new SceneGraphBuilder()def hc = { hover -> hover ? 4 : 0 }
sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3)
} } }}
Bind para propriedades
25
def sg = new SceneGraphBuilder()def hc = { hover -> hover ? 4 : 0 }
sg.stage(title: 'Vanishing Circles', show: true) { scene(fill: black, width: 800, height: 600) { 50.times { circle(centerX: rand(800), centerY: rand(600), radius: 150, stroke: white, strokeWidth: bind('hover', converter: hc)) { fill rgb(rand(255), rand(255), rand(255), 0.2) effect boxBlur(width: 10, height: 10, iterations: 3)
} } }}
Criacao de sequencias via loop
Propriedades em 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. } }
26
Propriedades em GroovyFX
public class Person { @FXBindable String firstName; @FXBindable String lastName;}
27
public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”;}
Propriedades em GroovyFX
28
Inicializadores opcionais
public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”;}
def p = new Person()def last = p.lastNamep.firstName = “Agent”
Propriedades em GroovyFX
29
Valores get and set
public class Person { @FXBindable String firstName; @FXBindable String lastName = “Smith”;}
def p = new Person()def last = p.lastNamep.firstName = “Agent”
textField(text: bind(p.lastNameProperty()))
Propriedades em GroovyFX
30
Acesso a propriedades embutidas para binding
Binding em GroovyFX
@FXBindableclass 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
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
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()
Animation em GroovyFX
33
Sintaxe facil para animacoes: at (duration) {keyframes}
timeline(cycleCount: Timeline.INDEFINITE, autoReverse: true) {
at (1000.ms) { change(rect1, 'x') to 200 change rect2.yProperty() to 200 }}.play()
Animation em GroovyFX
34
Key frame DSL
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()
Animation em GroovyFX
35
Controle de velocidade opcional
Event Listeners em GroovyFX
36
> Sintaxe para Closure usando controles embutidos> Argumentos opcionais para eventos
onMouseClicked { e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 }
}.play()}
Event Listeners em GroovyFX
> Sintaxe para Closure usando controles embutidos> Argumentos opcionais para eventos
37
onMouseClicked { MouseEvent e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 }
}.play()}
Sintaxe compacta{body}
Event Listeners em GroovyFX
> Sintaxe para Closure usando controles embutidos> Argumentos opcionais para eventos
38
Parametros opcionais para eventos
{event -> body}
onMouseClicked { MouseEvent e -> timeline { at(3.s) { change e.source.radiusProperty() to 0 }
}.play()}
TableView em Java
39
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);
TableView em GroovyFX
40
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) })}
Layout em Java
41
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);
Layout em GroovyFX
42
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") } }}
Layout em GroovyFX
43
Layout em GroovyFX
44
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")}
Layout em GroovyFX
45
GroovyFX Suporta…
46
GroovyFX Suporta…
47
48
JavaFX Com Scala
49
O Que e Scala
> Comecou em 2001 by Martin Odersky> Compila para bytecodes Java> Linguagem puramente orientada a objetos> Tambem para programacao declarativa
2001• Scala Comecou
2003/2004• Scala v1.0
2006• Scala v2.0
2011• Scala 2.9.0 (ultima)
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
Java vs. Scala DSLpublic class HelloStage extends Application {
public void start(Stage stage) { stage.setTitle("Hello Stage"); stage.setWidth(600); stage.setHeight(450); Scene scene = new Scene(); scene.setFill(Color.LIGHTGREEN); Rectangle rect = new Rectangle(); rect.setX(25); rect.setY(40); rect.setWidth(100); rect.setHeight(50); rect.setFill(Color.RED); scene.setRoot(new Group(rect)); stage.setScene(scene); stage.show(); }
public static void main(String[] args) { launch(HelloStage.class, args); }}
object HelloJavaFX extends JFXApp { stage = new Stage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = LIGHTGREEN content = Seq(new Rectangle { x = 25 y = 40 width = 100 height = 50 fill = RED }) } }}
51
21 Linhas430 Caracteres
17 Linhas177 Caracteres
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 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) } } }}
Classe base para aplicacoes JavaFX
54
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) } } }}
Definicao declarativa do Stage
55
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) } } }}
Definicoes de propriedades embutidas
56
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) } } }}
Criacao de sequencias via Loop
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
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
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();
Animation em Scala
59
Animacoes JavaFX Script-like 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();
Animation in Scala
60
overloading de operadores para sintaxe da animacao
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();
Animation in Scala
61
Controle de velocidade opcional
Event Listeners em Scala
62
> Suportado usando sintaxe Closure embutida> Argumentos opcionais para tratamento de eventos> 100% tipagem forte
onMouseClicked = { Timeline(at(3 s){radius->0}).play()}
Event Listeners em Scala
> Suportado usando sintaxe Closure embutida> Argumentos opcionais para tratamento de eventos> 100% tipagem forte
63
Sintaxe compacta{body}
onMouseClicked = { Timeline(at(3 s){radius->0}).play()}
Event Listeners em Scala
> Suportado usando sintaxe Closure embutida> Argumentos opcionais para tratamento de eventos> 100% tipagem forte
64
Evento = parametro opcional {(event) => body}
onMouseClicked = { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play()}
Sobre o projeto Visage
65
> 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/
> “Visage e uma domain specific language (DSL) projetada para suportar a funcao de construcao de interfaces.”
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
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
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
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
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
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
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