Ventanas de Splash Avanzadas
lunes, octubre 13, 2003 at 2:00AM Como realizar una Ventana de Splash
Y a�adirle algunos efectos especiales :-P
Fecha de creaci�n: 3.10.2003
Revisi�n 1.0 (3.10.2003)
Sergio Alonso Burgos (Zerjillo)
zerjiopropaganda ARROBA hotmail PUNTO com
|
Introducci�n
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 clasecom.zerjio.windows.SplashWindowprogramada 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(1):
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.
![]() |
| Figura 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 paquetecom.zerjio.windowsque contiene las clasesSplashWindowyBackgroundPanel.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.
Figura 2: Imagen de fondo de la Ventana de Splash docs: Carpeta con la documentaci�n (JavaDoc) del paquetecom.zerjio.windows.com->zerjio->windows: Carpeta con el c�digo fuente del paquetecom.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
![]() |
| Figura 3: Elementos de la Ventana de Splash |
La ventana de Splash est� formada por los elementos que se detallan a continuaci�n:
Etiquetas: Como se ver� m�s adelante es posible a�adir cualquier
Componenta la ventana. Estos en concreto sonJLabels.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.
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.
Boton Cerrar: En este caso se ha a�adido un
Componentm�s para permitir "cerrar" la ventana de Splash (unJButton).
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 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:
![]() |
| Figura 4: Estructura en capas de la ventana de Splash |
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.
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.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
PNGyGIF) 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.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.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 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) {
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.
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);
}
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);
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);
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);
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);
...
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.
![]() |
| Figura 5: Porblema 1 en nuestra ventana |
![]() |
| Figura 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
Notas
(1) Aunque puede haber otros muchos motivos por los cuales utilizar una ventana de Splash.
Recursos
[1]
C�digo fuente, ejemplos y documentaci�n
Acerca del autor
Sergio Alonso Burgos (Zerjillo)
(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.
j2se 





Reader Comments