Yes, it's a known issue, but it's possible to work around this, using a clever trick I once found in a blog post by Chris Campbell:
It is true that Sun's Java 2D implementation does not automatically antialias image edges when rendering with Graphics.drawImage(). However, there is a simple workaround: use TexturePaint and render a transformed/antialiased fillRect().
This is the code I use, adapted from the code in his blog:
// For multiples of 90 degrees, use the much faster drawImage approach
boolean fast = ((Math.abs(Math.toDegrees(angle)) % 90) == 0.0);
int w = source.getWidth();
int h = source.getHeight();
// Compute new width and height
double sin = Math.abs(Math.sin(angle));
double cos = Math.abs(Math.cos(angle));
int newW = (int) Math.floor(w * cos + h * sin);
int newH = (int) Math.floor(h * cos + w * sin);
// Create destination image for painting onto
BufferedImage dest = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
// Set up transformation around center
AffineTransform transform = AffineTransform.getTranslateInstance((newW - w) / 2.0, (newH - h) / 2.0);
transform.rotate(angle, w / 2.0, h / 2.0);
Graphics2D g = dest.createGraphics();
try {
g.transform(transform);
if (!fast) {
// Max quality
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Here's the trick:
g.setPaint(new TexturePaint(source,
new Rectangle2D.Float(0, 0, source.getWidth(), source.getHeight())));
g.fillRect(0, 0, source.getWidth(), source.getHeight());
}
else {
// Multiple of 90 degrees:
g.drawImage(source, 0, 0, null);
}
}
finally {
g.dispose();
}