Dibujar con Graphics encima de un panel con una imagen de fondo

Iniciado por NathanD, 12 Noviembre 2013, 19:57 PM

0 Miembros y 1 Visitante están viendo este tema.

NathanD

Buenas, estoy con algo que me lleva trayendo de cabeza desde hace bastante. Mi pregunta es ésa, ¿cómo puedo poner una imagen de fondo, y luego superponer figuras con Graphics? Lo he intentado de mil maneras, a veces no me hace caso, y otras da error en tiempo de ejecución, y no sabría ni qué código poner aquí. He conseguido poner otros componentes como JLabels o JButtons, pero con Graphics no puedo.

Gracias de antemano y saludos.

Mitsu

Coloca el código que tengas para ver las posibles fallas.

NathanD

Éste es uno de tantos intentos. No está muy limpio; lo he hecho con algo de prisa. Lo dicho arriba, no sé como poner un panel de fondo y luego ver los Graphics encima de éste.

El código:
Código (java) [Seleccionar]
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Demo1 extends JComponent {


   private final static int ANCHO = 512;

   private final static int ALTO = 384;

   private final static int DIAMETRO = 20;

   private float x, y;

   private float vx, vy;

   public Demo1() {
       setPreferredSize(new Dimension(ANCHO, ALTO));
       x = 10;
       y = 20;
       vx = 300;
       vy = 400;
   }

   private void fisica(float dt) {
       x += vx * dt;
       y += vy * dt;
       if (vx < 0 && x <= 0 || vx > 0 && x + DIAMETRO >= ANCHO)
           vx = -vx;
       if (vy < 0 && y < 0 || vy > 0 && y + DIAMETRO >= ALTO)
           vy = -vy;
   }

   public void paint(Graphics g) {
   
       g.setColor(Color.WHITE);
       g.fillRect(0, 0, ANCHO, ALTO);
       g.setColor(Color.RED);
       g.fillOval(Math.round(x), Math.round(y), DIAMETRO, DIAMETRO);
   }

   private void dibuja() throws Exception {
    this.repaint();
   }

   public void cicloPrincipalJuego() throws Exception {
       float dt = 0.01f;
       while (true) {
        Thread.sleep(10);
        fisica(dt);
           dibuja();
       }
   }

   public static void main(String[] args) throws Exception {
    JFrame jf = new JFrame("Demo1");
       jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       jf.setResizable(false);
       
       Demo1 demo1 = new Demo1();
       jf.setContentPane(crearPanel());
       jf.pack();
       jf.setVisible(true);
       demo1.cicloPrincipalJuego();
   }

private static Container crearPanel() {
JPanel panel = new JPanel();
JLabel label = new JLabel();

label.setIcon(new ImageIcon("img.jpg"));
panel.add(label);

return panel;
}
}


Muchas gracias por vuestra paciencia y saludos.

Mitsu

#3
Hago uso de BufferedImage y de ImageIO para almacenar la imagen en un buffer y leer la imagen original respectivamente.



Código (=java) [Seleccionar]

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class ImageJPanel extends JFrame {


public static void main(String... args) {
new ImageJPanel();
}

public ImageJPanel() {
super("Dibujo sobre imagen");

this.add(new PanelOverDraw());
this.setSize(484,519);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setVisible(true);
}

public class PanelOverDraw extends JPanel {


private BufferedImage img = null;

public PanelOverDraw() {

File imageFile = new File("background.jpg"); // guarda la imagen en un archivo
try {
img = ImageIO.read(getClass().getResourceAsStream(imageFile.toString())); // la carga en una BufferedReader
} catch (IOException e) {
e.printStackTrace();
}

this.setPreferredSize(new Dimension(484,409));

// creamos una instancia graphics desde la imagen para pintar sobre ella
Graphics2D pint = img.createGraphics();
        pint.setColor(Color.GREEN);
        pint.fillRect(200,200,100,100);
        pint.dispose();

}

@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(img,0,0,null); // dibuja la imagen al iniciar la aplicacion
}

}
}

NathanD

Cita de: M1t$u en 13 Noviembre 2013, 05:43 AM
Hago uso de BufferedImage y de ImageIO para almacenar la imagen en un buffer y leer la imagen original respectivamente.



Código (=java) [Seleccionar]

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class ImageJPanel extends JFrame {


public static void main(String... args) {
new ImageJPanel();
}

public ImageJPanel() {
super("Dibujo sobre imagen");

this.add(new PanelOverDraw());
this.setSize(484,519);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setVisible(true);
}

public class PanelOverDraw extends JPanel {


private BufferedImage img = null;

public PanelOverDraw() {

File imageFile = new File("background.jpg"); // guarda la imagen en un archivo
try {
img = ImageIO.read(getClass().getResourceAsStream(imageFile.toString())); // la carga en una BufferedReader
} catch (IOException e) {
e.printStackTrace();
}

this.setPreferredSize(new Dimension(484,409));

// creamos una instancia graphics desde la imagen para pintar sobre ella
Graphics2D pint = img.createGraphics();
        pint.setColor(Color.GREEN);
        pint.fillRect(200,200,100,100);
        pint.dispose();

}

@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(img,0,0,null); // dibuja la imagen al iniciar la aplicacion
}

}
}


Muchísimas gracias, no sabes cuánto me has ayudado. Gracias.

NathanD

Copio y pego el código y me sale el siguiente error de compilación:

Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java:1348)
at ImageJPanel$PanelOverDraw.<init>(ImageJPanel.java:40)
at ImageJPanel.<init>(ImageJPanel.java:25)
at ImageJPanel.main(ImageJPanel.java:19)


La línea del error es la 24.

Código (java) [Seleccionar]
this.add(new PanelOverDraw());

¿A qué se puede deber? Gracias por tu paciencia y un saludo.

Mitsu

ImageIO.read() está retornando null. Esto significa, que el path de la imagen está mal. Si tienes la imagen en un subpaquete, no olvides colocar "/" al principio del path.

NathanD

Vale, ya está, tenía que colocar la imagen en la carpeta bin con los .class, aunque hasta ahora la he puesto en la carpeta del proyecto...

Muchísimas gracias otra vez.