I once had a similar problem, and it was solved by drawing text with high fidelity, and then drawing a rotated image.
Here is the code:
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class RotatedText extends JPanel {
String message = "How does this text look?";
public RotatedText() {
this.setPreferredSize(new Dimension(640, 280));
}
public BufferedImage createStringImage(Graphics g, String s) {
int w = g.getFontMetrics().stringWidth(s) + 5;
int h = g.getFontMetrics().getHeight();
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D imageGraphics = image.createGraphics();
imageGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
imageGraphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
imageGraphics.setColor(Color.BLACK);
imageGraphics.setFont(g.getFont());
imageGraphics.drawString(s, 0, h - g.getFontMetrics().getDescent());
imageGraphics.dispose();
return image;
}
private void drawString(Graphics g, String s, int tx, int ty, double theta, double rotx, double roty) {
AffineTransform aff = AffineTransform.getRotateInstance(theta, rotx, roty);
aff.translate(tx, ty);
Graphics2D g2D = ((Graphics2D) g);
g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2D.drawImage(createStringImage(g, s), aff, this);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("MyriadPro", Font.BOLD, 20));
drawString(g, message, 80, 20, 0, 0, 0);
drawString(g, message, 80, 80, -Math.toRadians(7.0), -10, 80);
drawString(g, message, 60, 260, -Math.toRadians(30.0), -40, 80);
g.setFont(new Font("MyriadPro", Font.BOLD, 12));
drawString(g, message, 380, 20, 0, 0, 0);
drawString(g, message, 380, 120, -Math.toRadians(7.0), -10, 80);
drawString(g, message, 320, 400, -Math.toRadians(30.0), -40, 80);
}
private void display() {
JFrame f = new JFrame("RotateTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new RotatedText().display();
}
});
}
}