JavaFX e Scala – Como Leite com Bolacha  Stephen Chin                Rafael Afonso                              Independen...
Conheça os Apresentadores       Stephen Chin             Rafael Afonso                                           Programad...
Plataforma JavaFX 2.0Experiências de Aplicações imersivas>   Animações, Videos e Gráficos    Cross-platform>   Integra Jav...
JavaFXScala                 4
JavaFX Com Java
JavaFX em Java>   A API do JavaFX usa uma melhora do    padrão JavaBeans>   Similar a outros UI toolkits (Swing, Pivot,   ...
Vanishing Circles                    7
Esqueleto da Aplicaçãopublic class VanishingCircles extends Application {  public static void main(String[] args) {    App...
Criação dos CírculosList<Circle> circles = new ArrayList<Circle>();for (int i = 0; i < 50; i++) {  final Circle circle = n...
Configuração do Bindingcircle.strokeWidthProperty().bind(Bindings   .when(circle.hoverProperty())   .then(4)   .otherwise(...
Configuração de Event Listenerscircle.addEventHandler(MouseEvent.MOUSE_CLICKED,                        new EventHandler<Mo...
Iniciando a AnimaçãoTimeline moveCircles = new Timeline();for (Circle circle : circles) {  KeyValue moveX = new KeyValue(c...
JavaFX Com Scala              13
Java vs. Scala DSLpublic class VanishingCircles extends Application {                                   object VanishingCi...
object VanishingCircles extends JFXApp {  stage = new Stage {    title = "Disappearing Circles"    width = 800    height =...
object VanishingCircles extends JFXApp {  stage = new Stage {    title = "Disappearing Circles"    width = 800            ...
object VanishingCircles extends JFXApp {  stage = new Stage {    title = "Disappearing Circles"    width = 800    height =...
object VanishingCircles extends JFXApp {  stage = new Stage {    title = "Disappearing Circles"    width = 800            ...
object VanishingCircles extends JFXApp {  stage = new Stage {    title = "Disappearing Circles"    width = 800            ...
Binding em ScalaAdição/Subtração/Multiplicação/Divisão Infixas:height <== rect1.height + rect2.heightOperadores de Agregaç...
Animação em Scalaval timeline = new Timeline {  cycleCount = INDEFINITE  autoReverse = true  keyFrames = for (circle <- ci...
Sintaxe de animação como noAnimação em Scala                   JavaFX Script:                            at (duração) {key...
Animação em Scalaval timeline = new Timeline {  cycleCount = INDEFINITE  autoReverse = true  keyFrames = for (circle <- ci...
Animação em Scalaval timeline = new Timeline {  cycleCount = INDEFINITE  autoReverse = true  keyFrames = for (circle <- ci...
Event Listeners em Scala>   Suporte a sintaxe de Closure>   Argumentos para objetos eventos>   100% type-safe    onMouseCl...
Event Listeners em Scala                                   Parâmetro evento>   Suporte a sintaxe de Closure       opcional...
Color Selector Red ControlGreen Control                                                                Pre-defined colors ...
Color Selector>   Versões anteriores feitas em Java Swing, JavaFX 1.3,    HTML4 e HTML5.>   Objetivo é alterar os parâmetr...
SliderControl                                                Propriedade usada                 Wrapper de                 ...
Cor do Retânguloval currentColor = new ObjectProperty[Color](Color.WHITE, "Color")currentColor.onChange(rectangleRegion.se...
Sincronização de Valores                                                                                         Buffer qu...
Cores pré-definidasimport scalafx.scene.paint.Colorimport scalafx.scene.paint.Color._object WebColor {    val colors = Lis...
Exibição das cores pré-definidasobject ColorSelector extends JFXApp {  private def verifyWebColor {    cmbWebColor.value()...
Formatação das coresobject Formatter {  val formatters = List(HexFormatter, RgbFormatter, PercentFormatter, HsbFormatter)}...
Exibição da formatação das cores private def formatColor {    this.txfColorValue.text() =this.cmbColorFormat.value.get.for...
Funcionamento do ScalaFX Ou: Como escrever sua própria DSL em Scala.Com citações de Stephen Colebourne (@jodastephen) para...
Inicialização da Aplicação>   JavaFX requer que todo código de UI seja    executado na Thread da aplicação.>   Mas nossa A...
DelayedInit>    Introduzido no Scala 2.9>    Como usar:1.    Estender um trait especial chamado DelayedInit2.    Implement...
Hierarquia de Conversões implicitas>   ScalaFX define um conjunto de proxies que    espelham a hierarquia de JavaFX>   As ...
Precedência de Implicits de N Níveis>   Scala dispara uma exceção se dois implicits têm    a mesma precedência.>   Classes...
Propriedades>   JavaFX suporta propriedades do tipo Boolean,    Integer, Long, Float, Double, String, e Object>   Propried...
@specialized>   Anotação especial que gera variantes primitivas    da classe.>   Melhora a performance ao evitar boxing/un...
Bindings>    Como Scala sabe a ordem de avaliação?text <== when (rect.hover || circle.hover&& !disabled) then textField.te...
Regra de Precedência de Operadores>   Primeiro caractere determina a precedência    Menor Precedência                     ...
Precedência de Operadorestext <== when (rect.hover || circle.hover           11      10                          9&& !disa...
Conclusão>   Você pode usar Scala e JavaFX juntos.>   ScalaFX fornece APIs mais simples, feita sob    medida para Scala.> ...
Obrigado                           Stephen Chin                           steveonjava@gmail.com                           ...
Upcoming SlideShare
Loading in …5
×

JavaFX and Scala - Like Milk and Cookies - Brazil

7,667 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
7,667
On SlideShare
0
From Embeds
0
Number of Embeds
5,320
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Stage.add??
  • JavaFX and Scala - Like Milk and Cookies - Brazil

    1. 1. JavaFX e Scala – Como Leite com Bolacha Stephen Chin Rafael Afonso Independente, Magna JavaFX Evangelist, Oracle Sistemas steveonjava@gmail.com rafael.afonso@gmail.com tweet: @rucafonso tweet: @steveonjava
    2. 2. Conheça os Apresentadores Stephen Chin Rafael Afonso Programador Homem de Java desde 2001 Família Motorciclista Interessado em Scala desde 2008
    3. 3. Plataforma JavaFX 2.0Experiências de Aplicações imersivas> Animações, Videos e Gráficos Cross-platform> Integra Java, JavaScript e HTML5 na mesma aplicação> Nova pilha gráfica toma vantagem da aceleração de hardware para aplicações 2D e 3D> Use sua IDE favorita: NetBeans, Eclipse, IntelliJ, etc.
    4. 4. JavaFXScala 4
    5. 5. JavaFX Com Java
    6. 6. JavaFX em Java> A API do JavaFX usa uma melhora do padrão JavaBeans> Similar a outros UI toolkits (Swing, Pivot, etc.)> Usa o Design Pattern Builder para minimizar a parte monótona.
    7. 7. Vanishing Circles 7
    8. 8. Esqueleto da Aplicaçãopublic 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); [cria os círculos…] root.getChildren().addAll(circles); primaryStage.setScene(scene); primaryStage.show(); [inicia a animação…] }}
    9. 9. Criação dos CírculosList<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); [configura os bindings…] [configura os event listeners…] circles.add(circle);} 9
    10. 10. Configuração do Bindingcircle.strokeWidthProperty().bind(Bindings .when(circle.hoverProperty()) .then(4) .otherwise(0)); 10
    11. 11. Configuração de Event Listenerscircle.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(); }}); 11
    12. 12. Iniciando a AnimaçãoTimeline 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(); 12
    13. 13. JavaFX Com Scala 13
    14. 14. Java vs. Scala DSLpublic 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 Linhas 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 Linhas strokeWidth <== when (hover) then 4 otherwise 0 stroke = WHITE onMouseClicked = { Timeline(at (3 s) {radius -> 0}).play() 1299 Caracteres circle.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { public void handle(MouseEvent t) { KeyValue collapse = new KeyValue(circle.radiusProperty(), 0); } } } 591 Caracteres 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(); }} 14
    15. 15. 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) } } }} 15
    16. 16. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 Classe base para height = 600 scene = new Scene { ScalaFX aplicações 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) } } }} 16
    17. 17. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 height = 600 Definição Declarativa scene = new Scene { fill = BLACK do Stage 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) } } }} 17
    18. 18. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 Definições de height = 600 propriedades inline 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) } } }} 18
    19. 19. object VanishingCircles extends JFXApp { stage = new Stage { title = "Disappearing Circles" width = 800 Criação de Sequência height = 600 Via 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) } } }} 19
    20. 20. Binding em ScalaAdição/Subtração/Multiplicação/Divisão Infixas:height <== rect1.height + rect2.heightOperadores de Agregação:width <== max(rect1.width, rect2.width, rect3.width)Expressões Condicionais:strokeWidth <== when (hover) then 4 otherwise 0Expressões Compostas:text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled" 20
    21. 21. Animação em Scalaval timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width.get, circle.centerY -> random * stage.height.get ) }}timeline.play(); 21
    22. 22. Sintaxe de animação como noAnimação em Scala JavaFX Script: at (duração) {keyframes}val timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width.get, circle.centerY -> random * stage.height.get ) }}timeline.play(); 22
    23. 23. Animação em Scalaval timeline = new Timeline { cycleCount = INDEFINITE autoReverse = true keyFrames = for (circle <- circles) yield at (40 s) { Set( circle.centerX -> random * stage.width.get, circle.centerY -> random * stage.height.get ) }}timeline.play(); Sobrecarga de Operador para sintaxe de animação 23
    24. 24. Animação em Scalaval 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(); Sintaxe tween opcional 24
    25. 25. Event Listeners em Scala> Suporte a sintaxe de Closure> Argumentos para objetos eventos> 100% type-safe onMouseClicked = { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() } 25
    26. 26. Event Listeners em Scala Parâmetro evento> Suporte a sintaxe de Closure opcional: {(event) => body}> Argumentos para objetos eventos> 100% type-safe onMouseClicked = { (e: MouseEvent) => Timeline(at(3 s){radius->0}).play() } 26
    27. 27. Color Selector Red ControlGreen Control Pre-defined colors (from Color JavaFX class) Blue ControlOpacity (Alpha) Control Syncronizer Values goes from 0 to 255 Enable/Disable Opacity Colors Formatation: • Hexadecimal: #ADFF2F • RGB: rgba(173, 255, 47, 0,61) • Percent: rgba( 67%, 100%, 18%, 0,61) • HSB: hsba( 84, 82%, 100%, 0,61) 27
    28. 28. Color Selector> Versões anteriores feitas em Java Swing, JavaFX 1.3, HTML4 e HTML5.> Objetivo é alterar os parâmetros da cor do retângulo pelos componentes Vermelho (R), Verde (G), Azul (B) e Opacidade (A – Alpha), com valores variando de 0 a 255.> É possível escolher uma cor pré-definida no objeto scalafx.scene.paint.Color (que é um wrapper da classe javafx.scene.paint.Color).> Também é possível exibir o valor da cor tal como usado no HTML e ainda escolher a formatação (Hexedecimal, RGB, HSL). 28
    29. 29. SliderControl Propriedade usada Wrapper de Internamenteclass SliderControl extends HBox { javafx.beans.property.DoubleProperty val realValue = new DoubleProperty(new SimpleDoubleProperty) def value = this.realValue def value_=(d: Double) { if (d < Min) { value() = Min } else if (d > Max) { getter e setter do valor (equivalente às properties do C#). value() = Max } else { value() = d Equivalente a fazer realValue.set(d) } } val sldValue = new Slider { // ... value <==> realValue } Operador de} Duplo Binding 29
    30. 30. Cor do Retânguloval currentColor = new ObjectProperty[Color](Color.WHITE, "Color")currentColor.onChange(rectangleRegion.setStyle("-fx-background-color: " +RgbFormatter.format(currentColor(), !this.chbDisableAlpha.selected.get)))private def changeColor { val newAlphaValue = if (controlAlpha.disabled.get()) 1.0 else (controlAlpha.value.toDouble / 255) this.currentColor() = Color.rgb(controlRed.value.toInt, controlGreen.value.toInt, controlBlue.value.toInt, Se fosse em Java, teríamos que escrever: newAlphaValue) controlRed.valueProperty.addListener(} new ChangeListener<DoubleProperty>() { @Override public void changed(ObservableDouble d, Double old,val controlRed = new SliderControl("R") { Double new) { value = 255 changeColor(); }} }controlRed.value.onChange(changeColor) }); O ScalaFX já faz isso por nós usando closures. 30
    31. 31. Sincronização de Valores Buffer que reúne osval synchronizedValue = new DoubleProperty(new SimpleDoubleProperty) controle sincronizadosval synchronizedControls = new ObservableBuffer[SliderControl]synchronizedControls.onChange((buffer, changes) => synchronizedValues(buffer, changes))private def controlSelected(control: SliderControl) { // Método chamado ao clicar no Checkbox desincronização if (control.selectedControl.get) synchronizedControls.add(control) Versão ScalaFX do Super trait das else synchronizedControls.remove(control) ObservableList do JavaFX listas em Scala}// Método chamado ao adicionar/remover um elementoprivate def synchronizeValues(buffer: ObservableBuffer[SliderControl], changes: Seq[Change]) { changes(0) match { case Add(pos, added) => { val media = buffer.map(_.value.get).sum / buffer.size added.last.asInstanceOf[SliderControl].value <==> synchronizedValue Adiciona duplo binding buffer.foreach(_.value = media) } case Remove(pos, removed) => { removed.last.asInstanceOf[SliderControl].value unbind synchronizedValue Remove duplo binding } }}controlRed.selectedControl.onChange(controlSelected(controlRed)) 31
    32. 32. Cores pré-definidasimport scalafx.scene.paint.Colorimport scalafx.scene.paint.Color._object WebColor { val colors = List( WebColor("ALICEBLUE", ALICEBLUE), WebColor("ANTIQUEWHITE", ANTIQUEWHITE), WebColor("AQUA", AQUA), ... WebColor("WHITE", WHITE), WebColor("WHITESMOKE", WHITESMOKE), WebColor("YELLOW", YELLOW), WebColor("YELLOWGREEN", YELLOWGREEN))}sealed case class WebColor(name: String, color: Color) 32
    33. 33. Exibição das cores pré-definidasobject ColorSelector extends JFXApp { private def verifyWebColor { cmbWebColor.value() =WebColor.colors.find(_.sameColor(currentColor.get)).orNull } private def webColorSelected { if (this.cmbWebColor.value.get != null) { val color = this.cmbWebColor.value.get.color controlRed.value() = doubleToInt(color.red) controlGreen.value() = doubleToInt(color.green) controlBlue.value() = doubleToInt(color.blue) } } val cmbWebColor = new ComboBox[WebColor](WebColor.colors) { onAction = webColorSelected converter = StringConverter.toStringConverter((wc: WebColor) => wc.name) }} 33
    34. 34. Formatação das coresobject Formatter { val formatters = List(HexFormatter, RgbFormatter, PercentFormatter, HsbFormatter)}abstract sealed case class Formatter(val description: String) { protected def colorToRgbInt(c: Color): (Int, Int, Int) = (doubleToInt(c.red), doubleToInt(c.green), doubleToInt(c.blue)) protected def formatWithAlpha(c: Color): String protected def formatWithoutAlpha(c: Color): String def format(c: Color, hasAlpha: Boolean): String = if (hasAlpha) formatWithAlpha(c) else formatWithoutAlpha(c)}object HexFormatter extends Formatter("Hexadecimal") { val HEXADECIMAL_FORMAT = "#%02x%02x%02x"; def formatWithAlpha(c: Color): String = { val (r, g, b) = super.colorToRgbInt(c) HEXADECIMAL_FORMAT.format(r, g, b).toUpperCase } def formatWithoutAlpha(c: Color): String = formatWithAlpha(c)} 34
    35. 35. Exibição da formatação das cores private def formatColor { this.txfColorValue.text() =this.cmbColorFormat.value.get.format(this.currentColor.get, !this.chbDisableAlpha.selected.get) } val cmbColorFormat = newComboBox[Formatter](Formatter.formatters) { promptText = "Color Format" converter = StringConverter.toStringConverter((f:Formatter) => f.description) value = RgbFormatter onAction = formatColor } 35
    36. 36. Funcionamento do ScalaFX Ou: Como escrever sua própria DSL em Scala.Com citações de Stephen Colebourne (@jodastephen) para obem de nossa sanidade!Aviso: Declarações extraídas de http://blog.joda.org e podem não refletir exatamente sua opnião ou ponto de vista. 36
    37. 37. Inicialização da Aplicação> JavaFX requer que todo código de UI seja executado na Thread da aplicação.> Mas nossa Aplicação ScalaFX não possui método start:object VanishingCircles extends JFXApp { stage = new Stage { … }} Como esse código funciona?!? 37
    38. 38. DelayedInit> Introduzido no Scala 2.9> Como usar:1. Estender um trait especial chamado DelayedInit2. Implementar um método do tipo:  def delayedInit(x: => Unit): Unit3. Guardar a closure init e chamá-la no Thread da Aplicação Joda diz… Para mim, Scala não inova o suficiente e adiciona demais – uma combinação letal. 38
    39. 39. Hierarquia de Conversões implicitas> ScalaFX define um conjunto de proxies que espelham a hierarquia de JavaFX> As classes JavaFX são “implicitamente” acondicionadas (wrapped) quando se chama a API do ScalaFX> Mas a prioridade de implicit de Scala ignora a hierarquia de tipos! JFXNode SFXNode JFXShape ? SFXShape JFXCircle ! SFXCircle 39
    40. 40. Precedência de Implicits de N Níveis> Scala dispara uma exceção se dois implicits têm a mesma precedência.> Classes que são estendidas têm uma precedência menorobject HighPriorityIncludes extends LowerPriorityIncludes {…}trait LowerPriorityIncludes {…}> Você pode empilhar os traits com profundidade de n níveis para reduzir a precisão para n. Joda diz… Bem, pode ser type safe, mas é também silencioso e bem mortal. 40
    41. 41. Propriedades> JavaFX suporta propriedades do tipo Boolean, Integer, Long, Float, Double, String, e Object> Propriedades usam Genéricos para segurança de tipos.> Mas genéricos não suportam primitivos…> JavaFX soluciona isso com 20 interfaces e 44 classes para todos os tipos de combinações de tipos somente-leitura ou graváveis.> Podemos melhorar? 41
    42. 42. @specialized> Anotação especial que gera variantes primitivas da classe.> Melhora a performance ao evitar boxing/unboxing trait ObservableValue[@specialized(Int, Long, Float, Double, Boolean) T, J]> Diminui a duplicação de código (ScalaFX tem apenas 18 classes de Propriedades/Valores) Joda diz… Qualquer que seja o problema o sistema de tipos deve ser parte da solução. 42
    43. 43. Bindings> Como Scala sabe a ordem de avaliação?text <== when (rect.hover || circle.hover&& !disabled) then textField.text + " isenabled" otherwise " disabled" E por que esse operador esquisito de binding?!? 43
    44. 44. Regra de Precedência de Operadores> Primeiro caractere determina a precedência Menor Precedência Exceção são os 10. (all letters) operadores de atribuição 9. | cuja prioridade é menor 8. ^ ainda… 7. & 6. < > 11. Operadoresde atribuição 5. = ! que terminam com igual 4. : > Mas não começam com igual 3. + * > E não podem ser: 2. / %  <= 1. (todos os outros  >= caracteres especiais)  != Maior Precedência 44
    45. 45. Precedência de Operadorestext <== when (rect.hover || circle.hover 11 10 9&& !disabled) then textField.text + " is7 5 10 3enabled" otherwise "disabled" 10 Joda diz… Pessoalmente, acho que o objetivo de sintaxe aberta e flexível (DSLs arbitrárias) não compensam o esforço 45
    46. 46. Conclusão> Você pode usar Scala e JavaFX juntos.> ScalaFX fornece APIs mais simples, feita sob medida para Scala.> Experimente ScalaFX hoje e ajude a contribuir com APIs para a futura versão 1.0! http://code.google.com/p/scalafx/
    47. 47. Obrigado Stephen Chin steveonjava@gmail.com tweet: @steveonjavaDesconto especial de 40% para o JustJava.Entre em apress.com e digite o código PJVF73 47

    ×