可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In a subclass of a JPanel
I am doing this:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.rotate(Math.toRadians(90.));
g2d.drawString(aString, 40, -40);
}
The letters are rotated correctly, but the second one is not in the expected position below the first (to its right, in the rotated space), but is above it (to its left), the third is above (to the left of) the second, etc. Changing the rotation angle to 45 degrees results in each character being rotated 45 degrees cw, as expected, but the row of characters being rotated 45 degrees ccw, which is consistent with both rotations being halfway toward the result for 90 degrees.
At 0 degrees rotation the text appears correctly.
I'm developing with NetBeans 7.1.2 on Mac OS X 10.8.2. Same version of NetBeans on Win 7 SP1 does not have the problem.
What could be causing this?
回答1:
I've found an odd solution for this problem (that matches the oddness of the bug)
FontRenderContext frc = new FontRenderContext(g2.getTransform(), true, true);
g2.drawGlyphVector(currentFont.createGlyphVector(frc, aString), textX, textY);
For some reason setting anti-aliasing to true on the FontRenderContext will cause it to act correctly. Seems that someone is missing a minus sign somewhere in the render code, or misunderstood the spec they were writing for!
回答2:
We're seeing the same thing. We have code that works great on Windows spanning most of the JRE 6 and 7 versions. The same code today exhibited the rotated backwards characters problem. The problem JRE version is 1.6.0_37 on OS X. It may or may not have worked before on OS X. 99.9% of our users are on Windows.
One workaround would be to render the text to a BufferedImage and then rotate the image. That's a method I've used to get a better result visually for rotating text 20-30 degrees or so.
回答3:
The method of AffineTransformation posted by user1181445 below was working for me for all platforms, including the problematic OSX, up until the most recent Java OSX update (version 7, update 55). Now the rotated text is messed up, but only on the applet. I don't see a problem in the standalone version of our app.
回答4:
On OS X 10.10 vs Windows 7, I've got exactly the same problem, but in reverse! I.e. rotating the entire graphics context before drawing the vertical text looks fine, but applying an AffineTransform to a new font produces strangely rotated text.
I think it is slightly more efficient to rotate just the text, so a practical if inelegant solution is to check the platform first:
Font font = g.getFont();
if (System.getProperty("os.name").startsWith("Mac")) {
g.rotate(-Math.PI / 2, x, y);
g.drawString(string, x, y);
g.rotate(Math.PI / 2, x, y);
} else {
AffineTransform fontAT = new AffineTransform();
fontAT.rotate(-Math.PI / 2);
g.setFont(font.deriveFont(fontAT));
g.drawString(string, x, y);
g.setFont(font);
}
回答5:
There are 2 things that could work from what I can see right now.
The first would be to split the String into a char array, then after the rotate go 1-by-1 incrementing the font size (+1 or 2 if bolded) so that they line up, going top to bottom.
The second way would be to make your own font, which I wouldn't recommend. If you draw the String before the rotation, then when it rotates hypothetically if you made the font correctly it will display as it should.
If I can think of another way I will post it.
Edit:
final AffineTransform at = new AffineTransform();
final Font font = g.getFont();
// Derive a new font using a rotatation transform (Theta is angle in radians).
at.rotate(theta);
final Font newFont = font.deriveFont(at);
// set the derived font in the Graphics2D context
g2d.setFont(newFont);
// Render a label instance of type String using the derived font
g2d.drawString(label, x, y);
So, to draw vertically that would be a rotate of 270 degrees, or 3/2 * pi