Category Archives: Java

Java, ese “maravilloso” mundo

logo_java.pngUna cosa es conocer java, el lenguaje de programación que más se usa a nivel empresarial. Pero mucha gente dice, incluso, saber programar en Java. Cuando en verdad lo que hacen es copypastear código buscado en google o similares, ejecutar las cosas mil veces hasta que funciona, tener mil plugins de eclipse para hacer tareas que ni llegan a entender o comprender qué hacen realmente (y desde luego que si les quitas el IDE, ni sabrían seguir trabajando).
 
Cuando alguien me pregunta si sé Java, la verdad que siempre dudo en qué contestar, puesto que aún no he llegado a conocer en profundidad y/o usar todas las tecnologías. Podríamos citar: Applets, swing, SWT, AWT, Java 2D, Java 3D, servlets, JSP, CORBA, JB, EJB, JCA, JMS, JDO, EIS, RMI, JCA, JCE, JDBC, JNDI, JAAS, JRMP, JNI, JNLP, JTA, portlets, JAXP, JAXB, JAX-WS, JMX, JMI, JSF, GWT, Struts, Jetty, Ant, Maven, JUnit, Tomcat, JBoss, JOnAS, WebSphere y por supuesto XML (del cual se podría hacer un post similar a este…) y Web Services (aunque el modelo REST es mil veces mejor).
 
Además, seguro que habrá otras tantas tecnologías que no las conoceré. Todas las mencionadas las conozco, pero no puedo decir que sé manejar todas ellas (a decir verdad, de unas cuantas solo he leído cuatro historias para saber qué cojones es, y para de contar). Por lo tanto, cuando alguien me pregunta si Java, suelo contestar que intento defenderme, si quiero respuesta rápida, o, respondo con una contra pregunta para que especifique más, si quiero alargar el tema.
 
Por supuesto, para aprender éstas y otras muchas tecnologías que me habré olvidado, la mejor web del mundo mundial es JCP.

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 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 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.