1
6 import javax.swing.*;
7 import java.awt.geom.*;
8 import java.awt.event.*;
9 import java.awt.*;
10
11 public class Rose extends JComponent {
12
13 public double theta = 0;
14
15 double grabtheta = 0;
16 double oldtheta = 0;
17
18 Scaleable target;
19
20 public static int size = 80;
21
22 int xoff=size/2;
23 int yoff=size/2;
24 int r=size/2;
25
26 public Rose(Scaleable target) {
27 super();
28 this.target = target;
29 enableEvents(AWTEvent.MOUSE_EVENT_MASK|AWTEvent.MOUSE_MOTION_EVENT_MASK|
30 AWTEvent.COMPONENT_EVENT_MASK);
31 setSize(size,size);
32 setPreferredSize(new Dimension(xoff+r,yoff+r));
33 setMinimumSize(new Dimension(xoff+r,yoff+r));
34 setMaximumSize(new Dimension(xoff+r,yoff+r));
35 }
36
37 double getTheta(Point p) {
38 return(-Math.atan2(p.getX()-xoff,p.getY()-yoff));
39 }
40
41 protected void processComponentEvent(ComponentEvent e) {
42 super.processComponentEvent(e);
43 if (e.getID()==ComponentEvent.COMPONENT_RESIZED) {
44 Dimension s = getSize();
45 if (s.width<s.height) r = s.width/2-1;
46 else r = s.height/2-1;
47 xoff = s.width/2;
48 yoff = s.height/2;
49 repaint();
50 }
51 }
52
53 protected void processMouseEvent(MouseEvent e) {
54 super.processMouseEvent(e);
55 if ((e.getModifiers()&InputEvent.BUTTON3_MASK) !=0) {
56 if (e.getID()==MouseEvent.MOUSE_PRESSED) {
57 javax.swing.Box box = new javax.swing.Box(BoxLayout.X_AXIS);
58 box.add(new JLabel("rotation angle:"));
59 JTextField text = new JTextField(""+(theta*180/Math.PI));
60 oldtheta = theta;
61 text.setColumns(30);
62 box.add(text);
63 int res = JOptionPane.showConfirmDialog(null,box,"Angle setting",
64 JOptionPane.YES_NO_OPTION);
65 if (res == JOptionPane.YES_OPTION) {
66 double newtheta = Math.PI*Double.parseDouble(text.getText())/180;
67 change(newtheta);
68 }
69 }
70 } else {
71 if (e.getID()==MouseEvent.MOUSE_PRESSED) {
72 grabtheta = getTheta(e.getPoint());
73 oldtheta = theta;
74 }
75 if (e.getID()==MouseEvent.MOUSE_RELEASED) {
76 if (theta!=oldtheta) {
77 target.setRotation(theta);
78 }
79 }
80 }
81 }
82
83 public void change(double newtheta) {
84 if (newtheta!=theta) {
85 theta=oldtheta=newtheta;
86 target.setRotation(theta);
87 repaint();
88 }
89 }
90
91 protected void processMouseMotionEvent(MouseEvent e) {
92 super.processMouseMotionEvent(e);
93 if (e.getID()==MouseEvent.MOUSE_DRAGGED) {
94 double newtheta = getTheta(e.getPoint());
95 theta = (theta+newtheta-grabtheta+4*Math.PI)%(Math.PI*2);
96 grabtheta = newtheta;
97 repaint();
98 }
99 }
100
101 static double tick = 0.2;
102
103 public void paint(Graphics g) {
104 Graphics2D gr = (Graphics2D)g;
105 Dimension s = getSize();
106
107 AffineTransform temp =gr.getTransform();
108 temp.concatenate(AffineTransform.getRotateInstance(theta,xoff,yoff));
109 gr.setTransform(temp);
110
111 gr.drawOval(xoff-r,yoff-r,2*r,2*r);
112 gr.drawLine(xoff,yoff-r,xoff,yoff+r-(int)(tick*r));
113
114 gr.drawLine(xoff,yoff-r,xoff-(int)(tick*r),yoff-r+(int)(tick*r));
115 gr.drawLine(xoff,yoff-r,xoff+(int)(tick*r),yoff-r+(int)(tick*r));
116
117 gr.drawLine(xoff,yoff+r-(int)(tick*r),xoff-(int)(tick*r),yoff+r);
118 gr.drawLine(xoff,yoff+r-(int)(tick*r),xoff+(int)(tick*r),yoff+r);
119 }
120 }
121