1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components.gauger;
21
22 import com.cosylab.gui.components.Gauger;
23
24 import java.awt.Color;
25 import java.awt.Graphics2D;
26 import java.awt.Point;
27 import java.awt.Polygon;
28 import java.awt.Rectangle;
29
30
31
32
33
34
35
36
37 public class Needle implements ActiveElement
38 {
39
40
41
42 private final static double RELATIVE_NEEDLE_SIZE = 0.6;
43
44
45
46
47 private static final double DEFAULT_RATIO = 7.0;
48 private Gauger gauger;
49 private boolean changeSignificant;
50 private Point p;
51 private double angle;
52 private Rectangle bounds = new Rectangle(0, 0, 0, 0);
53 private double currentPosition = 0.5;
54 protected ScaleTransform transform = null;
55 private double[] xValues = new double[3];
56 private double[] yValues = new double[3];
57 private Polygon poly = new Polygon(new int[3], new int[3], 3);
58 private boolean outOfBounds=false;
59
60
61
62
63
64
65 public Needle(Gauger gauger)
66 {
67 p = new Point();
68 angle = 0;
69 this.gauger = gauger;
70 changeSignificant = true;
71 }
72
73
74
75
76 protected synchronized void calculatePolygon()
77 {
78 double sin = Math.sin(angle);
79 double cos = Math.cos(angle);
80
81 for(int i = 0; i < xValues.length; i++) {
82 double xi = xValues[i];
83 double yi = yValues[i];
84 poly.xpoints[i] = (int)(xi * sin - yi * cos + p.x);
85 poly.ypoints[i] = (int)(xi * cos + yi * sin + p.y);
86 }
87
88 poly.invalidate();
89
90 bounds = poly.getBounds();
91 bounds.grow(3, 3);
92 }
93
94 private synchronized final void invalidate()
95 {
96 double size = transform.scaleHeight(0.5) * RELATIVE_NEEDLE_SIZE;
97 double s = (size / DEFAULT_RATIO);
98 yValues[0] = -s;
99 xValues[0] = 0;
100
101 yValues[1] = 0;
102 xValues[1] = -size;
103
104 yValues[2] = s;
105 xValues[2] = 0;
106 }
107
108
109
110
111
112
113 public Rectangle getBounds()
114 {
115 return bounds;
116 }
117
118
119
120
121
122
123 public boolean isChangeSignificant()
124 {
125 return changeSignificant;
126 }
127
128 protected void updatePosition(double x)
129 {
130 if((transform != null)) {
131 changeSignificant = true;
132
133
134 if(changeSignificant) {
135 transform.mapUVtoXY(x, 0, p);
136
137 angle = transform.getAngle(x);
138 calculatePolygon();
139 }
140 }
141 }
142
143
144
145
146
147
148
149 public void setPosition(double proportionalPosition)
150 {
151 updatePosition(proportionalPosition);
152
153 if(changeSignificant) {
154 currentPosition = proportionalPosition;
155 }
156 }
157
158
159
160
161
162
163 public synchronized void render(Graphics2D g)
164 {
165
166 double position = (gauger.getValue()-gauger.getMinimum())/(gauger.getMaximum() - gauger.getMinimum());
167
168 if(outOfBounds == ( (position < 0) || (position>1.0) )) {
169 g.setColor(gauger.getOutOfBoundsColor());
170 } else if( (position <= gauger.getLowAlarmLimit()) || (position>=gauger.getHighAlarmLimit()) ){
171 g.setColor(gauger.getAlarmColor());
172 } else if( (position <= gauger.getLowWarningLimit()) || (position>=gauger.getHighWarningLimit()) ){
173 g.setColor(gauger.getWarningColor());
174 } else{
175 g.setColor(gauger.getNeedleColor());
176 }
177
178 g.fillPolygon(poly);
179 g.drawPolygon(poly);
180
181 g.setColor(Color.BLACK);
182
183 g.drawLine(poly.xpoints[0], poly.ypoints[0], poly.xpoints[1],
184 poly.ypoints[1]);
185 }
186
187
188
189
190
191
192
193 public void setTransform(ScaleTransform transform)
194 {
195 this.transform = transform;
196 invalidate();
197 updatePosition(currentPosition);
198 }
199
200
201
202
203
204
205
206 public boolean isOutOfBounds(){
207 return outOfBounds;
208 }
209 }
210
211