04 agosto 2009

JavaFX Sintaxis Declarativa

En el post anterior hemos visto un ejemplo sobre cómo realizar un Hello World con JavaFX pero sin entrar en mucho detalle sobre algunas líneas del código, ahora seguiremos con algunos ejemplos más y explicando un poco sobre esto de Sintaxis Declarativa, por ejemplo un objeto puede ser creado con un Objeto Literal. Lo que significa una sintaxis declarativa concisa parecida a javascript, en lugar de explicar "como" realizar algo (el algoritmo, en los lenguajes imperativos), deberemos describir "que" es ese algo. Por ejemplo, en HTML, se declara el contenido de la página, pero no se explica cómo este será mostrado en la pantalla. Ahora veremos algunos ejemplos para aclarar esto.

Iremos desarrollando un ejemplos casi línea por línea para ir notando la simpleza del lenguaje e ir viendo algunos efectos, para este ejemplo usaremos una imagen que la pueden encontrar en el siguiente link ,comencemos.

Paso 1:


import javafx.stage.Stage;

Stage {
width: 400
height: 400
}

con las pocas líneas de arriba ya hemos definido una instancia de un objeto Stage, el cual es necesario para renderizar una ventana.

Paso 2:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 400
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
}
]
}
}

aquí hemos complicado un poco la cosa, pero veremos cada detalles, los primeros import de Scene, Image e ImageView son necesarios por los siguiente motivos.
Scene es el objeto el cual nos permite renderizar elementos gráficos dentro de el, el ImageView es el contenedor para una determinada imagen, y por último el Image es la imagen en sí. Si notamos la definición de Scene, vemos que a su propiedad content(Aquí dibujamos los elementos gráficos), hemos agregado una instancia de ImageView y a esta le hemos asignado la imagen previamente cargada en la variable image. Como podrán notar toda la sintaxis es muy simple y siempre nos preocupamos en la declaración de lo que deseamos y no en como generar todo esto.
El código hasta ahora nos generaría una ventana, con la imagen posicionada en el centro, pero nuestra Scene por defecto tiene un color blanco de fondo, si vemos en posts anteriores veremos que podíamos asignar colores en forma de gradientes, pues bueno eso haremos como siguiente paso.

Paso 3:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.Color;

/**
* @author softdesigner
*/

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 400
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
}
]
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 0.0
endY : 1.0
stops: [
Stop {
color : Color.WHITE
offset: 0.0
},
Stop {
color : Color.BLACK
offset: 1.0
}
]
}
}
}

Si vemos la propiedad fill del objeto Scene, nos damos cuenta que estamos asignando un LinearGradient a esta propiedad, como podemos deducir esto generara un Gradiente linear por medios de las propiedades startX, startY, endX, endY definimos la dirección lineal y por medio de los stops definimos que distintos Stop usar, cada Stop define necesita su propiedad color y su propiedad offset la cual indicada cuando se detendrá ese gradiente.

Muchas veces cuando estamos retocando imágenes o logrando algún efecto se nos plantea la necesidad de lograr un efecto de reflejo sobre el agua o algún material, JavaFX viene con muchas de estas dificultades resueltas ya que brinda diversos efectos para ser aplicados a nuestras imágenes, para ver esto usaremos un efecto de Reflection para lograr reflejar nuestra imagen.

Paso 4:


import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.Color;
import javafx.scene.effect.Reflection;

/**
* @author softdesigner
*/

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 600
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
effect: Reflection {
fraction: 0.75
topOffset: 0.0
topOpacity: 0.5
bottomOpacity: 0.0
}
}
]
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 0.0
endY : 1.0
stops: [
Stop {
color : Color.WHITE
offset: 0.0
},
Stop {
color : Color.BLACK
offset: 1.0
}
]
}
}
}

Ahora tenemos nuestra imagen con un efecto de Reflection, este es asignado al ImageView ya que es el contenedor de la imagen y ahora explicaremos cada propiedad de este efecto.
fraction: Es la fracción que se muestra reflejada en base a la imagen original(Valor porcentual).
topOffset: Es la distancia entre la imagen y el comienzo de su reflejo(Valor libre).
topOpacity: Es la opacidad del comienzo del reflejo(Valor porcentual).
bottomOpacity: Es la opacidad del final del reflejo(Valor porcentual).

Para ir terminando el ejemplo como último detalle, queremos mostrar dos efectos al mismo tiempo, los cuales serán una DropShadow y un efecto Reflection.

Paso 5:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.Color;
import javafx.scene.effect.Reflection;
import javafx.scene.effect.DropShadow;

/**
* @author softdesigner
*/

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 600
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
effect: Reflection {
fraction: 0.75
topOffset: 0.0
topOpacity: 0.5
bottomOpacity: 0.0
input: DropShadow {
offsetX: 10
offsetY: 10
color: Color.BLACK
radius: 10
}
}
}
]
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 0.0
endY : 1.0
stops: [
Stop {
color : Color.WHITE
offset: 0.0
},
Stop {
color : Color.BLACK
offset: 1.0
}
]
}
}
}

Si leemos acerca de la propiedad effect del ImageView descubriremos que solo acepta un objeto effect, y aquí nos entra la duda de cómo haremos mas agregar dos efectos al mismo tiempo, para esto casi todos los efectos tiene una propiedad input la cual recibe un effect, así que si nosotros quisiéramos ir encadenando efectos deberíamos hacerlo por medio de esta propiedad, en la parte superior del código se nota que el efecto Reflection recibe un input de un DropShadow, las propiedades del DrowShadow son las siguientes:
offsetX: Cantidad de pixeles sobre el eje x.
offsetY: Cantidad de pixeles sobre el eje y.
color: Color de relleno de la sombra.
radius: Radio del difuminado para la sombra.

Con esto daremos por finalizada esta mínima explicación y demostración sobre la Sintaxis declarativa que ofrece JavaFX y la simplicidad y poder de este lenguaje.
Les dejo un link al ejemplo del proyecto netbeans, luego intentare dejar el jnlp para que lo puedan descargar.

Proyecto
DeclarativeSyntax.rar



Saludos

4 comentarios:

  1. muy buena explicacion...

    ResponderEliminar
  2. Muy buenas explicaciones para empezar a cojer soltura.

    Y además en castellano :).

    Un saludo.

    ResponderEliminar
  3. Muchas gracias por los comentarios y espero poder darle mas vida al blog,pero la verdad a veces no hay tiempo

    Saludos

    ResponderEliminar
  4. Gracias por la explicación, está realmente buena =)

    ResponderEliminar