02 noviembre 2005

Poner imagen de fondo en una ventana

He estado haciendo unos experimentos para ver si consigo poner una imagen de fondo en una ventana. No sé si he llegado a la mejor solución, pero aquí hay una.

Lo primero es hacer una clase que herede de Container y redefina el método paint(Graphics g) de esta manera

class Contenedor extends Container
{
// La imagen que queremos de fondo, un fichero .gif
public ImageIcon icono = new ImageIcon ("./imagen.gif");

// Redefinición del método paint()
public void paint (Graphics g)
{
// Borramos todo y lo pintamos del color de fondo por defecto.
Rectangle r = g.getClipBounds();
g.setColor(this.getBackground());
g.fillRect (r.x, r.y, r.width, r.height);

// Pintamos la imagen
g.drawImage (icono.getImage(), 0,0,this);

// Hacemos que se pinten los botones dentro de este contenedor
super.paint(g);
}
}

Luego basta con instanciar un JFrame o JDialog y meterle este contenedor

JFrame ventana = new JFrame();
ventana.setContentPane(new Contenedor());

Con esto vale. Como pega es que la imagen no se repite si la ventana es más grande que la imagen. Esta sólo sale una vez.

Los componentes que se pinten en la ventana, (JButton y demás, salvo el JLabel), tienen su propio color de fondo y machacan la imagen. Si no se quiere así, habría que ir llamando a los método setOpaque(true) de los compoentes.

Unas variantes para esto pueden ser las siguientes:
  • En drawImage() podemos hacer que la imagen coja el tamaño del contenedor. Para ello hay que poner unos parámetros más e incluso el color de fondo: g.drawImage (icono.getImage(), 0, 0, this.getWidth(), this.getHeight(), this.getBackground(), this);
  • Si no damos tamaño a la imagen, pero sí ponemos el color de fondo, nos ahorramos borrar antes el contenedor. La pega es que si el contenedor es más grande que la imagen, todo ese sobrante no se borra.

6 comentarios:

kcer dijo...

No me funciono, no tengo claro la ultima parte, hice la clase contenedor aparte y la clase de la ventana aparte luego escribi el code de la clase contenedor pero no se como llamar la clase desde el frame o q como le hago...

Anónimo dijo...

Me sirve, pero tengo un problema, la imagen de fondo se sobrepone sobre los demas componentes. ¿Que se puede hacer para solucionar eso?

chuidiang dijo...

Hola:

En el método paint() se dibuja la imagen y se llama a super.paint(), que es el que dibuja los componentes. Según el orden en el que los llames (paint() antes o después de dibujar la imagen), saldrán los componentes encima o debajo de la imagen.

Se bueno.

Anónimo dijo...

Tengo como fondo de la aplicación una pagina html; la idea es que muestre una pagina en la web o si no existe la pagina o no hay conección muestra una pagina local.
Hasta ahora todo bien el problema es que cuando abro un panel y lo minimizo esta desaparece, como puedo hacer que aparezca al frente? Como mantengo el JEditorPane (aqui muestro la pagina HTML) siempre al fondo? Gracias
Joaquin (jscabuzzo@gmail.com)

kcer dijo...

lo mejor es poner un jlabel y dentro asignar de backgroung la ruta de la imagen

kriizz wood dijo...

hola!!!
Esto es lo que yo hice...
El primer código lo agrege aparte en una clase llamada Contenedor... Klaro esto tenia que estar en donde tengo el código de la ventana la cual quiero que aparezca el fondo.
Después....
La segunda parte la puse en la Forma de la Ventana debajo del main
pero no me sale la imagen de Fondo...

Alguien puede decirme en donde se agrega la 2da parte o si esta bien lo que hice!!!

Salu2 y de antemano Gracias!!!