Incluyendo una imagen de fondo en un JPanel

22nov08

Para que un JPanel tenga una imagen de fondo básicamente lo que hacemos es sobrescribir el método paint, dibujando la imagen del tamaño del panel, y luego sobre esta imagen el resto de los componentes.


Código:

import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
//...

public class JPanelConFondo extends JPanel {

    private Image imagen;

	//...

    @Override
    public void paint(Graphics g) {
		g.drawImage(imagen, 0, 0, getWidth(), getHeight(),
                        this);

		setOpaque(false);
        super.paint(g);
    }

	//...
}

Como podemos ver en el método paint hemos especificado tres lineas:

  • g.drawImage: dibujamos la imagen (guardada en el atributo “imagen”) en toda la extension del panel
  • setOpaque(false): le indicamos al panel que no dibuje su fondo por defecto (sino este taparía la imagen)
  • super.paint(g): le indicamos al panel que continúe dibujando el resto de los componentes
JPanel con una imagen de fondo

JPanel con una imagen de fondo

Redimensionado

Una cosa importante a la hora de dibujar la imagen es que lo hacemos desde el pixel [0,0] hasta el pixel [getWidth(), getHeight()], esto indica que cubrirá toda la extensión del panel en ese momento, permitiéndonos que la imagen acompañe una redimension del panel.

Efecto del redimencionado del panel en la imagen

Efecto del redimencionado del panel en la imagen

Algunas Variaciones

Una variación puede ser que el panel dibuje la imagen solo si está asignada a la variable “imagen”, en caso contrario (imagen == null) se dibujara el fondo por defecto:

	//...

    @Override
    public void paint(Graphics g) {
        if (imagen != null) {
            g.drawImage(imagen, 0, 0, getWidth(), getHeight(), 
                             this);

            setOpaque(false);
        } else {
            setOpaque(true);
        }

        super.paint(g);
    }

	//...

La carga de la imagen la podemos realizar en el constructor:

	//...

    public JPanelConFondo(Image imagenInicial) {
        if (imagenInicial != null) {
            imagen = imagenInicial;
        }
    }

	//...

o que la misma pueda ir variando:

	//...

    public void setImagen(Image nuevaImagen) {
        imagen = nuevaImagen;

        repaint();
    }

	//...

De este método podemos observar dos cosas:

  • repaint(): Lo llamamos explícitamente para que cuando cambiemos la imagen esta se muestre inmediatamente.
  • Si el parámetro nuevaImagen es null, veremos el fondo por defecto.
El panel no tiene imagen de fondo (imagen == null)

El panel no tiene imagen de fondo (imagen == null)

Código

Este es el código del panel completo:

package ar.lefunes.jpanelconfondo;

import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class JPanelConFondo extends JPanel {

    private Image imagen;

    public JPanelConFondo() {
    }

    public JPanelConFondo(String nombreImagen) {
        if (nombreImagen != null) {
            imagen = new ImageIcon(
                           getClass().getResource(nombreImagen)
                           ).getImage();
        }
    }

    public JPanelConFondo(Image imagenInicial) {
        if (imagenInicial != null) {
            imagen = imagenInicial;
        }
    }

    public void setImagen(String nombreImagen) {
        if (nombreImagen != null) {
            imagen = new ImageIcon(
                   getClass().getResource(nombreImagen)
                   ).getImage();
        } else {
            imagen = null;
        }

        repaint();
    }

    public void setImagen(Image nuevaImagen) {
        imagen = nuevaImagen;

        repaint();
    }

    @Override
    public void paint(Graphics g) {
        if (imagen != null) {
            g.drawImage(imagen, 0, 0, getWidth(), getHeight(),
                              this);

            setOpaque(false);
        } else {
            setOpaque(true);
        }

        super.paint(g);
    }
}

Ejemplo Descargable

Puedes descargar el ejemplo completo desde (aprox. 37,5 KB): http://lefunes.googlecode.com/files/JPanel_imagen_fondo.zip

About these ads


45 Responses to “Incluyendo una imagen de fondo en un JPanel”

  1. 1 Sergio

    Como se le hace pues me descargo el programa y cuando lo ejecuto me manda exepciones para obtener la imagen.
    Como se hace corectamante pues no me queda.

  2. @Sergio, que excepciones te salen?

    Saludos

  3. 3 luis

    lefun te ovidates decir que la imagen va en la misma carpeta que la clase
    tanpoco pusiste un metodo para poner la direcion de la imagen

  4. @luis la imagen puede ir tanto en la misma carpeta como así también dentro del .jar de la aplicación, de eso depende de como cargues la imagen.

    Por el lado del método para cargar la imagen, fijate que en la clase JPanelConFondo tenés dos constructores (así como 2 métodos setImagen) a los cuales les podes pasar o la imagen ya cargada o la ruta a la imagen como una cadena.

    En el ejemplo que dejé para descargar se puede ver mejor la forma en que esto funciona.

    Saludos y gracias por los comentarios ;)

  5. 5 Enrik

    Hola lefunes.

    Tu codigo me esta siendo de gran ayuda para una practica que estoy haciendo en la uni.
    Me podrias explicar como le tengo que poner la ruta para cargar una imagen desde fuera del proyecto? No lo consigo de ninguna manera, perdon si es una pregunta absurda pero esque estoy empezando en esto. Saludos

  6. @luis y @Enrik dejo un post de como cargar imágenes internas y externas con Java http://lefunes.wordpress.com/2009/01/29/cargando-imagenes-desde-java/

    En el ejemplo del post pueden ver como usar ambas con el JPanel visto en este post.

    Saludos

  7. Alquien sabe como hacer esto en netbeans, estoy en proyecto importante, para mi tesis, estoy trabajando con un compañero, pero quiero modificar el diseño de algunas ventanas que el hizo, el proyecto esta hecho en netbeans, el creo un complemento JFrame, no se si me doy a entender, generalmente en el paquete se le da click derecho y nueva clase, para los que an manejado netbeans saben que existe la opcion de new JFrame, bueno asi las creo el, el punto es que solo quiero ponerle fondo al panel y no alterar los componentes del frame, ya que si lo hago se modificaria la mayor parte del codigo.

    Probblemente les paresca algo trivial, pero me gusta tener una buena presentacion en mis proyectos y me gustria mucho poner una imagen de fondo.

    Si alquien sabe se lo agradecere mucho.

    PD: Ya intente casi de todo y nopo jeje.

  8. @Yuliana, para ello fijate en este post. Si descargas el ejemplo verás que la clase que generas con la opción “new JFrame” de NetBeans es algo así (viendo el código generado):

    //...
    public class NuevoJFrame extends JFrame {
    
        public NuevoJFrame() {
            initComponents();
        }
    //...
    }
    

    Pudiendo reemplazar de la clase que heredamos de la siguiente manera:

    //...
    public class NuevoJFrame extends JFrameConFondo {
    
        public NuevoJFrame() {
            initComponents();
        }
    //...
    }
    

    La otra opción directa es agregar la linea setContentPane en el constructor:

    //...
    public class NuevoJFrame extends JFrame {
    
        private final JPanelConFondo contenedor = new JPanelConFondo();
    
        public NuevoJFrame() {
            setContentPane(contenedor);
            initComponents();
        }
    //...
    }
    

    donde el contenedor es un objeto JPanel como el que vimos en este post.

    Saludos, espero que les sea de utilidad

  9. 9 Victor

    Muchas gracias por tu codigo, ha sido de gran utilidad para el proyecto que estoy realizando, de nuevo muchas gracias !!

  10. 10 Colo

    Hola a todos necesito que alguien me ayude en un pequeño problemita que estoy teniendo en un trabajo, lo que tengo que hacer es que en un JPanel se visualisen 2 figuras que me llegan, el problema es que no se visualizan las 2 al mismo tiempo, sino que la imagen que me llega de ultimo tapa las demas, si alguien me pudiera ayudar se lo agradeceria mucho. De antemano muchas gracias

  11. 11 Gildardo

    Despues de estar buscando y buscando en Internet al fin encontre como lograr insertar una imagen en un JPanel a fin de dar una mejor presentación al proyecto que estoy realizando en la Universidad.
    Mucha gracias por compartir tus conocimientos.

  12. @Colo fijate que las imágenes tengan fondo transparente, para que al pegar una encima de la otra se superpongan

  13. 13 marisol

    lefun, estuve checando el codigo y la verdad me parece que es muy imteresante…sabes tengo un problema y me gustaria que me ayudaran a resolverlo….Estoy en un rpoyecto de simulacion.y la idea es establecer una imagen de fondo y sobre ese fondo simular que una persona se transporte desde la entrada de un banco hasta la caja1…¿?eh intentado mover a la imagen de la persona pero no logro hacerlo….¿Podrias ayudarme porfavor? es urgente….te lo agradeceria muchisimo

  14. 14 Melissa

    hola! cuando descargo el codigo me funciona perfecto… pero necesito la imagen de fonde desde el principio, ps que me aparezaca desde que inicia la aplicación, mi codigo es éste:

    public class NewJFrame extends JFrame {
    private final JPanelFondo contenedor = new JPanelFondo(“tierra.jpg”);

    • 15 Melissa

      public class NewJFrame extends JFrame {

      private final JPanelFondo contenedor = new JPanelFondo(“tierra.jpg”);

      public NewJFrame() {
      initComponents();
      setContentPane(contenedor);
      }
      ..
      }

      //en JPanelFondo, solo dejé el constructor que recibe el String

      public JPanelFondo(String nombreImagen) {
      if (nombreImagen != null) {
      imagen = new ImageIcon(getClass().getResource(nombreImagen)).getImage();
      }
      }

      pero al correr la aplicación me genera un error en ésta linea de codigo, donde se crea la imagen = new ImageIcon…

      Me indica incopatibilidad…

      Les agradezco mucho si me pueden colaborar!
      Gracias :)

  15. 16 renatox

    ola
    descargue tu programa y lo abri con el netbeans y nada no me corre ninguno de los botones que has puesto, es decir no me carga niguna imagen

  16. 17 Simcos

    Saludos men, felicitaciones tenes un buen blog, muy didáctico e instructivo, perdona pero tengo una duda para un proyect de la univ hecho con el netbeans: he tratado de diversas formas que la imagen de fondo se cargue desde un principio es decir que cuando se cargue la ventana ya aparezca el jPanel con la imagen de fondo, es decir sin necesidad de presionar ningun boton, si me podes guiar en los cambios necesarios para lograrlo os agradezco mucho….. y Felicitaciones nuevamente men…..

  17. 18 Felipe

    Ola excelente tutorial me ha sido de muchísima ayuda. Una pregunta… Cuando llamas al método repaint () que hace exactamente, va al método paint?, o cuando se invoca al método paint? Por favor trata de contestarme seria de gran ayuda.

  18. 19 Edmond

    Muy bueno, gracias !
    Me sirvió

    saludos

  19. 20 anonimo

    Hola, me había surgido un problema al querer CASTEAR el panel generado por la GUI
    con el JPanelConFondo. Quería compartir la solución ya que yo estuve horas buscandolá. Hay que retocar algunas propiedades del panel de la swing agregado en la GUI. Pueden comparar la ventana de propiedades de este ejemplo con la de su proyecto y agregar lo que falte o este diferente y sale funcionando.

  20. 21 Reblujo

    lefunes, mira yo descargo el codigo lo ejecuto en netbeans 6.7 pero me salen una excepciones como las siguinentes:

    Exception in thread “AWT-EventQueue-0″ java.lang.NullPointerException
    at javax.swing.ImageIcon.(ImageIcon.java:167)
    at ar.lefunes.jpanelconfondo.JPanelConFondo.setImagen(JPanelConFondo.java:29)
    at ar.lefunes.jpanelconfondo.EjemploJPanelConFondo.btFondo1ActionPerformed(EjemploJPanelConFondo.java:90)
    at ar.lefunes.jpanelconfondo.EjemploJPanelConFondo.access$000(EjemploJPanelConFondo.java:3)
    at ar.lefunes.jpanelconfondo.EjemploJPanelConFondo$1.actionPerformed(EjemploJPanelConFondo.java:27)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6263)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:6028)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4630)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
    at java.awt.Container.dispatchEventImpl(Container.java:2085)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

  21. 22 Reblujo

    donde señala la primera excepcion esto:
    public ImageIcon (URL location) {
    this(location, location.toExternalForm());
    }

    la segunda me señala esto

    public void setImagen(String nombreImagen) {
    if (nombreImagen != null) {
    imagen = new ImageIcon(getClass().getResource(nombreImagen)).getImage();
    } else {
    imagen = null;
    }

    repaint();
    }

    y no deja cargar las imagenes segun el ejemplo que colgaste.

    Gracias por tu colaboracion

  22. 23 fortino

    Muy buen aporte solo hay que asegurarse de que la imagen este en la misma carpeta donde guardas tus clases ..Funciona perfecto.

  23. 24 Mhax

    me sale una excepcion de casteo:
    Exception in thread “AWT-EventQueue-0″ java.lang.ClassCastException: javax.swing.JPanel cannot be cast to newFolder.JPanelConFondo

    • 25 Trancos

      A mi me sale el mismo error de Casteo ¿lo solucionaste? ¿como le hiciste?

  24. 26 willian

    Pero si quisiera agregar otra imagen como haria ??? mejor dicho la 3 imagen

  25. 27 007

    No se funciona el Ejemplo en Netbeans, no muestra las imagenes, sale excepciones…

  26. 28 007

    Ya solucione las excepciones.
    Gracias por tus codigos :)

  27. 29 Juanxo

    Saludos :

    Muy buen código, pero si los botones los ponemos fuera del Panel al maximar el Frame se desconfigura todo .. habrá una solución ??

  28. Correcciones para las probables excepciones.
    1,_ Ubiquen las imagenes en el mismo paquete donde esta el jframe(EjemploJPanelConFondo ).

    2._ En el jframe, las llamadas a los metodos deben quedar asi
    ((JPanelConFondo) panelFondo).setImagen(“satelite.jpg”);
    ((JPanelConFondo) panelFondo).setImagen(“tierra.jpg”);

    3._ Por si acaso haganle un cleanandbuild a sus proyecto, clik derecho sobre el proyecto y click en cleanandbuild .

    4._ Listo, ahora que funciona bien , investiguen las otras opciones para cargar imagenes desde otros paquetes.

  29. 32 ernesto

    Esto no funciona bajoeclipse XD java lang null pointer exception

  30. 33 eduardo

    alguien pudo solucionar lo del casteo???

  31. estan bien lmalithos par de burros

  32. n o entiendo ni madres y eso que se acen llamr programadores pinches copy paste

  33. 36 jeanzxd

    Donde esta la Imagen..??

  34. Muchas gracias por el codigo, muy util en un trabajo para la universidad (y)

  35. 38 Thomas

    El código está bueno, el punto es que en ningún lugar pusiste que había que colocar un control JPanelConFondo en la paleta de controles.

    O que de alguna manera se pudiera editar la instanciación en Netbeans:

    miPaquete.JPanelConFondo miPanel = new miPaquete.JPanelConFondo();

    A mi me dio problemas con el casteo, pero despues me fije que el ‘bean class’ lo tenias asi: ar.lefunes.jpanelconfondo.JPanelConFondo

    Yo creo que te faltó explicarte mejor, acordate que no todos entendemos tu manera pensar y de hacer las cosas.

  36. 39 Javier

    Hola, excelente tutorial solo una pregunta, es posible que en un mismo jFrame se trabajen varios jPanel con elementos diferentes dentro de cada jPanel? Gracias

  37. 40 Josh

    Tengo el problema del casteo.. que hay q editar para que funcione?

    Saludos

  38. Si tengo un app (agenda) que toma los datos del contacto de una base de datos y las fotos desde una carpeta o directorio desde la raiz c:/, como hago para que este panel visualice la foto???

  39. Perdon amigo hago lo mismo que dise el programa pero Me sale ClassCastException por favor ayuda con eso

    java.lang.ClassCastException: javax.swing.JPanel cannot be cast to graficacion.img

    donde graficacion es mi package y img mi clase JPanelConFondo


  1. 1 Incluyendo una imagen de fondo en un JFrame « Le Funes
  2. 2 Aplicación MDI (JDesktopPanel) con imagen de fondo « Le Funes
  3. 3 Blog de JAVA - FinderIT » Blog Archive » Cargando imágenes desde Java

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s


Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

%d personas les gusta esto: