Java FX Script, primeros pasos - Parte 2
Antes de comenzar con esta segunda parte, quiero agradecerle a toda la gente que durante esta semana estuvo dejando comentarios y criticas sobre el curso, tanto en la sección "comentarios" del blog como aquellos que se comunicaron por email. Me alegra saber que hay tanta gente enganchada, ya que, como escribí en los comentarios, nunca pensé que esto (que pretendía ser una introducción a JFX que pasara casi desapercibida) iba a tener el nivel de respuesta que tuvo.
Para aquellos que no estuvieron siguiendo los comentarios de la parte 1, les cuento como he decidido que siga esto: primero vamos a terminar de cubrir los aspectos básicos de la versión interpretada de JavaFX Script, para luego marcar las diferencias entre esta y la nueva versión de JFXS, JavaFX Script compilado. Una vez completo esto, vamos a empezar con ejemplos más avanzados.
Sin más introducción, retomemos donde habíamos dejado en la parte 1:
Nota: al igual que en la parte 1, sólo utilizaremos el pad de JavaFX para los ejemplos de esta parte.
Expresiones
Esta parte además de aburrida es mera sintaxis, a la que van a tener que recurrir una y otra vez hasta que la memoricen, así que me voy a limitar a copiar la tabla de operadores de la referencia, y a mostrarles un par de ejemplos (aquellos que estén acostumbrados a Java noten especialmente que el operador de "⁞no igualdad" y los booleanos cambian, lo cual puede ser un dolor de cabeza en sus primeros pasos por JFXS):
| Operador | Significado | Equivalente en Java |
|---|---|---|
| Relational Operators | ||
== |
igualdad | == |
<> |
no igualdad |
!= |
< |
menor que |
< |
> |
mayor que |
> |
<= |
menor o igual que |
<= |
>= |
mayor o igual que |
>= |
| Boolean Operators | ||
and |
'y' lógico |
&& |
or |
'o' lógico |
|| |
not |
negación | ! |
| Arithmetic Operators | ||
+ |
suma | + |
- |
resta, negación unaria |
- |
* |
multiplicación | * |
/ |
división | / |
% |
resto |
% |
+= |
suma y asignación |
+= |
-= |
resta y asignación |
-= |
*= |
producto y asignación |
*= |
/= |
cociente y asignación |
/= |
%= |
resto y asignación |
%= |
| Other Operators | ||
sizeof |
tamaño de arreglo |
n/a |
indexof |
posición ordinal |
n/a |
if e1 then e2 else e3 |
expresión condicional |
e1 ? e2 : e3 |
select |
list comprehension | n/a |
foreach |
list comprehension | n/a |
new |
asignación de memoria |
new |
op() |
llamada a función u operación |
n/a |
x.op() |
llamada a método |
x.op() |
instanceof |
control de tipo |
instanceof |
this |
acceso a si mismo |
this |
. |
acceso a atributos, contextos |
., n/a |
bind [lazy] |
evaluación incremental |
n/a |
: |
inicialización "ansiosa" |
n/a |
[] |
selección en un arreglo |
[] |
format as |
formateado de strings |
n/a |
<<>> |
identificadores | n/a |
{} |
referencias en expresiones string |
n/a |
(expr) |
agrupado | (expr) |
reverse |
invierte una lista |
n/a |
[number1,next..number2] |
rango numérico |
n/a |
Ejemplos varios:
import java.lang.System;
import java.lang.Math;
var x = 2;
var y = 4;
var a = true;
var b = false;
System.out.println(x == y); // imprime false
System.out.println(x <> y); // imprime true
System.out.println(x < y); // imprime true
System.out.println(x > y); // imprime true
System.out.println(x >= y); // imprime false
System.out.println(x <= y); // imprime true
System.out.println(x + y); // imprime 6
System.out.println(x - y); // imprime -2
System.out.println(x * y); // imprime 8
System.out.println(x / y); // imprime 0.5
System.out.println(x % y); // imprime 2
System.out.println(a and b); // imprime false
System.out.println(a or b); // imprime true
System.out.println(not a); // imprime false
System.out.println(sizeof [x,y]); // imprime 2
System.out.println([x,y][indexof . == 0]); // imprime 2
System.out.println(if a then x else y); // imprime 2
System.out.println(select q from q in [x, y] where q > 3); // imprime 4
System.out.println(foreach(q in [x, y] where q < 3) q); // imprime 2
System.out.println(Math.max(x, y)); // imprime 4
System.out.println("abc".toUpperCase()); // imprime ABC
System.out.println(x instanceof Number); // imprime true
x = 10;
System.out.println(x); // imprime 10
|
Pasada la parte más pesada, volvamos a los mecanismos propios de JFXS:
Literales y expresiones con Strings
En JavaFX las cadenas de caracteres pueden ser declaradas usando comillas simples o dobles:
var s = 'Hola'; var s = "Hola"; |
Es importante destacar que dentro de estas declaraciones, pueden incluirse referencias a variables (o incluso porciones de código) encerrándolas entre llaves ('{', '}'):
var nombre = 'Pepe';
var s = "Hola {nombre}"; // s = 'Hola Pepe'
var respuesta = true;
var s = "La respuesta es {if respuesta then "Si" else "No"}";
// s = 'La respuesta es Si'
|
A diferencia de Java, en JFXS los Strings declarados con comillas dobles pueden contener saltos de línea:
var s = "Esto
tiene
varias lineas";
|
Arreglos
Una de las estructuras más utilizadas en JFXS son los arreglos, los cuales representan una secuencia de elementos que, al igual que en Java, deben ser del mismo tipo. En este lenguaje, los arreglos poseen muchas funcionalidades, lo cual da lugar a un infinito número de posibilidades al momento de trabajar con ellos. Comencemos por ver como crear una variable de este tipo:
var diasLaborales = ["Lun","Mar","Mie","Jue","Vie"]; var dias = [weekdays, ["Sab","Dom"]]; |
Cómo puede observarse en el ejemplo de arriba, los arreglos se crean utilizando corchetes y comas, y pueden crearse en base a otros arreglos. Sin embargo, es importante saber que los arreglos no son objetos en sí mismos y, además, que las expresiones que producen arreglos anidados (como la declaración de "dias" del ejemplo) son aplanadas automáticamente. Esto último implica que el valor de "dias" será en realidad '["Lun", "Mar", "Mie", "Jue", "Vie", "Sab", "Dom"]' y no '["Lun", "Mar", "Mie", "Jue", "Vie", ["Sab", "Dom"]]' (si bien la diferencia es sutil, puede llevar a errores).
Si intentamos imprimir el valor del arreglo con "System.out.println(dias)" sólo veremos el primer elemento del arreglo, para obtener todos los elementos, tendremos que usar un índice. Además, cabe destacar que en JFXS no obtendremos una excepción "ArrayIndexOutOfBoundsException" como en Java al intentar acceder a un índice fuera de rango, en lugar de eso, obtendremos un cero.
Para saber el tamaño de un arreglo, podemos usar el operador "sizeof":
var n = sizeof dias; // n = 7 |
Pueden utilizarse dos puntos seguidos '..' para crear arreglos cuyos elementos formas series aritméticas, por ejemplo:
var unoACien = [1..100]; var tamanio = sizeof unoACien; // tamanio == 100 var porTres = [1*3, 2*3 .. 10*3]; // [3,6,9,12,15,18,21,24,27,30] tamanio = sizeof porCien; // tamanio == 10 |
El Operador "[]"
En JFXS el operador "[]" se utiliza para expresar una selección utilizando predicados Xquery-Update (similares a los de XPath). Este mecanismo se basa en la utilización de una variable de contexto, con la cual el interprete se encargará de localizar aquellos valores que cumplen con la condición planteada. Es importante destacar que es el valor y no el índice a lo que estaremos haciendo referencia. Para obtener el índice, debemos utilizar el operador "indexof":
var nums = [1,2,3,4]; var numsMayoreQueDos = nums[n|n > 2]; // resulta en [3,4] var numsMenosLosDosPrimeros = nums[n|indexof n > 1]; // resulta en [3,4] |
El significado de la primera expresión es "los n, contenidos en num tal que ('|') n sea mayor a 2" mientras que el de la segunda es "los n tales que el índice de dichos n sea mayor que 1". Nota: En versiones anteriores de JFXS se aceptaba no declarar n y utilizar un punto en lugar de "n|n", por lo que es probable que lo encuentren en algún ejemplo más viejo. Bastará con intercambiar dicho punto por "n|n" para hacer que estos funcionen correctamente.
![]() |
| Error que surge al intentar usar el punto como variable de contexto |
Insertar y Borrar elementos en un arreglo
Para realizar inserciones y borrados en los arreglos, se utilizan los operadores "insert" y "delete", los cuales soportan los siguientes modificadores:
insert Expression1 [as first | as last] into Expression2: inserta la primera expresión al comienzo o al final de la segunda (la segunda debe ser un atributo o variable). insert Expression1 before Expression2: inserta la primera expresión antes de la segunda (la segunda debe ser una selección sobre un atributo o variable) insert Expression1 after Expression2: inserta la segunda expresión luego de la segunda (la segunda debe ser una selección sobre un atributo o variable) |
Para mayor claridad, veamos varios ejemplos varios de posibles usos de insert:
var x = [1,2,3]; insert 12 into x; // resulta en [1,2,3,12] insert 10 as first into x; // resulta en [10,1,2,3,12] insert [99,100] as last into x; // resulta en [10,1,2,3,12,99,100] var y = [1,2,3]; insert 10 after y[n|n == 3]; // resulta en [1,2,3,10] insert 12 before y[1]; // resulta en [1,12,2,3,10] insert 13 after y[n|n == 2]; // resulta en [1, 12, 2, 13, 3, 10]; |
El operador "delete" funciona en forma similar, nótese que en caso de no especificar una expresión se borrará todo el arreglo:
var x = [1,2,3]; insert 10 into x; // resulta en [1,2,3,10] insert 12 before x[1]; // resulta en [1,12,2,3,10] delete x[n|n == 12]; // resulta en [1,2,3,10] delete x[n|n >= 3]; // resulta en [1,2] insert 5 after x[n|n == 1]; // resulta en [1,5,2]; insert 13 as first into x; // resulta en [13, 1, 5, 2]; delete x; // borra el arreglo resulta en [] |
Queries en arreglos
Además de estas operaciones, pueden realizarse Consultas (mejor conocidas como Queries) más complejas sobre los arreglos utilizando el mecanismo llamado "List Compehensions" a través de los operadores "select" y "foreach". Algunos ejemplos a continuación:
var a:Integer* = select n*n from n in [1..10];
// resulta en [1,4,9,16,25,36,49,64,81,100]
|
Lo que estamos diciendo es algo así como: "recorré los números de 1 a 10, asignando el número de turno a la variable 'n', elevalo al cuadrado y agregalo al arreglo 'a'".
Pueden agregarse filtros utilizando el operador "where":
var a:Integer* = select n*n from n in [1..10] where (n%2 == 0);
// resulta en [4,16,36,64,100]
|
Aquí estariamos diciendo: "recorré los numeros de 1 a 10, y asigná el número de turno a la variable 'n' sólo si es par, elevalo al cuadrado y agregalo al arreglo 'a'".
Podemos realizar bucles sobre más de una variable resultando en, por ejemplo, el siguiente producto cartesiano:
var a:Integer* = select n*m from n in [1..4], m in [100,200] where (n%2 == 0);
// resulta en [200, 400, 400, 800]
|
Aquí, decimos "recorré los números de 1 a 4, asigna el número a 'n' si es par, luego por cada n recorré el arreglo que contiene 100 y 200, asigná el elemento de turno a la variable 'm' y multiplicalo por n y agregalo al arreglo 'a'".
Podríamos completarlo aún más agregando finalmente una condición sobre el segundo arreglo:
var a:Integer* = select n*m from n in [1..4], m in [100,200] where (n%2 == 0) and (m==100);
// resulta en [200, 400]
|
Utilizando el operador "foreach", se pueden obtener los mismos resultados:
var a:Integer* =
foreach(n in [1..4], m in [100,200] where (n%2 == 0) )
n*m; // resulta en [200, 400, 400, 800]
|
Formateado
Finalmente, para cerrar esta parte veremos el operador "format as" que permite (como su nombre lo indica) dar formatos especificos a ciertos valores permitiendo, por ejemplo, su homogeneidad a la hora de almacenarlos, imprimirlos, etc.
Para empezar, la sintaxis de format as es:
expresión format as directiva |
En donde la directiva indica cual es la clase que se utilizará para dar el formato. Más especificamente, si la directiva comienza con '%' se utilizará la clase java.util.Formatter, en caso contrario si la expresión es de tipo Number se utilizará java.util.DecimalFormat, sino, si la expresión es de tipo Date se utilizará java.text.SimpleDataFormat.
Algunos ejemplos:
import java.util.Date; 100.896 format as <<%f>>; // resulta en '100.896000' 31.intValue() format as <<%02X>>; // resulta en '1F' var d = new Date(); d format as <<yyyy-MM-dd'T'HH:mm:ss.SSSZ>>; // resulta en '2005-10-31T08:04:31.323-0800' 0.00123 format as <<00.###E0>>; // resulta en '12.3E-4' |
El uso de las comillas francesas ('<<' y '>>') hace que JavaFX reconozca cualquier secuencia de caracteres encerrada en estas como un identificador (incluso los espacios en blanco). Esto permite utilizar las palabras reservadas de JFXS u otros identificadores ilegales como nombres de variables, clases, atributos o funciones. Lo que es más importante, permite llamar a métodos Java que poseen nombres de palabras reservadas en JavaFX, por ejemplo:
import javax.swing.JTextArea;
var textArea = new JTextArea();
textArea.<<insert>>("Hello", 0);
|
Hasta aquí llegamos hoy. Del contenido básico sólo queda por cubrir: funciones, clases, sentencias de control y triggers (y algún que otro detalle), con lo cual es muy posible que quede completo con la próxima clase, que posiblemente esté publicando a mitad de la semana próxima. Hasta entonces, una buena practica puede ser la de comenzar a probar estos ejemplos, y modificarlos para ver toda la gama de posibilidades que provee JavaFX Script y, de paso, irse acostumbrando a la sintaxis del lenguaje.


Hola soy estudiante de Ingeniería en Sistemas de Información de UTN-San Francisco, queria decirte que tanto la parte 1, como la 2 me gustaron mucho, sobre todo por lo simple que estan hechas. Es fácil de entender y eso me agrada.
Enviado por Rocío en agosto 10, 2008 a las 12:22 PM GMT-03:00 #
Muy buen aporte, agradezco tu dedicacion en la introduccion del JavaFX.
Saludos desde Montevideo-ROU
Enviado por Fernando ROU en agosto 11, 2008 a las 10:00 AM GMT-03:00 #
Emilio:
Ezequiel muy bueno tus aportes para javaFX, yo estoy siguiendo bastante esto por que me parece que esta muy muy bueno, ahora una pregunta con respecto a los operadores, el "foreach" no se dejo de usar, por lo que he leido se cambio por el "for", o estoy confundido, si es así en que caso se aplica el foreach y en que el for??
Desde ya muchas gracias.
Enviado por emilio en agosto 16, 2008 a las 11:37 PM GMT-03:00 #
Hola gente Estoy en el segundo capitulo me interesa mas aprender a si que felicitaciones nuevamente a los que hacen posible todo esto y vamos por el tercer capitulo hasta ahora estoy bien cualquier duda que tenga les preguntare.
Enviado por yamilfg en febrero 22, 2009 a las 03:04 PM GMT-03:00 #