APIs fluente consiste em um grupo de classes coordenadas que tem métodos que são modelados para trabalharem juntos, quando lido, descreve o que eles fazem.
A API fluente para criar bindings é incorporada na série de classes IntegerExpression. Essas classes de expressão são superclasses de ambas das classes property e binding.
Contudo, os métodos da fluente API estão disponíveis e são familiares das classes property e binding. Você pode ver isso navegando na documentação.
No geral, eles refletem o que a classe Bindings tem para oferecer. Vamos ver um exemplo utilizando a API fluente.
1 |
recipientSelected.and(amount.greaterThan(0.0)).not() |
1 |
temperature.asString(“%2.1f \u00b0C”) |
Um fato é que todos os métodos para o type-specific para as expressões numéricas são definidas na interface base NumberExpression com um retorno do tipo NumberBinding e estão subscrevendo na expressão type-specific classes com uma assinatura de parâmetros idênticos com mais um tipo de retorno específico.
Isso é chamado de covariant return-type overriding e esse recurso existe desde a versão 5 do Java. Uma das consequências desse fato é que o bindings numéricos com a API fluente tem mais tipos específicos do que fábricas de métodos na classe Bindings.
Utilizando a API fluente para achar a área do triângulo:
TriangleAreaFluentExample.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package main.java.br.com.cursojavanow; import javafx.beans.binding.Bindings; import javafx.beans.binding.NumberBinding; import javafx.beans.binding.StringExpression; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; public class TriangleAreaFluentExample { public static void main(String[] args) { IntegerProperty x1 = new SimpleIntegerProperty(0); IntegerProperty y1 = new SimpleIntegerProperty(0); IntegerProperty x2 = new SimpleIntegerProperty(0); IntegerProperty y2 = new SimpleIntegerProperty(0); IntegerProperty x3 = new SimpleIntegerProperty(0); IntegerProperty y3 = new SimpleIntegerProperty(0); final NumberBinding area = x1.multiply(y2) .add(x2.multiply(y3)) .add(x3.multiply(y1)) .subtract(x1.multiply(y3)) .subtract(x2.multiply(y1)) .subtract(x3.multiply(y2)) .divide(2.0D); StringExpression output = Bindings.format( "For A(%d,%d), B(%d,%d), C(%d,%d)," + " the area of triangle ABC is %3.1f", x1, y1, x2, y2, x3, y3, area); x1.set(0); y1.set(0); x2.set(6); y2.set(0); x3.set(4); y3.set(3); System.out.println(output.get()); x1.set(1); y1.set(0); x2.set(2); y2.set(2); x3.set(0); y3.set(1); System.out.println(output.get()); } } |
Resulta na seguinte saída:
1 |
For A(0,0), B(6,0), C(4,3), the area of triangle ABC is 9.0 |
1 |
For A(1,0), B(2,2), C(0,1), the area of triangle ABC is 1.5 |
A classe When permite você expressar if/then/else na API fluente. Você pode construir um objeto dessa classe usando qualquer construtor ou método when() na classe Bindings, passando um ObservableBooleanValue.
Sobrecarregando os métodos then() o objeto When retorna um objeto de classe uma classe construtora com condição aninhada, o qual torna a sobrecarga dos métodos otherwise() que retorna um objeto binding. Exemplo:
1 |
new When(condition).then(result).otherwise(alternative) |
condition é um ObservableBooleanValue, e result e alternative são tipos similares e pode ser observable ou non-observable. O resultado do binding é um tipo similar para o result e alternative.
No próximo exemplo, vamos calcular a área do triângulo com os lados a, b e c utilizando a fórmula de Heron.
1 |
area = sqrt(s * (s – a) * (s – b) * (s – c)) |
onde s = (a + b + c) / 2 é o semiperímetro. O triângulo é a soma de dois lados quaisquer são maiores do que o terceiro lado.
HeronsFormulaExample.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package main.java.br.com.cursojavanow; import javafx.beans.binding.DoubleBinding; import javafx.beans.binding.When; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; public class HeronsFormulaExample { public static void main(String[] args) { DoubleProperty a = new SimpleDoubleProperty(0); DoubleProperty b = new SimpleDoubleProperty(0); DoubleProperty c = new SimpleDoubleProperty(0); DoubleBinding s = a.add(b).add(c).divide(2.0d); final DoubleBinding areaSquared = new When( a.add(b).greaterThan(c) .and(b.add(c).greaterThan(a)) .and(c.add(a).greaterThan(b))) .then(s.multiply(s.subtract(a)) .multiply(s.subtract(b)) .multiply(s.subtract(c))) .otherwise(0.0D); a.set(3); b.set(4); c.set(5); System.out.printf("Given sides a = %1.0f," + " b = %1.0f, and c = %1.0f," + " the area of the triangle is" + " %3.2f\n", a.get(), b.get(), c.get(), Math.sqrt(areaSquared.get())); a.set(2); b.set(2); c.set(2); System.out.printf("Given sides a = %1.0f," + " b = %1.0f, and c = %1.0f," + " the area of the triangle is" + " %3.2f\n", a.get(), b.get(), c.get(), Math.sqrt(areaSquared.get())); } } |
A saída será assim:
1 |
Given sides a = 3, b = 4, and c = 5, the area of the triangle is 6,00 |
1 |
Given sides a = 2, b = 2, and c = 2, the area of the triangle is 1,73 |
Note-se que a API fluente tem suas limitações. À medida que o relacionamento se torna mais complicado ou vai além dos operadores disponíveis, o método de extensão direta é preferido.
HeronsFormulaDirectExtensionExample.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package main.java.br.com.cursojavanow; import javafx.beans.binding.DoubleBinding; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; public class HeronsFormulaDirectExtensionExample { public static void main(String[] args) { final DoubleProperty a = new SimpleDoubleProperty(0); final DoubleProperty b = new SimpleDoubleProperty(0); final DoubleProperty c = new SimpleDoubleProperty(0); DoubleBinding area = new DoubleBinding() { { super.bind(a, b, c); } @Override protected double computeValue() { double a0 = a.get(); double b0 = b.get(); double c0 = c.get(); if ((a0 + b0 > c0) && (b0 + c0 > a0) && (c0 + a0 > b0)) { double s = (a0 + b0 + c0) / 2.0D; return Math.sqrt(s * (s - a0) * (s - b0) * (s - c0)); } else { return 0.0D; } } }; a.set(3); b.set(4); c.set(5); System.out.printf("Given sides a = %1.0f," + " b = %1.0f, and c = %1.0f," + " the area of the triangle" + " is %3.2f\n", a.get(), b.get(), c.get(), area.get()); a.set(2); b.set(2); c.set(2); System.out.printf("Given sides a = %1.0f," + " b = %1.0f, and c = %1.0f," + " the area of the triangle" + " is %3.2f\n", a.get(), b.get(), c.get(), area.get()); } } |
Fonte: The Definitive Guide to Modern Java Clients with JavaFX
Deixe um comentário