Hey guys, I'm working on a game, and I was trying to mirror the gif images inside the program so I wouldn't have to do it manually (And also so it wouldn't use twice as much space to store the mirrored gifs). Anyway, I Google'd it and found this answer, it works well in the code, when you set the imageIcon as the JLabel Icon, but when I try to modify it a little and paint the image to a component, it just disappears... Here's the code:

public class HelperClass {

    public static void main(String[] args) {
        JFrame f = new JFrame("Test");
        final ImageIcon io = new MirrorImageIcon("test.gif");
        final ImageIcon oi = new ImageIcon("test.gif");
        final Component c = new Component() {

            @Override
            public void paint(Graphics g) {
                super.paint(g);
                io.paintIcon(this, g, 50, 50);
                oi.paintIcon(this, g, 100, 50);
            }
};
        f.add(c);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300,300);
        f.setVisible(true);
    }

}

class MirrorImageIcon extends ImageIcon {

    public MirrorImageIcon(String filename) {
        super(filename);
    }

    @Override
    public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
        Graphics2D g2 = (Graphics2D)g.create();
        g2.translate(getIconWidth(), 0);
        g2.scale(-1, 1);
        super.paintIcon(c, g2, x, y);
    }

}

The original Image shows up, but the mirrored one doesn't! What am I doing wrong?

Why do you think your translate and scale calls will create a mirror image?
If you comment those two method calls out, the image is displayed.

Why do you think your translate and scale calls will create a mirror image?
If you comment those two method calls out, the image is displayed.

Wait a minute... Does "mirror image" means what I think it does? Does it mean "image flipped horizontally"?
Because those method calls do flip it horizontally! When you call the scale method, the image is flipped, but it stays a width of the image left, so the translate method fixes it!

Edited 5 Years Ago by yancouto: n/a

The code works just fine here. Check the size and positions you're painting the icons, because I think you're just overlapping them.

I tried the code and got a single image displayed.
When I commented out these lines:

g2.translate(getIconWidth(), 0);
        g2.scale(-1, 1);

It get two identical images displayed.

Does your execution show two images with one a mirror of the other?

Yes, but one is partially occluded by the other because I did not alter any of the positioning code to account for differences in image width.

Thanks. I changed the following line several times and am now able to see the mirrored image

io.paintIcon(this, g, 01, 50); // 01 vs 50

To get it to actually render in the correct location, I also had to negate the x position in the super.paintIcon() call to account for the inverted scaling:

super.paintIcon(c, g2, -x, y);

@yancuoto: I would also recommend extending JComponent instead of Component and overriding paintComponent() unless you have to mix this with other heavyweight AWT components.

Edited 5 Years Ago by Ezzaral: n/a

Comments
Thank you man, you really helped me!

To get it to actually render in the correct location, I also had to negate the x position in the super.paintIcon() call to account for the inverted scaling:

super.paintIcon(c, g2, -x, y);

@yancouto: I would also recommend extending JComponent instead of Component and overriding paintComponent() unless you have to mix this with other heavyweight AWT components.

Thanks man, this fixed the problem!
I checked the API and what happens is that the paint() method calls the paintComponent() and some other methods, am I right?
I think I get why you have to put -x, because the Graphics2D scaled the "x" with -1 so it would be inverted, right?

Anyway, thanks again!

> I think I get why you have to put -x, because the Graphics2D scaled the "x" with -1 so it would be inverted, right?
Yes, with the entire transform inverted like that, the x value you pass to the method actually ends up being an offset to the left instead of to the right.

This question has already been answered. Start a new discussion instead.