Anda di halaman 1dari 18

Como realizar una Ventana de Splash

Fecha de creación: 3.10.2003

Revisión 1.0 (3.10.2003)

Sergio Alonso Burgos (Zerjillo) (zerjiopropaganda ARROBA hotmail PUNTO com)

http://www.javaHispano.org

Copyright (c) 2003, Sergio Alonso Burgos. Este documento puede ser distribuido solo bajo los
términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última
versión se encuentra en http://www.javahispano.org/licencias/).
Como realizar una Ventana de Splash

Como realizar una Ventana de Splash


En este pequeño artículo se describe como crear una ventana de Splash
vistosa, con efectos de transparencias, una barra de progreso, texto de
progreso, por citar algunas de sus cualidades, utilizando para ello la clase
com.zerjio.windows.SplashWindow programada el autor. Asimismo se dará una
descripción de dicho código para que pueda servir de inspiración a otros
programadores, y por último se tratarán algunos pequeños temas para
optimizar la carga de aplicaciones Java grandes.
El código fuente está escrito en inglés para que pueda ser utilizado con
comodidad por un número mayor de personas, sin embargo en este artículo
está escrito en español (y las descripciones del código también) para facilitar la
tarea a los programadores de Java hispanohablantes.

¿Que es una ventana de Splash?


Una ventana de Splash es una especie de pantalla de presentación que se muestra
usualmente durante la carga de una aplicación. Sus funciones principales son dos
NOTA: Aunque puede haber otros muchos motivos por los cuales utilizar una ventana de Splash.

:
» Informar al usuario de la aplicación sobre temas como el copyright, nombre
del autor y el proceso de carga.
» Entretener al usuario mientras que el proceso de carga de la aplicación (que
en ocasiones puede tardar bastante) termina. Asimismo se evita que el usuario
crea que el proceso de carga no está llevandose a cabo correctamente o que
se haya paralzado por algún motivo.

Las ventanas de splash han sido un elemento que ha ido evolucionando con el tiempo,
pasando de ser meros cuadros de texto ASCII hasta complicadas ventanas con
animaciones multimedia. En este artículo se pretende explicar la manera de realizar una
pantalla de splash vistosa en Java, como por ejemplo, la mostrada en la Figura 1.

Página 2
Como realizar una Ventana de Splash

1. Ejemplo de Ventana de Splash

Como se puede comprobar esta ventana posee varias propiedades interesantes, quizás
la más destacable es emular una ventana transparente (cosa que con los paquetes
estandar de Java no es posible).

El código fuente, la documentación y los ejecutables.


El código fuente, así como una aplicación de prueba y la documentación de las clases
utilizadas en este artículo pueden descargarse aqui: [1] .
Dentro del fichero SplashWindow v1.0.zip encontramos los siguientes ficheros:
» com.zerjio.windows.jar: El paquete com.zerjio.windows que contiene las
clases SplashWindow y BackgroundPanel.
» ExampleSplashWindow.*: Código fuente y ejecutable de una ventana de
Splash de ejemplo.
» license.txt: Licencia GPL, a la que está sometido el software que se
presenta.
» README.txt: Información sobre como ejecutar el ejemplo.

» LoadingScreen.png: La imagen que sirve de fondo a la Ventana de Splash.

Página 3
Como realizar una Ventana de Splash

2. Imagen de fondo de la Ventana de Splash

» docs: Carpeta con la documentación (JavaDoc) del paquete


com.zerjio.windows.

» com->zerjio->windows: Carpeta con el código fuente del paquete


com.zerjio.windows.

Si simplemente quieres utilizar una Ventana de Splash necesitas el fichero


com.zerjio.windows.jar (añadido al classpath de la aplicación), que una de las clases de
tu programa contenga un código similar al de la clase ExampleSplashWindow y una imagen
que haga de fondo de la ventana (puede estar en cualquier formato soportado por Java,
incluidos PNG y GIF con transparencias).
El código ha sido desarrollado en el entorno de desarrollo NetBeans IDE 3.5.1, con la
versión de SDK 1.4.2, pero probablemente funcionará con versiones anteriores del mismo
(no lo he comprobado pero no creo usar clases muy nuevas). Por supuesto el NetBeans
IDE no tiene por que estar instalado en la máquina para que funcionen estas clases.
La idea de como conseguir una ventana de Splash con transparencias se me ocurrió
(aunque supongo que no seréel primero en haberlo hecho) observando la carga del
programa Audiograbber (por un detalle muy importante que se mencionará más adelante
en la descripción de las clases).

Descripción de los elementos de la ventana de Splash

Página 4
Como realizar una Ventana de Splash

3. Elementos de la Ventana de Splash

La ventana de Splash está formada por los elementos que se detallan a continuación:
1. Etiquetas: Como se verá más adelante es posible añadir cualquier
Component a la ventana. Estos en concreto son JLabels.

2. Barra de Progreso: Uno de los elementos opcionales de la Ventana de


Splash que nos permite mostrar de manera gráfica el proceso de carga de la
aplicación.
3. Texto de Progreso: Otro elemento opcional que nos permite mostrar un
pequeño texto donde se describe la acción que se está llevando a cabo en ese
momento de la carga.
4. Boton Cerrar: En este caso se ha añadido un Component más para permitir
"cerrar" la ventana de Splash (un JButton).

Los elementos 1 y 4 no son propios de la SplashWindow, sino que son simples


Components que se pueden introducir para extender la funcionalidad básica de la Ventana.
Sin embargo los elementos 2 y 3 si son propios de la SplashWindow, aunque pueden ser
ocultados en caso de no necesitarse.

Descripción del código de las distintas clases


En esta sección se describirá el código de las distintas clases para poder programar
una Ventana de splash con facilidad o para inspirarte para mejorar la que aqui se
presenta o utilizar ideas en otros proyectos.
Nota: el código que se presenta en esta página no está completo. Todos los
comentarios del mismo, así como otros trozos que no revisten importancia para la
explicación no se han copiado. Se recomienda obtener el código fuente completo para

Página 5
Como realizar una Ventana de Splash

poder comprenderlo en su totalidad, así como ver lso comentarios en linea del mismo.

Estructura Visual de la Ventana de Splash


La Ventana de Splash contiene en principio 5 componentes visuales básicos:

4. Estructura en capas de la ventana de Splash

1. jLayeredPane: Un panel por capas que nos permite realizar las


superposiciones de elementos visuales para crear el efecto de transparencia.
Los demás elementos son insertados siempre dentro de este panel siguiendo la
estructura mostrada en la figura adjunta.
2. backgroundPanel: Un panel de fondo encargado de capturar la pantalla y
dibujarse a si mismo con el trozo de pantalla capturado. Este panel se
encuentra en la capa por defecto (DEFAULT_LAYER) del jLayeredPane, con lo que
los demás elementos insertados estarán "por encima" de él. Usualmente las
ventanas de Java son opacas, y esta no es una excepción, pero al capturar el
trozo de pantalla que existe en el momento de creación de la ventana de
Splash y convertirlo en el fondo, al usuario le daria la impresión de que la
ventana es invisible de no haber más elementos encima. De todas maneras
este método de simular transparencia no está exento de problemas, que son
reseñados en una sección posterior.
3. imageLabel: Una etiqueta cuyo único contenido es el gráfico que deseamos
que sirva de fondo a la ventana de splash. Dado que la imagen que se
especifique puede contener transparencias (típicas de los formatos PNG y GIF)
se podrá simular el efecto de transparencias. Esta etiqueta se encuentra en la
capa de paleta (PALETTE_LAYER) del jLayeredPane, con lo que queda por
encima del backgroundPanel y por debajo de los demas elementos.
4.

Página 6
Como realizar una Ventana de Splash

progressBar: La barra de progreso que muestra de manera gráfica el


proceso de carga de la aplicación. Se encuentra en la capa modal
(MODAL_LAYER) del jLayeredPane, con lo que se encuentra por encima de la
imageLabel.
5. progressText: El texto de progreso que muestra mediante un mensaje la
etapa de carga que se está llevando a cabo. Se encuentra, junto con la
progressBar y los demás Componentes añadidos en la capa modal
(MODAL_LAYER) del jLayeredPane, con lo que se encuentra por encima de la
imageLabel.

Como se ha visto con la correcta combinación de los distintos elementos en las capas
del jLayeredPane podemos conseguir el efecto de transparencia deseado.

Descripción del Código de la clase BackgroundPanel


La clase com.zerjio.windows.BackgroundPanel es una clase de apoyo que extiende a
la javax.swing.JPanel y que se encarga de capturar una porción de la pantalla y dibujar
sobre si misma dicha porción capturada con el fin de poder simular que es transparente.
Solo tiene un constructor:

public BackgroundPanel(int x, int y, int width, int height) {


this.x = x;
this.y = y;
this.width = width;
this.height = height;
try {
robot = new Robot();
} catch(Exception e) {
e.printStackTrace();
}
capture();
}

En el que se inicializan las varibles x, y, width y height que definen el rectángulo de


pantalla que ha de capturarse. Asimismo inicializa un objeto de la clase Robot que será el
encargado de realizar las capturas. Por último se llama al método capture() para que se
realice la captura de pantalla durante el proceso de creación del panel.

public void capture() {


try {
im = robot.createScreenCapture(new Rectangle(x, y, width, height));
} catch(Exception e) {
e.printStackTrace();
}
repaint();
}

Este método simplemente captura la porción deseada de pantalla, la guarda en la


variable im y por último ordena redibujarse para que la nueva captura pase a ser el dibujo

Página 7
Como realizar una Ventana de Splash

representado en el panel.

public void paintComponent(Graphics g) {


super.paintComponent(g);
if (im != null) {
g.drawImage(im, 0, 0, null);
}
}

El método paintComponent ha sido sobreescrito para que el panel dibuje la imagen


recien capturada.

Descripción del Código de la clase SplashWindow


La clase com.zerjio.window.SplashWindow es algo más compleja que la anterior, pero
como se puede comprobar casi todos los métodos que se implementan sirven única y
exclusivamente para poder acceder a muchas de las propiedades de los objetos que
posee (la barra de progreso, el texto de progreso, añadir o borrar Componentes, etc.
Dentro de dicha clase existe un variable y una par de métodos que revisten cierta
importancia y de los que aún no se ha comentado nada:

private int delay = 0;


public int getDelay() {
return delay;
}
public void setDelay(int delay) {
this.delay = delay;
}

El delay (retraso) indica el tiempo (en milisegundos) que se paralizará el código cuando
se haga un incremento en la barra de progreso. Este retraso, que puede ser 0 es bastante
útil ya que, como se verá más adelante, el thread intentará paralizarse durante este
tiempo, permitiendo con ello que otros threads (que pueden estar cargando otras clases)
pasen a ejecutarse. Por eso su uso es muy recomendable, incluso si vale 0, ya que el
thread se intentará parar y cederá el paso a cualquier otro que esté intentando ser
ejecutado.

public SplashWindow(String image, boolean transparent) {


ImageIcon icon = new ImageIcon(getClass().getResource(image));
int iconWidth = icon.getIconWidth();
int iconHeight = icon.getIconHeight();
// Setting bounds
setSize(new Dimension(iconWidth, iconHeight));
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
setLocation((screenSize.width - iconWidth) / 2, (screenSize.height -
iconHeight) / 2);
// Creating main components.
jLayeredPane = new JLayeredPane();
// If uses transparency we need a background panel
if (transparent) {

Página 8
Como realizar una Ventana de Splash

backgroundPanel = new BackgroundPanel((int)getLocation().getX(),


(int)getLocation().getY(), (int)getSize().getWidth(),
(int)getSize().getHeight());
backgroundPanel.setPreferredSize(new java.awt.Dimension(310, 164));
backgroundPanel.setBounds(0, 0, getWidth(), getHeight());
jLayeredPane.add(backgroundPanel, JLayeredPane.DEFAULT_LAYER);
}
// Preparing the background image
imageLabel = new JLabel();
imageLabel.setIcon(icon);
imageLabel.setBounds(0, 0, iconWidth, iconHeight);
jLayeredPane.add(imageLabel, JLayeredPane.PALETTE_LAYER);
// Preparing the progress bar
progressBar = new JProgressBar();
progressBar.setOpaque(false);
progressBar.setBorderPainted(false);
progressBar.setVisible(false);
jLayeredPane.add(progressBar, JLayeredPane.MODAL_LAYER);
// Preparing the progress Text.
text = new JLabel();
text.setVisible(false);
jLayeredPane.add(text, JLayeredPane.MODAL_LAYER);
// Finishing init
getContentPane().setLayout(new java.awt.BorderLayout());
getContentPane().add(jLayeredPane, BorderLayout.CENTER);
}

El constructor aunque largo no hace más que inicializar algunos objetos Swing con los
valores que deben tener por defecto, así como cargar la imagen que debe utilizarse de
fondo (que puede contener transparencias), y cuya ruta ha sido mandada a través del
argumento image. Un detalle importante es que la Ventana de Splash tomará las
dimensiones exactas de la imagen de fondo, y dicho tamaño será el que se le ordene
capturar al backgroundPanel. Además la ventana aparecerá centrada en la pantalla.
Comentar por último con respecto al constructor que la variable que se le pasa
transparent indica si se desea que la ventana utilice el efecto de transparencia. En caso
de que la imagen que utilicemos de fondo no tenga transparencias (sea opaca
completamente) es recomendable indicar que no se quieren usar, ya que se ahorraran
algunos recursos (no se creará el objeto backgroundPanel) y aumentará la velocidad de
carga.

public Component add(Component comp) {


jLayeredPane.add(comp, JLayeredPane.MODAL_LAYER);
return comp;
}
public void remove(Component comp) {
jLayeredPane.remove(comp);
}

Estos métodos nos permiten añadir Componentes a nuestra ventana de splash. En


concreto lo más normal será incluir algunas JLabels o bien algún JButtons. Como se
puede comprobar los objetos se añaden en la capa modal (MODAL_LAYER) del
jLayeredPane, con lo que nos aseguramos que aparecen por encima de la imagen de
fondo.

Página 9
Como realizar una Ventana de Splash

public void setProgressBarMaximum(int max) {


progressBar.setMaximum(max);
}
public void setProgressBarValue(int val) {
progressBar.setValue(val);
}
public void incrementProgressBarValue(int increment) {
progressBar.setValue(progressBar.getValue() + increment);
try {
Thread.sleep(delay);
} catch(InterruptedException e) {}
}
public void setProgressBarBounds(int x, int y, int width, int height) {
progressBar.setBounds(x, y, width, height);
}
public void setProgressBarColor(Color color) {
progressBar.setForeground(color);
}
public void setProgressBarVisible(boolean vis) {
progressBar.setVisible(vis);
}
public JProgressBar getProgressBar() {
return progressBar;
}

Este conjunto de métodos permiten cambiar las propiedades más importantes de la


barra de progreso de la ventana de splash. Los más importantes son:
setProgressBarBounds() (para situarla en una posición concreta y con un tamaño
apropiado), setProgressBarMaximum() (para indicar cual será el número de "pasos" que se
llevarán a cabo en la inicialización de la aplicación) y incrementProgressBarValue() (para
hacer que la barra de progreso avance). En este último método es donde se realiza una
pausa (Thread.sleep(delay);) de delay milisegundos, lo que le da la posibilidad a los
demás threads de ejecutarse, evitando además si el valor de delay es lo suficientemente
grande que el proceso de carga sea "demasiado rápido". Por último reseñar que el
método getProgressBar() nos permite obtener la barra de progreso en sí por si queremos
cambiar alguna propiedad especial sobre ella que no esté disponible a través de la clase
SplashWindow .

public void setProgressTextBounds(int x, int y, int width, int height) {


text.setBounds(x, y, width, height);
}
public void setProgressTextFont(Font font) {
text.setFont(font);
}
public void setProgressTextColor(Color color) {
text.setForeground(color);
}
public void setProgressTextVisible(boolean vis) {
text.setVisible(vis);
}

Página 10
Como realizar una Ventana de Splash

public void setProgressText(String text) {


this.text.setText(text);
}
public JLabel getProgressTextLabel() {
return text;
}

Este conjunto de métodos permiten controlar el aspecto del texto de progreso que
usualmente se encuentra encima de la barra de progreso. Los métodos más importantes
son: setProgressTextBounds() (para fijar la posición y tamaño de la etiqueta) y
setProgressText() (que nos permite cambiar el texto que se visualiza). Al igual que
pasaba con la barra de progreso existe un método (getProgressTextLabel()) que nos
devuelve la etiqueta por si necesitamos cambiar alguna propiedad que no esté accesible a
través de la clase SplashWindow.

public void updateBackground() {


if (backgroundPanel != null) {
backgroundPanel.capture();
}
}

Este método es usado para actualizar el fondo de la ventana (teóricamente para cuando
el proceso de carga es verdaderamente lento). Sin embargo su uso no es evidente ya que
requiere ocultar primero la ventana, pues si no se hiciera así la captura se realizaría sobre
la misma ventana de splash y evidentemente el fondo no cambiaría. Se puede cambiar
este método para que automáticamente haga invisible la ventana de splash, capture el
fondo y por último la restaure, pero este proceso provoca un parpadeo incómodo.

public void close() {


setVisible(false);
dispose();
}

Por último el método close() oculta la ventana de splash y libera los recursos de la
misma.

Descripción del Código de la clase ExampleSplashWindow


Esta clase no pertenece al paquete com.zerjio.windows, sino que es un ejemplo simple
de una ventana de Splash que utiliza las clases comentadas anteriormente. Quien quiera
crear una ventana de Splash puede utilizar este código como base para crear la suya
propia. En principio es una clase bastante sencilla, solo tiene un método main() donde se
inicializan todos los componentes que aparecerán el la ventana de splash y donde hará
un pequeño "simulacro" de carga y un método utilizado por un botón que permite cerrar la
ventana de Splash.

// Creation of the SplashWindow, using transparency


splash = new SplashWindow("/LoadingScreen.png", true);

Página 11
Como realizar una Ventana de Splash

Como se puede observar en el código lo primero que se hace es crear el objeto de la


clase SplashWindow que utilizará la imagen "/LoadingScreen.png" de fondo, y además se
indica que dicha imagen si tiene transparencias.

// Between every increment of the progress bar there will be a delay of


ne second.
splash.setDelay(1000);

A continuación se le dice a la nueva ventana que debe realizar una pausa de un


segundo cada vez que incremente la barra de progreso (un segundo es mucho, pero dado
que nuestro ejemplo no tiene nada que cargar, si no lo hieramos así no se vería la
pantalla más que durante una fracción de tiempo minúscula).

// Setting progress bar properties.


splash.setProgressBarMaximum(10);
splash.setProgressBarValue(0);
splash.setProgressBarBounds(29, 86, 215, 4);
splash.setProgressBarColor(Color.red);
splash.setProgressBarVisible(true);

Seguimos fijando las propiedades de la barra de progreso. En concreto fijamos que


habrá un número total de 10 pasos en la carga de la aplicación, la situamos en su sitio, la
hacemos de color rojo y la ponemos visible (por defecto es invisble).

// Setting progress text properties


splash.setProgressTextBounds(31, 67, 200, 15);
splash.setProgressTextFont(new Font("SYSTEM", Font.PLAIN, 10));
splash.setProgressTextColor(Color.yellow.brighter());
splash.setProgressTextVisible(true);

El siguiente paso es fijar las propiedades del texto de progreso: Su posición, una fuente
pequeña, color amarillo y visible (por defecto también es invisible).

// Setting a title label


JLabel title = new JLabel();
title.setFont(new Font("Dialog", Font.BOLD + Font.ITALIC, 18));
title.setForeground(new Color(64, 0, 0));
title.setText("SplashWindow Example");
title.setBounds(20, 15, 220, 30);
splash.add(title);
// Setting a subtitle label
JLabel subtitle = new JLabel();
subtitle.setFont(new Font("Dialog", Font.PLAIN, 11));
subtitle.setForeground(new Color(32, 0, 0));
subtitle.setText("Version 1.0");
subtitle.setBounds(24, 32, 200, 30);
splash.add(subtitle);
// Setting a copyright notice
JLabel copyright = new JLabel();
copyright.setFont(new Font("Dialog", Font.PLAIN, 9));
copyright.setForeground(Color.lightGray);
copyright.setText("(C) 2003, Zerjillo. http://zerjio.com");
copyright.setBounds(100, 100, 200, 20);
splash.add(copyright);

Página 12
Como realizar una Ventana de Splash

En esta porción de código se crean 3 etiquetas distintas, con tamaños de letra, textos y
colores disintos y se incluyen en la ventana de splash, con lo que creamos un titulo, un
subtitulo y una nota de copyright.

JButton closeButton = new JButton();


closeButton.setFont(new java.awt.Font("Dialog", 0, 10));
closeButton.setText("X");
closeButton.setMargin(new java.awt.Insets(0, 2, 0, 2));
closeButton.setBounds(270, 12, 17, 17);
closeButton.setOpaque(false);
closeButton.setForeground(new Color(64, 0, 0));
closeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
closeActionPerformed(evt);
}
});
closeButton.setVisible(true);
splash.add(closeButton);

A continuación se añade un botón con una pequeña "X" que simula un botón de cierre
de la ventana. Para que responda cerrando la ventana se añade un nuevo
ActionListener que llama al método closeActionPerformed() que como se verá más
adelante únicamente cierra la aplicación.

// Showing splash window


splash.setVisible(true);
// Wait
try {
Thread.sleep(800);
} catch (InterruptedException e) {}

Mostramos la ventana de splash y esperamos un poco.

// Simulate we are loading somethig


for (int i = 0 ; i < 10 ; i++) {
splash.setProgressText("Loading aplication (" + (i + 1) + ")...");
splash.incrementProgressBarValue(1);
}

Simulamos la carga del programa en 10 pasos. Evidentemente este código es el que


hay que cambiar para que se lleve a cabo la carga de las distintas clases que conforman
nuestra aplicación. Como hacer esto de manera eficaz se comenta en una sección
posterior.

// wait
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
// hide
splash.close();
// bye
System.exit(0);

Página 13
Como realizar una Ventana de Splash

Por último esperamos un poco, cerramos la ventana y acabamos la aplicación. Es de


suponer que en un programa real no se finalizará ahí el código de la aplicación, sino más
bien todo lo contrario.

private static void closeActionPerformed(java.awt.event.ActionEvent evt)


{
splash.close();
}

Este es el código que se ejecuta cuando el usuario pincha en el botón de cerrar. Como
se puede comprobar el código solo ejecuta un close() de la ventana de Splash, con lo
que la aplicación seguirá cargando perfectamente, aunque sin mostrar la ventana.

Como cargar eficientemente una aplicación


Como ya se ha comentado con anterioridad una de las principales funciones de una
ventana de Splash es visualizar el proceso de carga de una aplicación. Mucha gente me
ha preguntado como podemos hacer que las distintas clases que conforman nuestra
aplicación (en especial cuando se trata de clases gráficas, que tardan bastante en cargar
por su "complejidad"), ya que se puede comprobar que después de cargar una aplicación
esta sufre retrasos al pulsar sobre ciertas opciones, ya que las clases de dichas opciones
aún no habian sido cargadas.
El ejemplo típico puede ser cuando pinchas en el menú Ayuda -> Acerca de... y la
ventana que muestra el autor y vete tu a saber que más tarda como un segundo a dos en
aparecer la primera vez. Como ya se ha dicho esto ocurre porque la/s clase/s de dicha
ventana aún no han sido cargadas. Pues bien, para evitar esto lo mejor es durante la
inicialización de la aplicación obligar a que las cargue, con lo que cuando se acceda a
ellas por primera vez no se sufrirá dicho retraso. ¿Como?. Simplemente creando un
objeto de dicha clase y despues dejando su referencia a null para que el recolector de
basura se encargue de ella posteriormente.
A continuación voy a poner un ejemplo en el que se supone que mi aplicación tiene 3
clases distintas de Ventana (Ventana1, Ventana2 y Ventana3). También supongo que las
inicializaciones de la Ventana de Splash están realizadas y que se ha supuesto que el
número de pasos para cargar la aplicación es 3 (splash.setProgressBarMaximum(3);):

...
splash.setProgressText("Cargando la ventana 1...");
Ventana1 v1 = new Ventana1(); // Se carga la clase Ventana1
v1 = null;
splash.incrementProgressBarValue(1);
splash.setProgressText("Cargando la ventana 2...");
Ventana1 v2 = new Ventana2(); // Se carga la clase Ventana2
v2 = null;
splash.incrementProgressBarValue(1);
splash.setProgressText("Cargando la ventana 3...");
Ventana1 v3 = new Ventana3(); // Se carga la clase Ventana3
v3 = null;
splash.incrementProgressBarValue(1);
...

Página 14
Como realizar una Ventana de Splash

Un aspecto que hay que tener en cuenta es que si una clase referencia directamente a
otra, hay que establecer un orden cuidadoso para que el proceso de carga resulte más
"homogeneo", ya que la máquina virtual de Java si tiene que cargar una clase y dentro del
constructor se ordena que cree un objeto de otra que aún no está cargada, como es
lógico la cargará. Por ejemplo, supongamos que tenemos 3 clases: VentanaPadre,
VentanaHijo1 y VentanaHijo2, donde la primera en su constructor crea una instacia de
cada una de las hijas. Si suponemos que cargar cada clase supone un segundo de tiempo
(¡¡¡esperemos que no!!! :-P), si utilizamos un código como el que sigue (pseudocódigo):

Cargar_VentanaPadre();
Cargar_VentanaHijo1();
Cargar_VentanaHijo2();

El proceso de carga gastará 3 segundos en la primera instrucción y prácticamente nada


en las otras dos, porque al cargar la clase padre se está obligando a cargar también las
hijas. Sin embargo un código como:

Cargar_VentanaHijo1();
Cargar_VentanaHijo2();
Cargar_VentanaPadre();

conseguirá que cada instrucción solo tarde 1 segundo (al cargar la ventana padre no las
otras dos están cargadas, con lo que no se perderá el tiempo en volverlas a cargar).
Evidentemente no solo tarda una aplicación en cargar por las clases que hay que traer
a memoria, sino por los datos que haya que leer de disco, imágenes que haya que cargar,
búsquedas de actualizaciones en internet, etc., con lo que estas acciones deben ser
combinandas con astucia durante el proceso de carga para que ésta se lleve a cabo de
formar uniforme y lo más rápidamente posible. Cada aplicación particular tiene sus
peculiaridades a la hora de la carga que deben ser solventadas por su programador.

Problemas conocidos de la Ventana de Splash


La ventana de Splash que aqui se presenta tiene algunos problemas, no de gran
importancia, pero que si es importante reseñar. Todos ellos tienen en principio que ver
con la cualidad de "transparencia". Actualmente Java no soporta ventanas con
trasparencias directamente, y el método que hemos presentado en este artículo es un
pequeño parchazo que nos permite simularlas de manera más o menos eficiente. Sin
embargo:
Problema 1: Si el proceso de carga lleva mucho tiempo es muy posible que el usuario
cambie el fondo, con lo que será evidente que la ventana no es transparente, sino que se
ha copiado el fondo y después se ha dibujado encima. Esto no es un gran problema, ya
que no impide que la ventana siga funcionando, simplemente es estéticamente poco
agradable. Sin embargo existen aplicaciones comerciales que sufren este mismo efecto,
así que no creo que sea muy problemático.

Página 15
Como realizar una Ventana de Splash

5. Porblema 1 en nuestra ventana

Página 16
Como realizar una Ventana de Splash

6. Porblema 1 en una aplicación comercial

Problema 2: La operación de captura de pantalla puede ser costosa en tiempo (y


memoria), con lo que se aconseja que las pantallas de splash tengan un tamaño
razonable, o el mismo tiempo de la captura provocará que no sea muy util tener una
ventana de Splash. Asimismo dado que dicho tiempo de captura puede ser elevado, otras
fórmulas como capturar la pantalla cada x milisegundos para solventar el problema 1 no
son factibles.

Notas finales
Espero que este artículo y el código fuente que se ofrece con él te sea de utilidad. En
caso de querer hacer alguna corrección, apunte o comentario sobre el artículo o el código
fuente, por favor, no dudes en escribirme. En caso de que utilices mis clases por favor lee
la licencia GPL que acompaña al código y asegurate que no infringues ninguno de los
puntos que se presentan. También me gustaría que si utilizas mi código me escribas
reseñando en que aplicación lo haces. Muchas gracias. Zerjillo

Recursos y referencias
[1] Código fuente, ejemplos y documentación, SplashWindow v1.0.zip

Página 17
Como realizar una Ventana de Splash

Acerca del autor


(En Octubre de 2003)Ingeniero informático, empezando los estudios de doctorado en el
campo de la representación de conocimiento y toma de decisiones con información
lingüistica y/o incompleta. Becario del Centro de Servicios de Informática y Redes de
Comunicaciones (CSIRC) de la Universidad de Granada (España). Profesor de
Informática y preparador de Enseñanza Secundaria para Adultos. Aficiones: Música,
Lectura, Amigos e Informática.

Copyright (c) 2003, Sergio Alonso Burgos. Este documento puede ser distribuido solo bajo los
términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última
versión se encuentra en http://www.javahispano.org/licencias/).

Página 18

Anda mungkin juga menyukai