Swing - ImageIcon.paintIcon() problems with scaled Graphics

When calling the ImageIcon.paintIcon() method with a significantly scaled down Graphics object I'm observing problems - specifically drawing junk outside the region of the scaled down icon.

I can reproduce this behavior with the following program. You'll need to create your own icon named "mycon.gif" (try something around 100x100 pixels) and keep rotating the mouse wheel til the icon size is vanishingly small.

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

publicclass Problemextends JFrame{

public Problem(String name){

super(name);

add(new ProblemPanel(), BorderLayout.CENTER);

}

privatestaticvoid createGui(){

Problem p =new Problem("Problem");

p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

p.setSize(800, 800);

p.setVisible(true);

}

publicstaticvoid main(String[] args){

SwingUtilities.invokeLater(new Runnable(){

publicvoid run(){

createGui();

}

});

}

}

class ProblemPanelextends JPanelimplements MouseWheelListener{

privatestaticfinal String ICON ="mycon.gif";

privatestaticfinaldouble FACTOR = 1.1;

private Icon icon;

privatedouble scale;

public ProblemPanel(){

this.icon =new ImageIcon(getClass().getResource(ICON));

this.scale = 1.0;

addMouseWheelListener(this);

}

publicvoid mouseWheelMoved(MouseWheelEvent event){

if (event.getWheelRotation() < 0){

this.scale *= FACTOR;

}

else{

this.scale /= FACTOR;

}

repaint();

}

publicvoid paint(Graphics g){

Graphics2D g2d = (Graphics2D) g;

g2d.setColor(Color.white);

g2d.fillRect(0, 0, getWidth(), getHeight());

g2d.scale(this.scale, this.scale);

this.icon.paintIcon(this, g2d, 100, 100);

}

}

[4063 byte] By [Greg.Ariasa] at [2007-11-26 23:25:44]
# 1
Well, I can't test your code because I don't have a mouse wheel, but what if you changed the width/height used in the paintIcon method to match the scaling or the original icon size.
camickra at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...
# 2
I've run that code and I can't observe any problems. Works fine for me (JDK 1.5.0_07, and JDK 1.4.2_09 with corresponding change from add() to setContentPane()).
itchyscratchya at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...
# 3

The last two arguments to paintIcon specify the position not the size of the icon.

void paintIcon(Component c, Graphics g, int x, int y)

Greg.Ariasa at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...
# 4
This problem may be specific to my graphics hardware/driver.
Greg.Ariasa at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...
# 5
Could well be - have you checked for updated drivers for your graphics card?
itchyscratchya at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...
# 6
It worked on my MacBook Pro.
sundaycodera at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...
# 7

Do not change the state of passed Graphics object without restoring it. You apply a scaling transformation on a Graphics object that you don't own. Depending on VM implementation and other parameters, this may or may not be reproducible in other environments. Use .create() and .dispose() to operate on a Graphics copy.

kirillga at 2007-7-10 14:33:21 > top of Java-index,Desktop,Core GUI APIs...