Capas con imagen de fondo en Java
Publicado por blaxter - 09 Ago 2006 a las 14:42Java 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 300x10px donde la mitad superior es negra y la mitad inferior es blanca. Adivinas el efecto que surgirá?, yeah, una cebra xD.
GUI.java
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 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:

Demo 2 - JPanelBackground: ya que estamos, hacemos un nuevo JPanel nuevo, no?
JPanelBackground
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.
10 Comentarios »
RSS feed para los comentarios de esta entrada.
Dejar un comentario
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
tan divertido como eso… y mucho más tambien… (alguien ha visto la peli de Hostel ?
)
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
Comentario por txus — 9 Agosto, 2006 @ 14:57 #
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 #
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
Comentario por blaxter — 9 Agosto, 2006 @ 15:52 #
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 #
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 #
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 #
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 #
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 #
esta charrul esto mejor no publiquen nada!!!!!
Comentario por anonimo — 14 Mayo, 2008 @ 0:52 #
Se puede hacer de otra forma mucho más sencilla:
1) Se añade un LayeredPane.
2) En él se añade un etiqueta (que pondremos sin texto y como icono la imagen que queremos mostrar), ajustando su tamaño al de la ventana.
3) En el LayeredPane se añade otro panel (en la propiedad “Layer” ponemos “DRAG_LAYER”, para que quede sobre la imagen).
4) En este otro panel ponemos todos los demás componentes de la ventana.
(Todo esto lo he ehcho utilizando NetBeans 6.1)
Comentario por Ana — 9 Julio, 2008 @ 13:06 #