You are on page 1of 16

Capitulo 5 java fx 8 scene

En este capítulo, aprenderá:

 Qué escena y qué gráfico de escena hay en una aplicación JavaFX .


 Acerca de los diferentes modos de representación de un gráfico de escena .
 Cómo establecer el cursor para una escena .
 Cómo determinar el propietario del foco en una escena .
 Cómo usar el Clases de Platform y HostServices .

¿Qué es una escena?


Una escena representa el contenido visual de un escenario. La clase Scene en el
paquete javafx.scene representa una escena en un programa JavaFX. Un objeto de
Escena se adjunta, como máximo, una etapa a la vez. Si una escena ya adjunta se
adjunta a otra etapa, primero se separa de la etapa anterior. Una etapa puede tener,
como máximo, una escena asociada a ella en cualquier momento.

Una escena contiene un gráfico de escena que consiste en nodos visuales. En este
sentido, una escena actúa como un contenedor para un gráfico de escena. Un gráfico
de escena es una estructura de datos de árbol cuyos elementos se conocen como
nodos. Los nodos en un gráfico de escena forman una relación jerárquica padre-hijo.
Un nodo en un gráfico de escena es una instancia de la clase javafx.scene.Node. Un
nodo puede ser un nodo de rama o un nodo de hoja. Un nodo de rama puede tener
nodos secundarios, mientras que un nodo hoja no puede. El primer nodo en un gráfico
de escena se llama nodo raíz. El nodo raíz puede tener nodos secundarios; sin
embargo, nunca tiene un nodo padre. La Figura 5-1 muestra la disposición de los nodos
en un gráfico de escena. Los nodos de rama se muestran en rectángulos redondeados
y nodos de hoja en rectángulos.

La biblioteca de clases JavaFX proporciona muchas clases para representar nodos de


rama y hoja en un gráfico de escena. La clase Node en el paquete javafx.scene es la
superclase de todos los nodos en un gráfico de escena. La Figura 5-2 muestra un
diagrama de clases parcial para las clases que representan nodos.

Una escena siempre tiene un nodo raíz. Si el nodo raíz es redimensionable, por
ejemplo, una Región o un Control, rastrea el tamaño de la escena. Es decir, si la escena
cambia de tamaño, el nodo raíz redimensionable se redimensiona para llenar toda la
escena. En función de la política de un nodo raíz, el gráfico de escena puede
establecerse nuevamente cuando cambia el tamaño de la escena.

Un grupo es un nodo primario no reajustable que se puede configurar como nodo raíz
de una escena. Si un grupo es el nodo raíz de una escena, el contenido del gráfico de
escena queda recortado por el tamaño de la escena. Si la escena cambia de tamaño, el
gráfico de escena no se replantea.

El padre es una clase abstracta. Es la clase base para todos los nodos de la rama en un
gráfico de escena. Si desea agregar un nodo de bifurcación a un gráfico de escena, use
objetos de una de sus subclases concretas, por ejemplo, Grupo, Panel, HBox o VBox.
Las clases que son subclases de la clase Node, pero no de la clase Parent, representan
nodos hoja, por ejemplo, Rectangle, Circle, Text, Canvas o ImageView. El nodo raíz de
un gráfico de escena es un nodo de rama especial que es el nodo superior. Esta es la
razón por la que utiliza un Group o un VBox como nodo raíz al crear un objeto Scene.
Discutiré las clases que representan nodos de ramas y hojas en detalle en los Capítulos
10 y 12. La Tabla 5-1 enumera algunas de las propiedades comúnmente utilizadas de la
clase Escena.
Modos de representación gráfica
El gráfico de escena juega un papel vital al mostrar el contenido de una aplicación
JavaFX en la pantalla. Normalmente, dos tipos de API se utilizan para representar
gráficos en una pantalla:

 API de modo inmediato


 Modo retenido API

En la API de modo inmediato, la aplicación es responsable de emitir los comandos de


dibujo cuando se necesita un marco en la pantalla. Los gráficos se dibujan
directamente en la pantalla. Cuando la pantalla necesita ser repintada, la aplicación
necesita volver a emitir los comandos de dibujo a la pantalla. Java2D es un ejemplo de
API de renderizado de gráficos de modo inmediato.

En la API de modo retenido, la aplicación crea y adjunta objetos de dibujo a un gráfico.


La biblioteca de gráficos, no el código de la aplicación, conserva el gráfico en la
memoria. Los gráficos son representados en la pantalla por la biblioteca de gráficos
cuando es necesario. La aplicación es responsable solo de crear los objetos gráficos, la
parte "qué"; la biblioteca de gráficos es responsable de almacenar y representar los
gráficos, las partes "cuándo" y "cómo". La API de procesamiento de modo retenido
alivia a los desarrolladores de escribir la lógica para representar los gráficos. Por
ejemplo, agregar o eliminar parte de un gráfico de una pantalla es simple al agregar o
eliminar un objeto gráfico del gráfico usando API de alto nivel; la biblioteca de gráficos
se ocupa del resto. En comparación con el modo inmediato, el modo retenido API usa
más memoria, ya que el gráfico se almacena en la memoria. El gráfico de escena
JavaFX utiliza las API de modo retenido.

Podría pensar que el uso de la API de modo inmediato siempre sería más rápido que
usar la API de modo retenido porque la primera representa los gráficos directamente
en la pantalla. Sin embargo, el uso de la API de modo retenido abre la puerta a
optimizaciones por parte de la biblioteca de clases que no es posible en el modo
inmediato en el que cada desarrollador se encarga de escribir la lógica sobre qué y
cuándo debe representarse.

Las Figuras 5-3 y 5-4 ilustran cómo funcionan las API de modo inmediato y retenido,
respectivamente. Muestran cómo se dibujan un texto, un saludo y un hexágono en la
pantalla usando las dos API.

Configurar el cursor para una escena


Una instancia de la clase javafx.scene.Cursor representa un cursor de mouse. La clase
Cursor contiene muchas constantes, por ejemplo, HAND, CLOSED_HAND, DEFAULT,
TEXT, NONE, WAIT, para cursores de mouse estándar. El siguiente fragmento de código
establece el cursor de ESPERA para una escena:

Escena de escena;

...

scene.setCursor ( Cursor.WAIT);

También puede crear y establecer un cursor personalizado para una escena. El método
estático del cursor ( nombre de cadena) de la clase Cursor devuelve un cursor estándar
si el nombre especificado es el nombre de un cursor estándar. De lo contrario, trata el
nombre especificado como una URL para el mapa de bits del cursor. El siguiente
fragmento de código crea un cursor desde un archivo de mapa de bits llamado
mycur.png, que se supone que está en el CLASSPATH:

El dueño del foco en una escena


Solo un nodo en una escena puede ser el propietario del foco. La propiedad
focusOwner de la clase Scene rastrea la clase Node que tiene el foco. Tenga en cuenta
que la propiedad focusOwner es de solo lectura. Si desea que un nodo específico de
una escena sea el propietario del foco, debe llamar al método requestFocus ( ) de la
clase Node.

Puede usar el método getFocusOwner ( ) de la clase Scene para obtener la referencia


del nodo que tiene el foco en la escena. Una escena puede no tener un propietario de
foco, y en ese caso, el método getFocusOwner ( ) devuelve nulo. Por ejemplo, una
escena no tiene un propietario de enfoque cuando se crea, pero no se adjunta a una
ventana.

Es importante entender la distinción entre un propietario de foco y un nodo que tiene


foco. Cada escena puede tener un propietario de foco. Por ejemplo, si abre dos
ventanas, tendrá dos escenas y puede tener dos propietarios de foco. Sin embargo,
solo uno de los dos propietarios de foco puede enfocarse a la vez. El foco propietario
de la ventana activa tendrá el foco. Para verificar si el nodo propietario del foco
también tiene el foco, debe usar la propiedad enfocada de la clase Node. El siguiente
fragmento de código muestra la lógica típica al usar el propietario del foco:
Usando Clases de Constructor
JavaFX proporciona dos clases para crear y configurar objetos que constituyen los
bloques de construcción de un gráfico de escena. Una clase recibe el nombre del tipo
de objeto que la clase representa; otro con el nombre de clase anterior con el sufijo
"Builder". Por ejemplo, existen clases Rectangle y RectangleBuilder para trabajar con
rectángulos, existen clases Scene y SceneBuilder para trabajar con escenas, y así
sucesivamente.

Nota: ■ a partir de JavaFX 8, las clases de compilador se han desaprobado y no están


visibles en la documentación api. esta sección se proporciona en caso de que necesite
mantener el código JavaFX escrito en la versión anterior, como la versión 2. No utilice
las clases de compilador en JavaFX 8 o posterior. si no tiene que mirar la versión
anterior del código JavaFX, puede omitir esta sección.

Las clases de generador proporcionan tres tipos de métodos:

 Ellos tienen un create ( ) método estático para crear una instancia de la


clase de constructor.
 Contienen métodos para establecer propiedades. Los nombres de los métodos
son los mismos que los nombres de propiedad que establecen.
 Tienen un método build ( ) que devuelve el objeto de la clase para la que existe
la clase de constructor. Por ejemplo, el método build ( ) de la clase
RectangleBuilder devuelve un objeto de la clase Rectangle.

Las clases de generador están diseñadas para usar el método de encadenamiento. Sus
métodos para configurar propiedades devuelven la misma instancia de generador.
Suponiendo que p1 y p2 son propiedades de un objeto de tipo XXX, la siguiente
instrucción usa la clase de constructor para crear un objeto de tipo XXX. Establece las
propiedades p1 y p2 en v1 y v2, respectivamente:
El uso de clases de compilador requiere un código más largo; sin embargo, es más
legible en comparación con el uso de constructores para establecer las propiedades.
Otra ventaja de las clases de compilador es que pueden reutilizarse para construir
objetos con propiedades ligeramente diferentes. Supongamos que desea crear
múltiples rectángulos con un ancho de 100 píxeles y una altura de 200 píxeles, rellenos
con el color rojo. Sin embargo, tienen diferentes coordenadas xey. Puedes hacerlo con
el siguiente código:
Si utilizó el script JavaFX, que se eliminó de JavaFX versión 2.0, puede inclinarse a
utilizar clases de compilador para compilar escenas. Si ha estado utilizando Swing /
AWT, puede sentirse cómodo usando constructores y setters en su lugar. Los ejemplos
en este libro no usan clases de constructor.

void exit () Termina una aplicación JavaFX


boolean isFxApplicationThread ( ) Devuelve verdadero si el hilo de llamada
es el subproceso de aplicación JavaFX. De
lo contrario, devuelve falso.
boolean isImplicitExit () Devuelve el valor del atributo ImplicitExit
implícito de la aplicación. Si devuelve
verdadero, significa que la aplicación
terminará después de que se cierre la
última ventana. De lo contrario, debe
llamar al método exit ( ) de esta clase
para finalizar la aplicación.
boolean isSupported (función Devuelve verdadero si la característica
ConditionalFeature) condicional especificada es compatible
con la plataforma. De lo contrario,
devuelve falso.
void runLater (Runnable Ejecuta el Runnable especificado en el
ejecutable) subproceso de la aplicación JavaFX. El
tiempo de la ejecución no está
especificado. El método publica el
Runnable en una cola de eventos y lo
devuelve inmediatamente. Si se publican
Runnables múltiples utilizando este
método, se ejecutan en el orden en que
se envían a la cola.
void setImplicitExit (valor booleano) Establece el atributo implicitExit en el
valor especificado.
Comprender la clase de plataforma
La clase Platform en el paquete javafx.application es una clase de utilidad utilizada
para admitir funcionalidades relacionadas con la plataforma. Consiste en todos los
métodos estáticos, que se enumeran en la Tabla 5-2.

El método runLater ( ) se utiliza para enviar una tarea ejecutable a una cola de eventos,
por lo que se ejecuta en el subproceso de la aplicación JavaFX. JavaFX permite a los
desarrolladores ejecutar algunos de los códigos solo en el subproceso de la aplicación
JavaFX. El listado 5-2 crea una tarea en el método init ( ) que se invoca en el
subproceso iniciador JavaFX. Utiliza el método Platform.runLater ( ) para enviar la
tarea que se ejecutará en el subproceso de la aplicación JavaFX más adelante.

Consejo: utilice el método Platform.runLater ( ) para ejecutar una tarea que se crea en
un hilo que no sea el hilo de la aplicación JavaFX, pero que necesita ejecutarse en el
hilo de la aplicación JavaFX.
Algunas funciones en una implementación JavaFX son opcionales (o condicionales). Es
posible que no estén disponibles en todas las plataformas. El uso de una función
opcional en una plataforma que no admite la función no genera un error; la
característica opcional simplemente se ignora. Las características opcionales se definen
como constantes enum en la enumeración ConditionalFeature en el paquete
javafx.application, como se enumera en la Tabla 5-3.

Conocer el entorno del host


La clase HostServices en el paquete javafx.application proporciona servicios
relacionados con el entorno de inicio (escritorio, navegador web o WebStart) que aloja
la aplicación JavaFX. No puede crear una instancia de la clase HostServices
directamente. El método getHostServices ( ) de la clase Application devuelve una
instancia de la clase HostServices. El siguiente es un ejemplo de cómo obtener una
instancia de HostServices dentro de una clase que hereda de la clase Application:

HostServices host = getHostServices ( );

La clase HostServices contiene los siguientes métodos:

 Cadena getCodeBase ()
 Cadena getDocumentBase ()
 JSObject getWebContext ()
 String resolveURI (String base, String relativeURI)
 void showDocument (String uri)

El método getCodeBase ( ) devuelve el identificador de recurso uniforme (URI) de la


base de código de la aplicación. En un modo independiente, devuelve el URI del
directorio que contiene el archivo JAR utilizado para iniciar la aplicación. Si la
aplicación se inicia utilizando un archivo de clase, devuelve una cadena vacía. Si la
aplicación se inicia utilizando un archivo JNLP, devuelve el valor para el parámetro de
base de código especificado en el archivo JNLP.
El método getDocumentBase ( ) devuelve el URI de la base del documento. En un
entorno web, devuelve el URI de la página web que contiene la aplicación. Si la
aplicación se inicia con WebStart, devuelve el parámetro de base de código
especificado en el archivo JNLP. Devuelve el URI del directorio actual para la aplicación
iniciada en modo independiente.

El método getWebContext ( ) devuelve un JSObject que permite que una aplicación


JavaFX interactúe con los objetos JavaScript en un navegador web. Si la aplicación no
se está ejecutando en una página web, devuelve null. Puede usar el método eval ( ) del
JSObject para evaluar una expresión de JavaScript desde su código JavaFX. El siguiente
fragmento de código muestra un cuadro de alerta utilizando la función window.alert (
). Si la aplicación se ejecuta en un entorno no web, muestra una etapa modal JavaFX
en su lugar:

El método resolveURI ( ) resuelve el URI relativo especificado con respecto al URI base
especificado y devuelve el URI resuelto.

El método showDocument ( ) abre el URI especificado en una nueva ventana del


navegador. Según la preferencia del navegador, puede abrir el URI en una nueva
pestaña. Este método se puede usar tanto en modo autónomo como en un entorno
web. El siguiente fragmento de código abre el Yahoo! página de inicio:

getHostServices () .showDocument ("http://www.yahoo.com");

El programa en el listado 5-3 usa todos los métodos de la clase HostServices. Muestra
un escenario con dos botones y detalles de host. Un botón abre el Yahoo! página de
inicio y otra muestra un cuadro de alerta. La salida que se muestra en el escenario
variará según cómo se inicie la aplicación.
Resumen
Una escena representa el contenido visual de un escenario. La clase Scene en el
paquete javafx.scene representa una escena en un programa JavaFX. Un objeto de
Escena se adjunta a más de una etapa a la vez. Si una escena ya adjunta se adjunta a
otra etapa, primero se separa de la etapa anterior. Una etapa puede tener como
máximo una escena asociada a ella en cualquier momento.

Una escena contiene un gráfico de escena que consiste en nodos visuales. En este
sentido, una escena actúa como un contenedor para un gráfico de escena. Un gráfico
de escena es una estructura de datos de árbol cuyos elementos se conocen como
nodos. Los nodos en un gráfico de escena forman una relación jerárquica padre-hijo.
Un nodo en un gráfico de escena es una instancia de la clase javafx.scene.Node. Un
nodo puede ser un nodo de rama o un nodo de hoja. Un nodo de rama puede tener
nodos secundarios, mientras que un nodo hoja no puede. El primer nodo en un gráfico
de escena se llama nodo raíz. El nodo raíz puede tener nodos secundarios; sin
embargo, nunca tiene un nodo padre.

Una instancia de la clase javafx.scene.Cursor representa un cursor de mouse. La clase


Cursor contiene muchas constantes, por ejemplo, HAND, CLOSED_HAND, DEFAULT,
TEXT, NONE, WAIT, para cursores de mouse estándar. Puede establecer un cursor para
la escena usando el método setCursor ( ) de la clase Scene.

Solo un nodo en una escena puede ser el propietario del foco. La propiedad
focusOwner de solo lectura de la clase Scene rastrea el nodo que tiene el foco. Si desea
que un nodo específico de una escena sea el propietario del foco, debe llamar al
método requestFocus ( ) de la clase Node. Cada escena puede tener un propietario de
foco. Por ejemplo, si abre dos ventanas, tendrá dos escenas y puede tener dos
propietarios de foco. Sin embargo, solo uno de los dos propietarios de foco puede
enfocarse a la vez. El foco propietario de la ventana activa tendrá el foco. Para verificar
si el nodo propietario del foco también tiene el foco, debe usar la propiedad enfocada
de la clase Node.

La clase Platform en el paquete javafx.application es una clase de utilidad utilizada


para admitir funcionalidades relacionadas con la plataforma. Contiene métodos para
terminar la aplicación, verificando si el código que se está ejecutando se ejecuta en el
subproceso de la aplicación JavaFX, y así sucesivamente.

La clase HostServices en el paquete javafx.application proporciona servicios


relacionados con el entorno de inicio (escritorio, navegador web o WebStart) que aloja
la aplicación JavaFX. No puede crear una instancia de la clase HostServices
directamente. El método getHostServices ( ) de la clase Application devuelve una
instancia de la clase HostServices. El próximo capítulo discutirá los nodos en detalle.

You might also like