View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components.gauger;
21  
22  import java.awt.BasicStroke;
23  import java.awt.Color;
24  import java.awt.Graphics2D;
25  import java.awt.Point;
26  import java.awt.Rectangle;
27  import java.awt.geom.Line2D;
28  
29  import com.cosylab.gui.components.Gauger;
30  
31  
32  /**
33   * Component defining and rendering the needle.
34   *
35   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
36   * @version $id$
37   */
38  public class ThinNeedle implements ActiveElement
39  {
40  	/* Scale appearance */
41  
42  	/** Relative length of needle as fraction of scale space height */
43  	private final static double RELATIVE_NEEDLE_SIZE = 0.6;
44  	private Gauger gauger;
45  	private boolean changeSignificant;
46  	private Point p;
47  	private double angle;
48  	private Rectangle bounds = new Rectangle(0, 0, 0, 0);
49  	private double currentPosition = 0.5;
50  	protected ScaleTransform transform = null;
51  	//private Line poly = new Polygon(new int[3], new int[3], 3);
52  	
53  	private Point p1 = new Point(0, 0);
54  	private Point p2 = new Point(0, 0);
55  	
56  	private Line2D line = new Line2D.Double();
57  
58  	/**
59  	 * Needle constructor comment.
60  	 *
61  	 * @param gauger on which the needle will be rendered.
62  	 */
63  	public ThinNeedle(Gauger gauger)
64  	{
65  		p = new Point();
66  		angle = 0;
67  		this.gauger = gauger;
68  		changeSignificant = true;
69  	}
70  
71  	/**
72  	 * Updates the polygon representation of the needle.
73  	 */
74  	protected synchronized void calculatePolygon()
75  	{
76  		double sin = Math.sin(angle-Math.PI/2.0);
77  		double cos = Math.cos(angle-Math.PI/2.0);
78  
79  		double x1 = (int)(p1.x * sin - p1.y * cos + p.x);
80  		double y1 = (int)(p1.x * cos + p1.y * sin + p.y);
81  
82  		double x2 = (int)(p2.x * sin - p2.y * cos + p.x);
83  		double y2 = (int)(p2.x * cos + p2.y * sin + p.y);
84  		
85  		line.setLine(x1, y1, x2, y2);
86  		
87  		bounds = line.getBounds();
88  		bounds.grow(3, 3);
89  	}
90  
91  	private synchronized final void invalidate()
92  	{
93  		double size = transform.scaleHeight(0.5) * RELATIVE_NEEDLE_SIZE;
94  		p2.x = 0;
95  		p2.y = (int)size;
96  	}
97  
98  	/**
99  	 * Returns bounding rectangle of needle.
100 	 *
101 	 * @return Bounding rectangle of needle.
102 	 */
103 	public Rectangle getBounds()
104 	{
105 		return bounds;
106 	}
107 
108 	/**
109 	 * Returns true if needle has moved enough to require immediate redraw.
110 	 *
111 	 * @return True if needle should be redrawn immediatelly.
112 	 */
113 	public boolean isChangeSignificant()
114 	{
115 		return changeSignificant;
116 	}
117 
118 	protected void updatePosition(double x)
119 	{
120 		if((transform != null)) {
121 			transform.mapUVtoXY(x, 0, p);
122 			angle = transform.getAngle(x);
123 			calculatePolygon();
124 		}
125 	}
126 
127 	/**
128 	 * Sets position of needle in scale space coordinates. Value is relative
129 	 * position between 0.0 and 1.0 inclusively.
130 	 *
131 	 * @param proportionalPosition New position of needle.
132 	 */
133 	public void setPosition(double proportionalPosition)
134 	{
135 		updatePosition(proportionalPosition);
136 
137 		if(changeSignificant) {
138 			currentPosition = proportionalPosition;
139 		}
140 	}
141 
142 	/**
143 	 * Renders needle.
144 	 *
145 	 * @see ActiveElement#render(Graphics2D)
146 	 */
147 	public synchronized void render(Graphics2D g)
148 	{
149 		g.setColor(gauger.getNeedleColor());
150 
151 		g.setColor(Color.BLACK);
152 		BasicStroke bs = new BasicStroke(2.0f);
153 		g.setStroke(bs);
154 		g.draw(line);
155 
156 	}
157 
158 	/**
159 	 * Sets transform defining the gauger. This transform is used to render the
160 	 * needle at appropriate position and angle.
161 	 *
162 	 * @see ActiveElement#setTransform(ScaleTransform)
163 	 */
164 	public void setTransform(ScaleTransform transform)
165 	{
166 		this.transform = transform;
167 		invalidate();
168 		updatePosition(currentPosition);
169 	}
170 }
171 
172 /* __oOo__ */