0

How can I draw on JLabel with icon? In my code oval replaced the image, there is only oval and canvas, not image. I want to draw on image. What should I do?

public void go() {
    String IMAGE_PATH = "start_phone.jpg";
    URL imgUrl = getClass().getResource(IMAGE_PATH);
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    MyLabel imageLabel = new MyLabel();
    ImageIcon icon = new ImageIcon(getClass().getResource(IMAGE_PATH));
    imageLabel.setIcon(icon);
    imageLabel.add(panel);
    frame.add(imageLabel);
    frame.setSize(1200, 1200);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class MyLabel extends JLabel {
    public void paintComponent(Graphics g) {
        g.setColor(Color.green);
        g.fillOval(100, 100, 100, 100);
    }
}
Nerkan
  • 11
  • 1
  • 3
    If you only want to draw on the image, then create a `BufferedImage`, draw the `ImageIcon` on to it, then draw what ever you want onto of it. Wrap the `BufferedImage` in a `ImageIcon` and then assign it to the label. If you want to paint over the whole label (text and image), then call `super.paintComponent` first – MadProgrammer Apr 17 '19 at 21:52
  • Possible duplicate of [How to change JFrame icon](https://stackoverflow.com/questions/1614772/how-to-change-jframe-icon) – Manuel Apr 17 '19 at 22:26

1 Answers1

2

If all you want to do is draw onto the icon, then use a BufferedImage, for example...

Simple

try {
    BufferedImage phone = ImageIO.read(Main.class.getResource("/test/phone.png"));
    Graphics2D g2d = phone.createGraphics();
    g2d.setColor(Color.RED);
    g2d.fillOval(phone.getWidth() - 17, 0, 16, 16);
    g2d.dispose();

    JLabel label = new JLabel("Phone");
    label.setIcon(new ImageIcon(phone));

    JOptionPane.showMessageDialog(null, label);
} catch (IOException ex) {
    ex.printStackTrace();
}

In your code, you could either load the image directly as a BufferedImage, as the example above does, or load it as a ImageIcon and paint that onto a new BufferedImage, depending on your needs

If, instead, you want to paint onto of the label, well, that's more complicated. Remember a JLabel is a complex component, with icon, text and placement logic. The problem with all this is, you can't gain access to the information used to layout individual elements.

The important thing is, call super.paintComponent. This is actually painting the icon and text...

public static class ExampleLabel extends JLabel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.RED);
        g2d.fillOval(getWidth() - 17, 0, 16, 16);
        g2d.dispose();
    }

}

and then simply use it...

Complicated

try {
    BufferedImage phone = ImageIO.read(Main.class.getResource("/test/phone.png"));
    JLabel label = new ExampleLabel();
    label.setText("Phone");
    label.setIcon(new ImageIcon(phone));

    JOptionPane.showMessageDialog(null, label);
} catch (IOException ex) {
    ex.printStackTrace();
}

So, the answer to your question is, it depends on what you want to achieve...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Is there a way to do it without using `JOptionPane.showMessageDialog` ? I am coding a simple game and I want to add some beatiful background to panel where all elements is drawn. Is it possible just to add `JLabel` and draw on it or some other way which allows to just image as background to panel? – Nerkan Apr 18 '19 at 16:17
  • I am using timer to repainting so creation new image every time is impossible – Nerkan Apr 18 '19 at 19:34
  • @Nerkan The `JOptionPane` is an example. If you're trying to generate background component, then I wouldn't use a `JLabel`, it's now well suited for the task - See [this example](https://stackoverflow.com/questions/22162398/how-to-set-a-background-picture-in-jpanel/22162430#22162430) for more details – MadProgrammer Apr 18 '19 at 21:54