Nevermind, I found a way:
Just create a class ScaledIcon
which implements the Icon
Interface, takes the image, width and height as constructor, then implemented my own paintIcon method, which draws the icon with the preferred width and height (as set in Constructor) Usage:
JLabel label = new JLabel("Some Text", new ScaledIcon(originalIcon.getImage(), 16, 16), SwingConstants.HORIZONTAL);
Draws the Icon fine with higher DPI, works as expected (i.e. if UI is scaled to 200%), I get the desired result, finally a crisp icon (when loading a 32x32px version scaled to 16x16px).
ScaledIcon class:
public class ScaledIcon implements Icon {
private final Image image;
private final int width;
private final int height;
public ScaledIcon(Image image, int width, int height) {
this.image = image;
this.width = width;
this.height = height;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.drawImage(image, x, y, width, height, c);
}
@Override
public int getIconWidth() {
return width;
}
@Override
public int getIconHeight() {
return height;
}
}
ImageIcon
can be constructed based on anImage
, and anImage
has thegetScaledInstance()
methodgetIconWidth
andgetIconHeight
. Not sure of knock-on effects if that worksJLabel
and thatJLabel
contains an icon of the image that you are using.getScaledInstance()
method actually scales the image down (so reduces the pixelcount, if going from 32x32 to 16x16), same as directly using a 16x16 image and not getting a sharper image, when UI is scaled up. It makes me we wonder, if there is nothing provided for hidpi or retina screens.