943,769 Members | Top Members by Rank

Ad:
  • Java Discussion Thread
  • Marked Solved
  • Views: 5853
  • Java RSS
You are currently viewing page 2 of this multi-page discussion thread; Jump to the first page
Aug 23rd, 2008
0

Re: Trying to draw text at an angle

Click to Expand / Collapse  Quote originally posted by sciwizeh ...
yes, the blurry text is because of int rounding error. a better way to do it would be affinetransform, but i haven't used it much, and the sun tutorial confused me a bit, i think that this may also help.
Great. Thank you. I will check those links out.
Featured Poster
Reputation Points: 2614
Solved Threads: 687
Posting Expert
VernonDozier is offline Offline
5,373 posts
since Jan 2008
Aug 25th, 2008
0

Re: Trying to draw text at an angle

You have made this a bit more complex than need be. For simple transformations, the Graphics2D methods rotate() and translate() will suffice (they additively modify the current AffineTransform of the graphics context) without any need to obtain or work with an AffineTransform object directly.

I wrote this small example that might help
java Syntax (Toggle Plain Text)
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.EventQueue;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import javax.swing.JFrame;
  8. import javax.swing.JPanel;
  9.  
  10. public class TextExample extends JFrame {
  11.  
  12. GraphicPanel gPanel;
  13.  
  14. public TextExample() {
  15. setDefaultCloseOperation(EXIT_ON_CLOSE);
  16. setLayout(new BorderLayout());
  17. gPanel = new GraphicPanel();
  18. getContentPane().add(gPanel, BorderLayout.CENTER);
  19. setBounds(100, 100, 200, 200);
  20. setVisible(true);
  21. }
  22.  
  23. class GraphicPanel extends JPanel {
  24. protected void paintComponent(Graphics g) {
  25. Graphics2D g2 = (Graphics2D)g;
  26. g2.setBackground(Color.BLACK);
  27. g2.clearRect(0, 0, getWidth(), getHeight());
  28. g2.setColor(Color.WHITE);
  29. String msg = "Hi Vernon";
  30. FontMetrics metrics = g2.getFontMetrics();
  31. // translate context to center of panel
  32. // the point 0,0 now resides here
  33. g2.translate(getWidth() / 2, getHeight() / 2);
  34. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  35. metrics.getMaxAscent() / 2);
  36. // rotate 45 deg
  37. g2.rotate(-Math.PI / 4);
  38. g2.setColor(Color.YELLOW);
  39. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  40. metrics.getMaxAscent() / 2);
  41. // rotate 45 deg again - these transforms are additive
  42. g2.rotate(-Math.PI / 4);
  43. g2.setColor(Color.ORANGE);
  44. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  45. metrics.getMaxAscent() / 2);
  46. }
  47. }
  48.  
  49. public static void main(String... args) {
  50. EventQueue.invokeLater(new Runnable() {
  51. public void run() {
  52. new TextExample();
  53. }
  54. });
  55. }
  56. }
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 838
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
Aug 25th, 2008
0

Re: Trying to draw text at an angle

Click to Expand / Collapse  Quote originally posted by Ezzaral ...
You have made this a bit more complex than need be. For simple transformations, the Graphics2D methods rotate() and translate() will suffice (they additively modify the current AffineTransform of the graphics context) without any need to obtain or work with an AffineTransform object directly.

I wrote this small example that might help
java Syntax (Toggle Plain Text)
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.EventQueue;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import javax.swing.JFrame;
  8. import javax.swing.JPanel;
  9.  
  10. public class TextExample extends JFrame {
  11.  
  12. GraphicPanel gPanel;
  13.  
  14. public TextExample() {
  15. setDefaultCloseOperation(EXIT_ON_CLOSE);
  16. setLayout(new BorderLayout());
  17. gPanel = new GraphicPanel();
  18. getContentPane().add(gPanel, BorderLayout.CENTER);
  19. setBounds(100, 100, 200, 200);
  20. setVisible(true);
  21. }
  22.  
  23. class GraphicPanel extends JPanel {
  24. protected void paintComponent(Graphics g) {
  25. Graphics2D g2 = (Graphics2D)g;
  26. g2.setBackground(Color.BLACK);
  27. g2.clearRect(0, 0, getWidth(), getHeight());
  28. g2.setColor(Color.WHITE);
  29. String msg = "Hi Vernon";
  30. FontMetrics metrics = g2.getFontMetrics();
  31. // translate context to center of panel
  32. // the point 0,0 now resides here
  33. g2.translate(getWidth() / 2, getHeight() / 2);
  34. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  35. metrics.getMaxAscent() / 2);
  36. // rotate 45 deg
  37. g2.rotate(-Math.PI / 4);
  38. g2.setColor(Color.YELLOW);
  39. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  40. metrics.getMaxAscent() / 2);
  41. // rotate 45 deg again - these transforms are additive
  42. g2.rotate(-Math.PI / 4);
  43. g2.setColor(Color.ORANGE);
  44. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  45. metrics.getMaxAscent() / 2);
  46. }
  47. }
  48.  
  49. public static void main(String... args) {
  50. EventQueue.invokeLater(new Runnable() {
  51. public void run() {
  52. new TextExample();
  53. }
  54. });
  55. }
  56. }
Thank you. I will try that out. I sort of stumbled onto the knowledge that it wasn't nearly as difficult as I thought when I spent about two and a half hours going through the Java tutorial. I kept deleting things from their code till I got to the bare minimum, then finally realized that the bare minimum was only a couple of lines. But it took a while for me to keep deleting stuff from Sun's super cool example till I got to the part of it that I cared about. Thanks.
Featured Poster
Reputation Points: 2614
Solved Threads: 687
Posting Expert
VernonDozier is offline Offline
5,373 posts
since Jan 2008
Aug 26th, 2008
2

Re: Trying to draw text at an angle

Yes, some of their examples can be more complex than need be and obscure the usage they are trying to demonstrate.

One more thing worth noting with respect to AffineTransforms is that they represent the current state of the coordinate system within the graphics context. Since you can store references to as many AffineTransforms as you want, you can effectively "save" any state (translation, orientation, scale, and sheer) you wish and restore it at will. If you have many objects that render themselves independently, each can maintain it's own transform that it uses for rendering. When that object's turn to be rendered comes, you can save the current transform of your graphics context, apply that object's transform, render it, and then restore the original transform.

Here's an example of that:
java Syntax (Toggle Plain Text)
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.EventQueue;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.Point;
  8. import java.awt.geom.AffineTransform;
  9. import javax.swing.JFrame;
  10. import javax.swing.JPanel;
  11.  
  12. public class TransformExample extends JFrame {
  13.  
  14. GraphicPanel gPanel;
  15.  
  16. public TransformExample() {
  17. setDefaultCloseOperation(EXIT_ON_CLOSE);
  18. gPanel = new GraphicPanel();
  19. getContentPane().add(gPanel);
  20. setBounds(100, 100, 200, 200);
  21. setVisible(true);
  22. }
  23.  
  24. class GraphicPanel extends JPanel {
  25. TextLabel label1;
  26. TextLabel label2;
  27. TextLabel label3;
  28.  
  29. protected void paintComponent(Graphics g) {
  30. if (label1 == null) {
  31. // lazy initilization so I have dimensions to work with
  32. FontMetrics fm = g.getFontMetrics();
  33. int width = getWidth();
  34. int height = getHeight();
  35.  
  36. label1 = new TextLabel("Hi Vernon", Color.YELLOW,
  37. 20, height/2, -Math.PI/2);
  38.  
  39. String labelText = "I'm over here";
  40. int labelLen = fm.stringWidth(labelText);
  41. label2 = new TextLabel(labelText, Color.CYAN,
  42. width-labelLen, height/2, -Math.PI/4);
  43.  
  44. labelText = "Standing on my head";
  45. labelLen = fm.stringWidth(labelText);
  46. label3 = new TextLabel(labelText, Color.ORANGE,
  47. (width+labelLen)/2, height-20, Math.PI);
  48. }
  49.  
  50. Graphics2D g2 = (Graphics2D)g;
  51. g2.setBackground(Color.BLACK);
  52. g2.clearRect(0, 0, getWidth(), getHeight());
  53.  
  54. label1.draw(g2);
  55. label2.draw(g2);
  56. label3.draw(g2);
  57. }
  58. }
  59.  
  60. class TextLabel {
  61. private AffineTransform transform;
  62. private Point location;
  63. private double rotation;
  64. private String text;
  65. private Color color;
  66.  
  67. public TextLabel(String text, Color color, int x, int y,
  68. double rotation) {
  69.  
  70. this.text = text;
  71. this.color = color;
  72. this.location = new Point(x, y);
  73. this.rotation = rotation;
  74. transform = new AffineTransform();
  75. transform.translate(location.x, location.y);
  76. transform.rotate(rotation);
  77. }
  78.  
  79. public void draw(Graphics2D g){
  80. // save current color and transform
  81. AffineTransform currentTransform = g.getTransform();
  82. Color currentColor = g.getColor();
  83.  
  84. // apply my own color and transform
  85. g.setTransform(transform);
  86. g.setColor(color);
  87. // this will be left aligned at the origin
  88. // a parameter for left/center/right alignment
  89. // could be added easily
  90. g.drawString(text, 0, 0);
  91.  
  92. // restore the original state
  93. g.setColor(currentColor);
  94. g.setTransform(currentTransform);
  95. }
  96. }
  97.  
  98. public static void main(String... args) {
  99. EventQueue.invokeLater(new Runnable() {
  100. public void run() {
  101. new TransformExample();
  102. }
  103. });
  104. }
  105. }
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 838
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
Aug 26th, 2008
0

Re: Trying to draw text at an angle

Click to Expand / Collapse  Quote originally posted by Ezzaral ...
Yes, some of their examples can be more complex than need be and obscure the usage they are trying to demonstrate.

One more thing worth noting with respect to AffineTransforms is that they represent the current state of the coordinate system within the graphics context. Since you can store references to as many AffineTransforms as you want, you can effectively "save" any state (translation, orientation, scale, and sheer) you wish and restore it at will. If you have many objects that render themselves independently, each can maintain it's own transform that it uses for rendering. When that object's turn to be rendered comes, you can save the current transform of your graphics context, apply that object's transform, render it, and then restore the original transform.

Here's an example of that:

Perfect! My project is a type of ColorForms/CAD program where the user can draw pentagons, ovals, rectangles, text, etc., on the screen and they can all be different sizes and different angles and I'm going to try to give the option where a user can spin one shape and/or piece of text and leave the others the same or spin them all or spin some but not others or change one or more sizes, etc. Potentially you could have hundreds or even thousands of objects on the screen, all with different sizes and different angles. To rotate a polygon, I was doing the math and changing the polygon coordinates myself, but the idea of keeping the same points and having a different AffineTransformation for each of them is very appealing and seems like less calculation for me. Plus the goal is to be able to tilt images too eventually. This method has fantastic potential compared to my earlier approach. Thanks again. As usual, you gave great sample code.
Last edited by VernonDozier; Aug 26th, 2008 at 9:29 pm.
Featured Poster
Reputation Points: 2614
Solved Threads: 687
Posting Expert
VernonDozier is offline Offline
5,373 posts
since Jan 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Java Forum Timeline: Clean up my code
Next Thread in Java Forum Timeline: Socket problems





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC