Having problems rotating Shapes in JPanel

Please support our Java advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Jan 2008
Posts: 3,840
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Having problems rotating Shapes in JPanel

 
0
  #1
Sep 13th, 2008
This is a simplified version of a larger project. I have three JPanels contained in a larger JSplitPane called wholePanel . The top panel and left panel hold labels and buttons, which I have not included here. The lower right panel, called canvasPanel , is where I draw shapes. I'm trying to tilt an oval at an angle and I am successful at doing so. However, a problem occurs when I resize canvasPanel . The oval will jump if you drag the Pane dividers to resize. I believe that what is occurring is that the oval is realigning itself sometimes with respect to the upper left corner of wholePanel and sometimes with respect to the upper left of canvasPanel. So it has an annoying jump. I want it to always align itself with respect to canvasPanel , not wholePanel . This seems to happen because of the AffineTransform, but I don't know why or how to fix it.

My second problem is that sometimes canvasPanel does not paint until I resize it, leaving a dull gray panel with no background color and no shape. I want it to paint without the user having to do anything. Thank you. Code is below.

  1. package ColorForms;
  2.  
  3. import javax.swing.border.*;
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.awt.geom.*;
  7. import java.io.*;
  8. import javax.swing.*;
  9. import java.util.*;
  10. import java.lang.*;
  11.  
  12.  
  13.  
  14. public class ColorForms extends JFrame
  15. {
  16. LeftPanel leftPanel;
  17. TopPanel topPanel;
  18. CanvasPanel canvasPanel;
  19. JSplitPane wholePanel, bottomPanel;
  20.  
  21. public static void main (String args[])
  22. {
  23. ColorForms cf = new ColorForms ();
  24. }
  25.  
  26.  
  27. public ColorForms ()
  28. {
  29. this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
  30. this.setSize (400, 400);
  31. this.setVisible (true);
  32.  
  33. leftPanel = new LeftPanel ();
  34. topPanel = new TopPanel ();
  35. canvasPanel = new CanvasPanel ();
  36.  
  37. bottomPanel = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, leftPanel, canvasPanel);
  38. bottomPanel.setDividerLocation (50);
  39. wholePanel = new JSplitPane (JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel);
  40. wholePanel.setDividerLocation (70);
  41.  
  42. this.getContentPane ().add (wholePanel);
  43. }
  44. }
  45.  
  46.  
  47. class LeftPanel extends JPanel
  48. {
  49. public LeftPanel ()
  50. {
  51. }
  52. }
  53.  
  54.  
  55. class TopPanel extends JPanel
  56. {
  57. public TopPanel ()
  58. {
  59.  
  60. }
  61. }
  62.  
  63.  
  64. class CanvasPanel extends JPanel
  65. {
  66. public CanvasPanel ()
  67. {
  68. }
  69.  
  70.  
  71. public void paintComponent (Graphics g)
  72. {
  73. System.out.println ("I am in CanvasPanel repaint.");
  74.  
  75. int ovalCenterX = 100;
  76. int ovalCenterY = 100;
  77. int ovalWidth = 200;
  78. int ovalHeight = 100;
  79. int ovalUpperLeftX = ovalCenterX - ovalWidth / 2;
  80. int ovalUpperLeftY = ovalCenterY - ovalHeight / 2;
  81. double angle = 0.5;
  82.  
  83. super.paintComponent (g);
  84. Graphics2D g2 = (Graphics2D) g;
  85. g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  86. setBackground(Color.GREEN);
  87.  
  88. AffineTransform orig = g2.getTransform();
  89. AffineTransform af = new AffineTransform ();
  90. af.rotate(angle, ovalCenterX, ovalCenterY);
  91. g2.setTransform(af);
  92. g2.setColor (Color.BLACK);
  93. g2.fillOval (ovalUpperLeftX, ovalUpperLeftY, ovalWidth, ovalHeight);
  94. g2.setTransform(orig);
  95. }
  96. }
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 973
Reputation: Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough Alex Edwards is a jewel in the rough 
Solved Threads: 107
Alex Edwards's Avatar
Alex Edwards Alex Edwards is offline Offline
Posting Shark

Re: Having problems rotating Shapes in JPanel

 
0
  #2
Sep 13th, 2008
After running some tests I realized that somehow your transform is jumping between 1-22 on the (result?) matrice--

  1. import javax.swing.border.*;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import java.awt.geom.*;
  5. import java.io.*;
  6. import javax.swing.*;
  7. import java.util.*;
  8. import java.lang.*;
  9.  
  10.  
  11.  
  12. public class ColorForms extends JFrame
  13. {
  14. LeftPanel leftPanel;
  15. TopPanel topPanel;
  16. CanvasPanel canvasPanel;
  17. JSplitPane wholePanel, bottomPanel;
  18.  
  19. public static void main (String args[])
  20. {
  21. ColorForms cf = new ColorForms ();
  22. }
  23.  
  24.  
  25. public ColorForms ()
  26. {
  27. this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
  28. this.setSize (400, 400);
  29. this.setVisible (true);
  30.  
  31. leftPanel = new LeftPanel ();
  32. topPanel = new TopPanel ();
  33. canvasPanel = new CanvasPanel ();
  34.  
  35. bottomPanel = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, leftPanel, canvasPanel);
  36. bottomPanel.setDividerLocation (50);
  37. wholePanel = new JSplitPane (JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel);
  38. wholePanel.setDividerLocation (70);
  39.  
  40. this.getContentPane ().add (wholePanel);
  41. }
  42. }
  43.  
  44.  
  45. class LeftPanel extends JPanel
  46. {
  47. public LeftPanel ()
  48. {
  49. }
  50. }
  51.  
  52.  
  53. class TopPanel extends JPanel
  54. {
  55. public TopPanel ()
  56. {
  57.  
  58. }
  59. }
  60.  
  61.  
  62. class CanvasPanel extends JPanel
  63. {
  64. public CanvasPanel ()
  65. {
  66. }
  67.  
  68.  
  69. public void paintComponent (Graphics g)
  70. {
  71. System.out.println (((Graphics2D)g).getTransform());
  72.  
  73. int ovalCenterX = 100;
  74. int ovalCenterY = 100;
  75. int ovalWidth = 200;
  76. int ovalHeight = 100;
  77. int ovalUpperLeftX = ovalCenterX - ovalWidth / 2;
  78. int ovalUpperLeftY = ovalCenterY - ovalHeight / 2;
  79. double angle = 0.5;
  80.  
  81. super.paintComponent (g);
  82. Graphics2D g2 = (Graphics2D) g;
  83. g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  84. setBackground(Color.GREEN);
  85.  
  86. AffineTransform orig = g2.getTransform();
  87. AffineTransform af = new AffineTransform ();
  88. af.rotate(angle, ovalCenterX, ovalCenterY);
  89. g2.setTransform(af);
  90. g2.setColor (Color.BLACK);
  91. g2.fillOval (ovalUpperLeftX, ovalUpperLeftY, ovalWidth, ovalHeight);
  92. g2.setTransform(orig);
  93. // g2.setTransform(af);
  94. }
  95. }

-but I can't say much else with my lack of knowledge in transformations =/
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,840
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Having problems rotating Shapes in JPanel

 
0
  #3
Sep 13th, 2008
Alex, thanks for looking at it. I'm a little confused about what you meant with this line:

After running some tests I realized that somehow your transform is jumping between 1-22 on the (result?) matrice--
I put in some debugging output and the matrix values are staying the same for me. Maybe we aren't talking about the same thing.

I added a button which causes a repaint to see what that did and the results are interesting. Click the button and the oval appears to draw where I want it to. Drag the PANE resize bars and the oval jumps. It really looks like it is drawing at the proper (x,y) coordinates, but that it's baseline (0, 0) coordinate is changing from the upper left of canvasPanel to the upper left of another panel/pane, but again I don't know why or what to do about it. Here's the updated code with the button.

  1. package ColorForms;
  2.  
  3. import javax.swing.border.*;
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.awt.geom.*;
  7. import java.io.*;
  8. import javax.swing.*;
  9. import java.util.*;
  10. import java.lang.*;
  11.  
  12.  
  13. public class ColorForms extends JFrame
  14. {
  15. LeftPanel leftPanel;
  16. TopPanel topPanel;
  17. CanvasPanel canvasPanel;
  18. JSplitPane wholePanel, bottomPanel;
  19.  
  20. public static void main (String args[])
  21. {
  22. ColorForms cf = new ColorForms ();
  23. }
  24.  
  25.  
  26. public ColorForms ()
  27. {
  28. this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
  29. this.setSize (400, 400);
  30. this.setVisible (true);
  31.  
  32. leftPanel = new LeftPanel ();
  33. topPanel = new TopPanel (this);
  34. canvasPanel = new CanvasPanel ();
  35.  
  36. bottomPanel = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, leftPanel, canvasPanel);
  37. bottomPanel.setDividerLocation (50);
  38. wholePanel = new JSplitPane (JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel);
  39. wholePanel.setDividerLocation (70);
  40.  
  41. this.getContentPane ().add (wholePanel);
  42. }
  43. }
  44.  
  45.  
  46. class LeftPanel extends JPanel
  47. {
  48. public LeftPanel ()
  49. {
  50. }
  51. }
  52.  
  53.  
  54. class TopPanel extends JPanel implements ActionListener
  55. {
  56. JButton repaintButton;
  57. ColorForms cf;
  58.  
  59. public TopPanel (ColorForms cForm)
  60. {
  61. cf = cForm;
  62. repaintButton = new JButton ("Repaint");
  63. repaintButton.addActionListener(this);
  64. add (repaintButton);
  65. }
  66.  
  67. public void actionPerformed(ActionEvent e)
  68. {
  69. cf.canvasPanel.repaint ();
  70. }
  71. }
  72.  
  73.  
  74. class CanvasPanel extends JPanel
  75. {
  76. int timesPainted = 0;
  77.  
  78. public CanvasPanel ()
  79. {
  80. }
  81.  
  82.  
  83. public void paintComponent (Graphics g)
  84. {
  85. timesPainted++;
  86. System.out.print ("I am in CanvasPanel repaint. # of times painted = ");
  87. System.out.println (timesPainted);
  88.  
  89. int ovalCenterX = 100;
  90. int ovalCenterY = 100;
  91. int ovalWidth = 200;
  92. int ovalHeight = 100;
  93. int ovalUpperLeftX = ovalCenterX - ovalWidth / 2;
  94. int ovalUpperLeftY = ovalCenterY - ovalHeight / 2;
  95. double angle = 0.5;
  96.  
  97. super.paintComponent (g);
  98. Graphics2D g2 = (Graphics2D) g;
  99. g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  100. setBackground(Color.GREEN);
  101.  
  102. AffineTransform orig = g2.getTransform();
  103. AffineTransform af = new AffineTransform ();
  104. af.rotate(angle, ovalCenterX, ovalCenterY);
  105. g2.setTransform(af);
  106.  
  107.  
  108. // display AffineTransform attributes
  109. System.out.println (af.getScaleX());
  110. System.out.println (af.getScaleY());
  111. System.out.println (af.getShearX());
  112. System.out.println (af.getShearY());
  113. System.out.println (af.getTranslateX());
  114. System.out.println (af.getTranslateY());
  115.  
  116. g2.setColor (Color.BLACK);
  117. g2.fillOval (ovalUpperLeftX, ovalUpperLeftY, ovalWidth, ovalHeight);
  118. g2.setTransform(orig);
  119. }
  120. }
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,840
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Having problems rotating Shapes in JPanel

 
0
  #4
Sep 14th, 2008
I've been playing around with this. I added MouseListeners to the top panel and the canvas panel. Like the button, if you click on either, it will redraw in the correct place. I also draw a circle on the canvas that doesn't use a transform and it doesn't do that jump. Finally, when I add a ComponentListener (presently commented out) to the canvas panel and have it repaint when the component is resized, I don't need to click a panel or a button, but it jumps back and forth if you drag by the lower right corner. I'd still like to understand what's going on though. Thanks.

  1. package ColorForms;
  2.  
  3. import javax.swing.border.*;
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.awt.geom.*;
  7. import java.io.*;
  8. import javax.swing.*;
  9. import java.util.*;
  10. import java.lang.*;
  11.  
  12.  
  13.  
  14. public class ColorForms extends JFrame // implements ComponentListener
  15. {
  16. LeftPanel leftPanel;
  17. TopPanel topPanel;
  18. CanvasPanel canvasPanel;
  19. JSplitPane wholePanel, bottomPanel;
  20.  
  21. public static void main (String args[])
  22. {
  23. ColorForms cf = new ColorForms ();
  24. }
  25.  
  26.  
  27. public ColorForms ()
  28. {
  29. this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
  30. this.setSize (400, 400);
  31. this.setVisible (true);
  32.  
  33. leftPanel = new LeftPanel ();
  34. topPanel = new TopPanel (this);
  35. canvasPanel = new CanvasPanel ();
  36.  
  37. bottomPanel = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, leftPanel, canvasPanel);
  38. bottomPanel.setDividerLocation (50);
  39. wholePanel = new JSplitPane (JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel);
  40. wholePanel.setDividerLocation (70);
  41.  
  42. // canvasPanel.addComponentListener(this);
  43.  
  44. this.getContentPane ().add (wholePanel);
  45. }
  46. /*
  47.   public void componentResized(ComponentEvent e)
  48.   {
  49.   System.out.println ("Hi there");
  50.   canvasPanel.repaint();
  51.   }
  52.  
  53.   public void componentMoved(ComponentEvent e)
  54.   {
  55.   }
  56.  
  57.   public void componentShown(ComponentEvent e)
  58.   {
  59.   }
  60.  
  61.   public void componentHidden(ComponentEvent e)
  62.   {
  63.   }*/
  64. }
  65.  
  66.  
  67. class LeftPanel extends JPanel
  68. {
  69. public LeftPanel ()
  70. {
  71. }
  72. }
  73.  
  74.  
  75. class TopPanel extends JPanel implements ActionListener, MouseListener
  76. {
  77. JButton repaintButton;
  78. ColorForms cf;
  79.  
  80. public TopPanel (ColorForms cForm)
  81. {
  82. cf = cForm;
  83. repaintButton = new JButton ("Repaint");
  84. repaintButton.addActionListener(this);
  85. add (repaintButton);
  86. this.addMouseListener(this);
  87. }
  88.  
  89. public void actionPerformed(ActionEvent e)
  90. {
  91. cf.canvasPanel.repaint ();
  92. }
  93.  
  94. public void mouseClicked(MouseEvent e)
  95. {
  96. cf.canvasPanel.repaint();
  97. }
  98.  
  99. public void mousePressed(MouseEvent e) {
  100. }
  101.  
  102. public void mouseReleased(MouseEvent e) {
  103. }
  104.  
  105. public void mouseEntered(MouseEvent e) {
  106. }
  107.  
  108. public void mouseExited(MouseEvent e) {
  109. }
  110. }
  111.  
  112.  
  113. class CanvasPanel extends JPanel implements MouseListener
  114. {
  115. int timesPainted = 0;
  116.  
  117. public CanvasPanel ()
  118. {
  119. this.addMouseListener(this);
  120. }
  121.  
  122.  
  123. public void paintComponent (Graphics g)
  124. {
  125. timesPainted++;
  126. System.out.print ("I am in CanvasPanel repaint. # of times painted = ");
  127. System.out.println (timesPainted);
  128.  
  129. int ovalCenterX = 100;
  130. int ovalCenterY = 100;
  131. int ovalWidth = 200;
  132. int ovalHeight = 100;
  133. int ovalUpperLeftX = ovalCenterX - ovalWidth / 2;
  134. int ovalUpperLeftY = ovalCenterY - ovalHeight / 2;
  135. double angle = 0.5;
  136.  
  137. super.paintComponent (g);
  138. Graphics2D g2 = (Graphics2D) g;
  139. g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  140. setBackground(Color.GREEN);
  141.  
  142. AffineTransform orig = g2.getTransform();
  143. AffineTransform af = new AffineTransform ();
  144. af.rotate(angle, ovalCenterX, ovalCenterY);
  145. g2.setTransform(af);
  146.  
  147. g2.setColor (Color.BLACK);
  148. g2.fillOval (ovalUpperLeftX, ovalUpperLeftY, ovalWidth, ovalHeight);
  149. g2.setTransform(orig);
  150. g2.setColor (Color.MAGENTA);
  151. g2.fillOval (250, 100, 50, 50);
  152. }
  153.  
  154. public void mouseClicked(MouseEvent e)
  155. {
  156. repaint ();
  157. }
  158.  
  159. public void mousePressed(MouseEvent e)
  160. {
  161. }
  162.  
  163. public void mouseReleased(MouseEvent e)
  164. {
  165. }
  166.  
  167. public void mouseEntered(MouseEvent e)
  168. {
  169. }
  170.  
  171. public void mouseExited(MouseEvent e)
  172. {
  173. }
  174. }
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 4,508
Reputation: Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future 
Solved Threads: 522
Moderator
Featured Poster
Ezzaral's Avatar
Ezzaral Ezzaral is offline Offline
Industrious Poster

Re: Having problems rotating Shapes in JPanel

 
1
  #5
Sep 15th, 2008
The problem is originating with your creation of the affine transform that you are rotating:
  1. AffineTransform af = new AffineTransform ();
If you change that to pass the original transform to the constructor, it works just fine:
  1. AffineTransform af = new AffineTransform (orig);
Without backtracing the stack on every repaint() call, I can't tell you for certain, but I would guess the new transform is getting generated against the frame context when you resize and using the CanvasPanel on the other events. The fact that it's an inner class of another visual component further clouds the issue.

Honestly, you don't need to create a new transform from scratch anyway. Just call rotate directly on the graphics context
  1. g2.rotate(angle, ovalCenterX, ovalCenterY);
and it behaves just fine.

Also, if you move the setVisible() call to the end of the ColorForms constructor, it will paint the components you added properly on construction.
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 4,508
Reputation: Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future Ezzaral has a brilliant future 
Solved Threads: 522
Moderator
Featured Poster
Ezzaral's Avatar
Ezzaral Ezzaral is offline Offline
Industrious Poster

Re: Having problems rotating Shapes in JPanel

 
0
  #6
Sep 15th, 2008
Actually, disregard the comment on the inner class. I just noticed that it is not actually an inner class of ColorForms.

Since the "jumping" occurs on a top-level repaint of the containment heirarchy and CanvasPanel is a component of "bottomPanel", the new transform seems to be created relative to the bottomPanel graphics context when the paintComponent() call comes down from that container. Your other events are calling repaint directly on the CanvasPanel and the transform is fine on those.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,840
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Having problems rotating Shapes in JPanel

 
0
  #7
Sep 15th, 2008
All right! Now we're getting somewhere! Moving the setVisible line solved that half of the problem and using the original transform in the constructor solved the other part, at least for the way I have it now. I'm still playing around with it trying to expand on it to make it fit into my larger program, but I think I'm going to flag this one as solved. Thank you very much Ezzaral!
Reply With Quote Quick reply to this message  
Reply

Tags
graphics, transforms

This thread has been marked solved.
Perhaps start a new thread instead?
Message:




Views: 1746 | Replies: 6
Thread Tools Search this Thread



Tag cloud for graphics, transforms
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC