-1

I need to add a background Image to my main frame which has panels added to it. Then in the paintComponent method of my panel class I would be drawingOvals and lines. The paintComponent draws shapes to the panels and not the frame. I can add a background image to the frame using a label but the problem is that nothing is visible on top of that. Any help is appreciated.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Unknown94
  • 47
  • 6
  • Great. What have you done, and where are you stuck? – Hovercraft Full Of Eels Nov 13 '15 at 16:46
  • Links to creating a background image: [1](http://stackoverflow.com/questions/1064977/setting-background-images-in-jframe), [2](http://stackoverflow.com/questions/18777893/jframe-background-image), [3](http://stackoverflow.com/questions/1466240/how-to-set-an-image-as-a-background-for-frame-in-swing-gui-of-java). Links to drawing ovals in a JPanel: [1](http://stackoverflow.com/questions/17753492/adding-oval-shape-to-jpanel), [2](http://stackoverflow.com/questions/14056610/can-not-draw-oval-on-a-jpanel). – Hovercraft Full Of Eels Nov 13 '15 at 16:50
  • This is just a smaller part of the code I am working on. So I have tried using ImageIcon in paintComponent but it draws on top of the circles. – Unknown94 Nov 13 '15 at 16:51
  • I know how to add background Image and draw Ovals individually. The problem is that when I add a background nothing else can be done on top of it. The circles drawn arent visible as they are under the background label. – Unknown94 Nov 13 '15 at 16:54
  • No, you know **one way** to draw a background image -- but its the wrong way for your purposes. Please see answer below. – Hovercraft Full Of Eels Nov 13 '15 at 16:55

1 Answers1

3

You need to:

  • First and foremost, don't use an ImageIcon and a JLabel.
  • Use a single JPanel to draw both the background image and the shapes, and draw within its paintComponent method.
  • Instead use a BufferedImage, and draw that image in your JPanel's paintComponent method using g.drawImage(...) (g being your Graphics object variable).
  • In that same paintComponent method, draw your shapes, but after drawing the image.
  • Links to creating a background image: 1, 2, 3.
  • Links to drawing ovals in a JPanel: 1, 2.

For example, this image with an oval drawn on it:

enter image description here

Is created with this code:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.*;

public class DrawOnImage extends JPanel {
    private static final String PATH = "https://upload.wikimedia.org/wikipedia/"
            + "commons/thumb/c/c4/Gay_nov_20_1992_2115Z.jpg/"
            + "581px-Gay_nov_20_1992_2115Z.jpg";
    private static final Color SHAPE_COLOR = new Color(150, 150, 255);
    private static final Stroke STROKE = new BasicStroke(10f);
    private static final double OVAL_X = 195;
    private static final double OVAL_Y = 200;
    private static final double OVAL_W = 200;
    private BufferedImage img;
    private List<Shape> shapes = new ArrayList<>();

    public DrawOnImage(BufferedImage img) {
        this.img = img;
        shapes.add(new Ellipse2D.Double(OVAL_X, OVAL_Y, OVAL_W, OVAL_W));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(STROKE);
        g2.setColor(SHAPE_COLOR);
        for (Shape shape : shapes) {
            g2.draw(shape);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || img == null) {
            return super.getPreferredSize();
        }
        int w = img.getWidth();
        int h = img.getHeight();
        return new Dimension(w, h);
    }

    private static void createAndShowGui() {
        BufferedImage img = null;

        try {
            img = ImageIO.read(new URL(PATH));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        JFrame frame = new JFrame("Draw On Image");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new DrawOnImage(img));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • @AKANKSHABANSAL: please see update to answer including code. Also please don't post code in comments. Instead, if you need to show code, edit your question and show your code there. And again, **don't use ImageIcon and JLabel**. I can't stress this strongly enough. – Hovercraft Full Of Eels Nov 13 '15 at 17:10