Javafx Avancado

Post on 23-Jun-2015

1.439 views 6 download

Transcript of Javafx Avancado

JavaFX ScriptClasses, binding e outros elementos

Fábio Nogueira de LucenaInstituto de Informática (UFG)Graduação em Engenharia de Softwarehttp://engenhariadesoftware.inf.br

Visão geral de recursos “avançados”

Classe

class Aluno { var nome : String; var nota : Number; public override function toString() : String { “Aluno {nome} ({nota})”; }} println(Aluno { nome: “Fulano” nota: 3 }); println(new Aluno().nota);

Sobrescrever para 1 objeto

class Aluno { var nome : String; var nota : Number;}

var a = Aluno { nome: “Fulano” nota: 3 public override function toString() : String { "Aluno {nome} ({nota})"; }}; println(new Aluno); println(a);

Binding:permite associar variável ao valor de uma expressão

Binding

var a = 1;

var b = bind a; // Expressão é ‘a’println(“{a} {b}”); // 1 1a = 2;println(“{a} {b}”); // 2 2

Binding expressions são automaticamentereavaliadas quando suas dependências mudam

Binding

var a = 1;

var b = bind a+1; // Expressão é ‘a+1’println(“{a} {b}”); // 1 2a = 2;println(“{a} {b}”); // 2 3

Binding expressions são automaticamentereavaliadas quando suas dependências mudam

Binding

var a = 1;var quadrado = bind a*a; println(“{a} {quadrado}”); // 1 1a = 3;println(“{a} {quadrado}”); // 3 9

Binding expressions são automaticamentereavaliadas quando suas dependências mudam

Binding

var pi = 3.1415926536;var raio = 1;var area = bind pi * raio * raio;

println("Área de círculo de raio {raio}: {area}");raio = 3;

println("Área de círculo de raio {raio}: {area}");

Lembre-se: binding expressions sãoreavaliadas quando suas dependências mudam

O que está acontecendo?

O runtime de JavaFX “sabe” que o valor dea deve ser atualizado sempre que o valor

da expressão pi * raio * raio for alterado, ou seja,sempre que pi ou o valor de raio for alterado. Quando

isto ocorre, o runtime reavalia a expressão e o resultado é depositado na variável a!

var a = bind pi * raio * raio;

Mais um exemplo...

var x = 1;def dobro = bind 2 * x;def msg = bind "O dobro de {x} é {dobro}";println(msg);x = 2;println(msg);

Lembre-se: binding expressions sãoreavaliadas quando suas dependências mudam

Binding (if)var pi = 3.1415926536;var r = 1;var area = bind if (r <= 0) then 0 else pi*r*r;

println("Área de círculo de raio {r}: {area}");r = -3;

println("Área de círculo de raio {r}: {area}");

O binding depende, neste exemplo, da condição, do corpo do then e do else, ou seja, das variáveis r e pi

Binding (if)

var pi = 3.1415926536;var r = 1;

var area = bind if (r <= 0) then“inválido”else“{pi*r*r}”;println("Área de círculo de raio {r}: {area}");r = -3;

println("Área de círculo de raio {r}: {area}");

O binding depende, neste exemplo, da condição, do corpo do then e do else, ou seja, nas variáveis r e pi

Binding (for)

var fim = 1;def s = bind for (x in [1..fim]) x*x+10;println(s); // [ 11 ]fim = 2;println(s); // [ 11 14 ]

O binding depende apenas da variável fim

Binding (for)var fim = 1;var passo = 1;var y = 3;var seq = bind [1..fim step passo];def s = bind for (x in seq where x<y) x;println(s); // [ 1 ]fim = 2;println(s); // [ 1 2 ]passo = 2;println(s); // [ 1 ]y = -1;println(s); // [ ]

seq depende de fim e de passos depende de seq e y

Binding (block)var x = 1;var y = 2;var z = bind { def aux = x + y; 2 * aux;};println(z); // 6y = 1;println(z); // 4x = 0;println(z); // 2

z depende de aux, que depende de x e yOU SEJA, z depende de x e y

Binding (function)Pode existir binding para uma função

A função pode ser non-bound ou bound

DEPENDÊNCIABinding para non-bound function: argumentos

Binding para bound function: bloco

Binding (non-bound function)var k : Integer = 2;function fazAlgo(x : Integer, y : Integer) { k * x + y;}var x = 1;var y = 2;var resultado = bind fazAlgo(x,y);

println(resultado); // 4y = 1;println(resultado); // 3k = 0;println(resultado); // 3

O binding de resultado depende de x e yQuando x ou y mudar, fazAlgo é executada e o valor

obtido é depositado em resultado

Binding (bound function)var k : Integer = 2;bound function fazAlgo(x : Integer, y : Integer) { k * x + y;}var x = 1;var y = 2;var resultado = bind fazAlgo(x,y);

println(resultado); // 4y = 1;println(resultado); // 3k = 0;println(resultado); // 1

O binding de resultado depende de k*x+yQuando x ou y ou k mudar, fazAlgo é executada e o

valor obtido depositado em resultado

Binding (object literal)Variável com binding para object literal depende da união das dependências de todas as expressões do lado direito

das variáveis de instância.

Não inclui dependências de variáveis de instâncias para as quais há binding.

Quando ocorre mudança, cria-se uma nova instância!

Binding (object literal)class Aluno { var nome: String;}

var varNome = "a";

var a = bind Aluno { nome: varNome };

println("{a.hashCode()}: {a.nome}"); // hashX: aa.nome = "A";println("{a.hashCode()}: {a.nome}"); // hashX: AvarNome = "b";println("{a.hashCode()}: {a.nome}"); // hashY: b

O binding de a depende de varNomeQuando varNome mudar, uma nova instância é

criada e passa a ser referenciada por a

Binding (object literal)class Aluno { var nome: String;}

var varNome = "a";

var a = bind Aluno { nome: bind varNome };

println("{a.hashCode()}: {a.nome}"); // hashX: avarNome = "b";println("{a.hashCode()}: {a.nome}"); // hashX: b

O binding de a não depende de varNomeQuando varNome mudar, apenas o valor de

a.nome é alterado.

Binding bidirecional

Binding bidirecional acrescentewith inverse

ao final da expressão envolvendo o binding

Binding bidirecional

var x = 10;var y = bind x with inverse;println("x: {x} y: {y}");x = 2;println("x: {x} y: {y}");y = 5;println("x: {x} y: {y}");

O binding de y depende de a e vice-versaQuando a mudar y também mudaQuanto y mudar a também muda

Variável (function)var operacao : function(:Byte, :Byte) : Byte;var add = function(x:Byte, y:Byte) { x + y };var sub = function(x:Byte, y:Byte) { x - y };var pro = function(x:Byte, y:Byte) { x * y };var div = function(x:Byte, y:Byte) { x / y };

var ops = [ add, sub, pro, div ];

for (op in ops) { println(op(10,2));}

Qual o resultado?

Variável (function)

var f : function(:Boolean):function(x:Byte,y:Byte):Byte;var add = function(x:Byte,y:Byte) { x + y };var sub = function(x:Byte,y:Byte) { x - y };

f = function(flag : Boolean) { if (flag) add else sub};

println(f(true)(1,2));println(f(false)(1,2));

Qual o resultado?

Variável (function)

var add = function(x:Byte,y:Byte) { x + y };var sub = function(x:Byte,y:Byte) { x - y };

var f = function(flag : Boolean) { if (flag) add else sub};

println(f(true)(1,2));println(f(false)(1,2));

Inferência de tipos tornou desnecessárioindicar o tipo da variável f, ao contrário do

exemplo anterior (tipo explicitado)

Triggers

var x = 10 on replace antigo { println("x mudou de {antigo} para {x}");};

x = 11;x = 30;

Considerações finais

Nem tudo de JavaFX foi abordado

Tratamento de exceções

Classes (herança múltipla, init, postinit, ...)

Organização do código em packages, classes,...

Modificadores de acesso: public-init, public-read, ...

Visão geral é suficiente para “aprofundar”