25

I want to rotate text on a JPanel using Graphics2D..

My code is this:

double paso=d.width/numeroBarras;
        double alto=datos[i].valor;
        Font fBarras=new Font("Serif", Font.PLAIN, 15);
        g2.setFont(fBarras);
        Rectangle2D barra=new Rectangle2D.Double(x,d.height-alto,paso,alto);
        //g2.fill(barra);
        x+=paso;
        g2.draw(barra);
        g2.rotate(-Math.PI/2);
        g2.setColor(Color.BLACK);
        g2.drawString(datos[i].titulo,(float)alto,(float)paso)

This method must draw a rectangle and a text over the rectangle, but when i run this method all the graphic is rotated and i just want rotate the text ..

Thanks :)

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Rafael Carrillo
  • 2,772
  • 9
  • 43
  • 64

4 Answers4

32

This method will rotate the text and will render all other shapes the same.

Graphics2D g2 = (Graphics2D) g;
Font font = new Font(null, Font.PLAIN, 10);    
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(45), 0, 0);
Font rotatedFont = font.deriveFont(affineTransform);
g2.setFont(rotatedFont);
g2.drawString("A String",0,0);
g2.dispose();
Titus
  • 22,031
  • 1
  • 23
  • 33
  • This is what I want! For my case, I want to flip the text vertically and this is what I did: Font oldFont = g2.getFont(); Font newFont = oldFont.deriveFont(AffineTransform.getScaleInstance(1, -1)); g2.setFont(newFont); – Programus Feb 28 '19 at 03:26
31

The method Graphics2D.rotate applies transform to all subsequent rendering operations. You can preserve a copy of transform (with getTransform()) before applying rotation, and then restore the original.

g2.draw(barra);
AffineTransform orig = g2.getTransform();
g2.rotate(-Math.PI/2);
g2.setColor(Color.BLACK);
g2.drawString(datos[i].titulo,(float)alto,(float)paso);
g2.setTransform(orig);
lxbndr
  • 2,159
  • 1
  • 15
  • 17
  • So it rotates the string but not the coordinate system? – qed Nov 02 '13 at 22:47
  • It modifies current [`transform`](http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html#getTransform()) of rendering context. [`Graphics2D`](http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html) reference states that the transform is used to convert from User Space coordinate system to Device Space. So, it rotates coordinate system:) The last line of this example is restoring transform after string rendering. – lxbndr Nov 04 '13 at 08:44
  • Right! This method rotates the whole coordinate system, this X and Y of the drawString are also meant in the rotated coordinate system. So you are likely drawString in a translated coordinate system to a 0, 0 position instead. – Balazs Kelemen Oct 06 '20 at 09:48
23

This code is better and if you don't want to use AffineTransform.

public static void drawRotate(Graphics2D g2d, double x, double y, int angle, String text) 
{    
    g2d.translate((float)x,(float)y);
    g2d.rotate(Math.toRadians(angle));
    g2d.drawString(text,0,0);
    g2d.rotate(-Math.toRadians(angle));
    g2d.translate(-(float)x,-(float)y);
}    

Usage:

drawRotate(g2d, 100, 100, 45, "hello world");    // 100x100px, 45 degree, 
Danon
  • 2,771
  • 27
  • 37
  • 4
    This should be the accepted answer because it is simpler and thus applies to a broader range of situations. +1. – CodeMed Apr 01 '15 at 19:14
3

I have a piece of code with the following in that I have added to include Rectangle object. I can see my text is rotating, not the rectangle.

Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

String s = "dasdasdasd1";

Font font = new Font("Courier", Font.PLAIN, 12);
g2d.translate(20, 20);

FontRenderContext frc = g2d.getFontRenderContext();

GlyphVector gv = font.createGlyphVector(frc, s);
int length = gv.getNumGlyphs();
Rectangle2D barra=new Rectangle2D.Double(0, 0, 700, 500);
g2d.draw(barra);
for (int i = 0; i < length; i++) {
  Point2D p = gv.getGlyphPosition(i);
  AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY());
  at.rotate((double) i / (double) (length - 1) * Math.PI / 3);

  Shape glyph = gv.getGlyphOutline(i);
  Shape transformedGlyph = at.createTransformedShape(glyph);
  g2d.fill(transformedGlyph);
}

May be you can try with this.

UVM
  • 9,776
  • 6
  • 41
  • 66