Capas con imagen de fondo en Java

Java es un lenguaje muy potente, pero hacer interfaces es algo que puede llegar a ser tan divertido como una patada en los cojones xD. El editor de Netbeans es muy potente, pero como usa un layout propio (auque puedes usar otros, los estandar de la API de Java) luego para exportarlo y empaquetarlo todo en un jar, debo de ser muy tonto que no se hacerlo, luego tenemos Eclipse, un IDE que es el puro desorden personificado, por mucho que intento ponerme con él, pierdo más tiempo mirando donde están las cosas que trabajando, es decir, toca hacerse las GUI’s a mano.
Una de las cosas que más he hecho y más veces he perdido el tiempo, es crear una capa/ventana/cuadrado/ComoQuierasLlamarlo con una imagen de fondo. Para hacer esta trivialidad, en Java tenemos que hacer la de dios para lograrlo, lo que viene a ser usar un JPanel y sobrecargar el método de pintado en el cual pintaremos toda la superficie con una textura creada de la imagen. Vamos que es una puta mierda. Este post me lo escribo para mi mismo :P, para que otras veces venga aquí y haga copy paste y deje de tener que estar siempre mirando código viejo. Let’s go!

Demo 1 - Ventanita simple con un fondo:

    Recursos:

  • -GUI.java: la “aplicación” verdadera
  • -images.java: Clase estática para crear texturas de una imagen
  • -fondo.png: Fondo, puede ser más pequeño que la ventana y de esa forma se repetirá. Acabo de hacer una imagén de 300×10px donde la mitad superior es negra y la mitad inferior es blanca. Adivinas el efecto que surgirá?, yeah, una cebra xD.

GUI.java

import java.awt.*;
import javax.swing.*;
import java.net.URL;

public class GUI extends JFrame
{
   private static GUI ventanaPrincipal; // Ventana principal
   private JPanel panel; // Capa sobre la que se trabajará

   private final URL imgFondo =  this.getClass().getResource("fondo.png")
   private static TexturePaint fondo; // Textura con la que se pintará el fondo
   
   public static void main(String [] arg)
   {  // lanzamos aplicación
      javax.swing.SwingUtilities.invokeLater(new Runnable(){
         public void run()
         {
            lanzarAplicacion();
         }
      });
   }
   /**
    * construye los objetos requeridos para el funcionamiento de la aplicacion
    */

   private static void lanzarAplicacion()
   {
      // se crea la ventana
      ventanaPrincipal = new GUI("Demo guays");    
      // y la mostramos!
      ventanaPrincipal.setVisible(true);     
   }

   private GUI(String Titulo)
   {
      super(Titulo);

      panel = new JPanel()
      {
         private TexturePaint fondo = images.carga(imgFondo, this);
         protected void paintComponent(Graphics g)
         {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D)g;
            Dimension d = getSize();
            g2d.setPaint(fondo);
            g2d.fill(new Rectangle(0,0,d.width,d.height));
         }
      };       
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setPreferredSize(new Dimension(300, 300));
      setSize(300,300)
      getContentPane().add(panel);
   }
   
}

Images.java: Es un clase estática de la cual nos interesa el método carga(nombre_imagen, componente), el cual nos dará el tan preciado TexturePaint, la textura con la cual pintaremos felizmente. (nota: par de funciones no son mias, las saqué de un tutorial de java2d)

import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.image.*;
import java.net.URL;

public class images
{
   private static TexturePaint cargaTextura(URL imageFile, Component c)
   {
      TexturePaint imageDev;
      try
      {
         Image img = (new ImageIcon(imageFile)).getImage();
         BufferedImage image = getBufferedImage(img , c);
         imageDev =  new TexturePaint(image,
               new Rectangle(0, 0, image.getWidth(), image.getHeight()) 
         );
      }catch(Exception e){
         imageDev = null;
         System.out.println(e.getMessage())
      }
      return imageDev;
  }

   private static BufferedImage getBufferedImage(Image image, Component c)
   {
      waitForImage(image, c);
      BufferedImage bufferedImage = new BufferedImage(
         image.getWidth(c), image.getHeight(c), BufferedImage.TYPE_INT_RGB
      );
      Graphics2D g2d = bufferedImage.createGraphics();
      g2d.drawImage(image, 0, 0, c);
      return(bufferedImage);
   }

   private static boolean waitForImage(Image image, Component c)
   {
      MediaTracker tracker = new MediaTracker(c);
      tracker.addImage(image, 0);
      try{
         tracker.waitForAll();
      }catch(InterruptedException ie){}
      return(!tracker.isErrorAny());
   }
   /**
    * Crea un textura de una imagen para un componente concreto
    * @param s imagen a cargar
    * @param c componente sobre el cual pintaremos
    */

   public static TexturePaint carga(URL s, Component c)
   {
      TexturePaint image;
      image = cargaTextura(s, c);
      if (image == null)
         System.err.println("OMG! No puedo leer la imagen " + s);
      return image;
   }
}

Con esto obtenemos:

ventanajavapintada.jpg

Demo 2 - JPanelBackground: ya que estamos, hacemos un nuevo JPanel nuevo, no?

JPanelBackground

import javax.swing.JPanel;
import java.awt.*;
import java.net.URL;

public  class JPanelBackground extends JPanel
{
   private TexturePaint fondo;
   
   public JPanelBackground(URL imgFondo)
   {
      fondo = images.carga(imgFondo, this);
   }
   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D)g;
      Dimension d = getSize();
      g2d.setPaint(fondo);
      g2d.fill(new Rectangle(0,0,d.width,d.height));
   }
}

Con esto GUI.java cambiará a ser más simple y limpio, concretamente los cambios serían:

()
public class GUI extends JFrame
{
   ()
   private JPanelBackground panel; // Capa sobre la que se trabajará
   ()
   private GUI(String Titulo)
   {
      super(Titulo);

      panel = new JPanelBackground(imgFondo);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      ()
   } 
}

Todos los códigos fuentes están en este archivo ;)

Unos comentarios finales, todo esto nos permite, posteriormente, crear nuevos elementos sobre este JPanel que estarán por encima de la imagen que hemos pintado, si nos da igual esto (es decir, que no vamos a poner más cosas por encima), se podría hacer con un JLabel usando su método setIcon(new ImageIcon(”imagen.png”)), otra forma que muchos dirán sería usar un Canvas y su método setBackground, el cual es una ponzoña, pues al usarlo, el Canvas estará disparando eventos de repintado aparte de los usuales de su método Paint(), es decir, que con un Canvas habría que hacer lo que hemos hecho arriba con JPanel.

9 Comentarios »

RSS feed para los comentarios de esta entrada.

  1. avatar

    Java es un lenguaje muy potente, pero hacer interfaces es algo que puede llegar a ser tan divertido como una patada en los cojones xD

    tan divertido como eso… y mucho más tambien… (alguien ha visto la peli de Hostel ? :P )
    De los IDEs, pues otro que es fantabuloso (fantastico y maravilloso al mismo tiempo) es el Kawa, que por momentos se volvía anti-intuitivo :o

     

    Comentario por txus — 9 Agosto, 2006 @ 14:57 #

  2. avatar

    Pero si este blog sólo lo leemos tus amiguitos y no nos enteramos de eso para que lo pones jeje.

     

    Comentario por manolito — 9 Agosto, 2006 @ 15:09 #

  3. avatar

    txus, kawa es solo para Windows, además no tiene editor de interfaces si no recuerdo mal.
    manolito, lo escribo para tenerlo aquí para mi, e igual a alguien más le sirve también :P

     

    Comentario por blaxter — 9 Agosto, 2006 @ 15:52 #

  4. avatar

    hasta este post he llegado yo, que vivo en Uruguay porque necesitaba meter una imagen de fonde en un form del netbeans y hasta ahora no sabia como hacerlo…. meti unas key en google y me trajo hasta aqui…..cuando pruebe este codigo te digo si funciona o no, pero por ahora muchas gracias.
    Salu2
    Normandos

     

    Comentario por normandos — 19 Agosto, 2006 @ 22:30 #

  5. avatar

    Lo felicito su codigo es excelente sobre todo la elegancia de la segunda version donde mostro muy bien los patrones de diseño.

    me acaba de ayudar.

    si necesita codigos tutores de java escribame, se acaba de ganar un amigo. carmario55@gmail.com.

    algo mas yo estoy trabajando con un protocolo para captura de imagenes llamado twain si necesita algo. escribame

     

    Comentario por Ing mario Medina — 21 Septiembre, 2006 @ 17:36 #

  6. avatar

    Wilmer says: Hola, estoy viendo algoritmos y lenguajes 2 en la Universidad y vamos por swing!!

    me sorprende la facilidad y la destreza con que programas… pues a mí ,al verdad, me causa un poco de dificultad…

    En el proyecto final… estoy quedado, además para que se vea bonito quiero poner una imagen de fondo, más no sé como, por eso encontré esta pagina, debo revisar el código, aunque sé que no es lo mismo una textura que una imagen!!!

    Si me puedes ayudar, desde colombia, te agradecería enormemente!!!!
    Gracias y te felicito

     

    Comentario por Wílmer — 12 Noviembre, 2006 @ 7:32 #

  7. avatar

    Wilmer, es equivalente, en java para “pintar” necesitas una textura (fijate en el método cuando se hace g2d.setPaint(fondo); ahí estableces con qué vas a pintar), por lo tanto convertimos nuestra imagen de fondo en un TexturePaint y de esa forma ya podemos pintar toda la superficie del componente, lo que equivale a poner una imagen de fondo :)

     

    Comentario por blaxter — 12 Noviembre, 2006 @ 14:55 #

  8. avatar

    Muchas gracias por este codigo es de gran ayuda, me estaba volviendo loco tratando de buscar algo hecho asi
    Desde Argentina, saludos y nuevamente gracias

     

    Comentario por eynob — 15 Enero, 2007 @ 23:59 #

  9. avatar

    esta charrul esto mejor no publiquen nada!!!!!

     

    Comentario por anonimo — 14 Mayo, 2008 @ 0:52 #

Dejar un comentario

XHTML permitido: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Creative Commons License Esta obra está bajo una licencia de Creative Commons.

Este blog funciona gracias a WordPress con el theme GimpStyle diseñado por Horacio Bella y adaptado por un servidor.
Feed entradas