0

I have a Java swing application where I've created an ImageIcon with a picture and displayed it to a screen. I did that by loading a URL as an ImageIcon and placing it in the Java Swing window as a label.

Now I need to place 'markers' on the image with other images. In context: Place a picture of an eye on someones face over their eye.

I'd appreciate anyone who can point my in the right direction or give me some SSCCE code to work from.

What is the best manner to place 'markers' on an ImageIcon Java Swing?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Jay
  • 2,107
  • 4
  • 20
  • 24
  • 2
    Using `ImageIO` to load your images, this gives you a `BufferedImage`. This is much easier to draw in. If you can't, you will need to paint the `ImageIcon` to a `BufferedImage`, paint you marks and then wrap it back into a new `ImageIcon` – MadProgrammer Dec 18 '12 at 01:18
  • 1
    Get the `Graphcs` (or better, the `Graphics2D`) of the main `BufferedImage` and draw the marker images onto it at appropriate size and location. Check the docs for details and get back to us when *you* can post an SSCCE of *your* best attempt (is what I recommend). – Andrew Thompson Dec 18 '12 at 01:20
  • Thanks guys, will start researching how to use those tools. Any chance either of you have a basic sort of SSCCE I can use to get started? – Jay Dec 18 '12 at 01:26
  • 1
    For [example](http://stackoverflow.com/a/2658663/230513). – trashgod Dec 18 '12 at 01:27

1 Answers1

1

The basic concept is, you need a temporary image onto which you can paint the master/base image and the marker.

  1. Create a new BufferedImage. This would typically be the same size as the master image, but doesn't have to be.
  2. Paint the master image onto BufferedImage
  3. Paint the marker onto the BufferedImage
  4. Create a new ImageIcon using the BufferedImage
  5. Apply the ImageIcon to the label...

enter image description hereenter image description hereenter image description here

public class PaintIcon {

    public static void main(String[] args) {
        new PaintIcon();
    }

    public PaintIcon() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new PaintPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintPane extends JPanel {

        private JLabel label;
        private int state = 0;

        private BufferedImage disk;
        private BufferedImage play;
        private BufferedImage pause;
        private BufferedImage stop;

        public PaintPane() {

            setLayout(new GridBagLayout());
            add((label = new JLabel()));

            try {
                disk = ImageIO.read(getClass().getResource("/cd.png"));
                play = ImageIO.read(getClass().getResource("/media_play.png"));
                pause = ImageIO.read(getClass().getResource("/media_pause.png"));
                stop = ImageIO.read(getClass().getResource("/media_stop.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }

            updateState();

            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    state++;
                    if (state > 2) {
                        state = 0;
                    }
                    updateState();
                }
            });
        }

        protected void updateState() {
            BufferedImage base = new BufferedImage(disk.getWidth(), disk.getHeight(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = base.createGraphics();
            g2d.drawImage(disk, 0, 0, this);
            BufferedImage marker = null;
            switch (state) {
                case 0:
                    marker = stop;
                    break;
                case 1:
                    marker = play;
                    break;
                case 2:
                    marker = pause;
                    break;
            }
            int x = disk.getWidth() - marker.getWidth();
            int y = disk.getHeight() - marker.getHeight();
            g2d.drawImage(marker, x, y, this);
            g2d.dispose();

            label.setIcon(new ImageIcon(base));
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Hi, thanks, I really appreciate your response. I just tried to implement your code however I keep getting errors. I even went and put some some png files into the src and ensured the naming was the same: errors I got:`code` java.lang.IllegalArgumentException: input == null! at javax.imageio.ImageIO.read(ImageIO.java:1388) at PaintIcon$PaintPane.(PaintIcon.java:59) at PaintIcon$1.run(PaintIcon.java:35)`code` – Jay Dec 18 '12 at 02:35
  • Basically the error is telling you (in a round about way) that the resource you are trying to load can't be found. – MadProgrammer Dec 18 '12 at 02:37
  • Strange, I just got a bunch of .png files and named them exactly what you had cd, media_pause, media_stop and media_play – Jay Dec 18 '12 at 02:40
  • If you're running Eclipse, you may need to build and Jar the project – MadProgrammer Dec 18 '12 at 02:42
  • Running Netbeans but I will try that! =] – Jay Dec 18 '12 at 02:43
  • Built the example in Netbeans. Make sure the images are in the `default` package of the project. – MadProgrammer Dec 18 '12 at 02:48
  • Many thanks, it compiles however it just displays a static image, there seems no way of placing one image on to of another or anything? – Jay Dec 18 '12 at 02:48
  • Try clicking the icon. It has a mouse listener that will switch the between the different states ;) – MadProgrammer Dec 18 '12 at 02:53