001 /* EVolve - an Extensible Software Visualization Framework
002 * Copyright (C) 2001-2002 Qin Wang
003 *
004 * This library is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Library General Public
006 * License as published by the Free Software Foundation; either
007 * version 2 of the License, or (at your option) any later version.
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Library General Public License for more details.
013 *
014 * You should have received a copy of the GNU Library General Public
015 * License along with this library; if not, write to the
016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017 * Boston, MA 02111-1307, USA.
018 */
019
020 /*
021 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022 */
023
024 package EVolve.visualization;
025
026 import java.awt.*;
027 import java.awt.event.*;
028 import java.awt.geom.*;
029 import java.awt.image.*;
030 import javax.swing.*;
031
032 /**
033 * Panel with two axes.
034 */
035 public class AxesPanel extends JPanel {
036 private String xName, yName; // names of the axes
037 private BufferedImage image; // content
038
039 private double startX, startY, endX, endY; // relative position of the selection box
040 private boolean drawBox; // whether is drawing the box or not
041
042 private boolean drawPointer;
043 private boolean drawAxis;
044 private int xPos, yPos;
045 private int scaleX, scaleY;
046 private int originX,originY;
047
048 /**
049 * Creates an axes panel.
050 */
051 public AxesPanel() {
052 xName = "X-axis";
053 yName = "Y-axis";
054 image = null;
055
056 startX = 0.0;
057 startY = 0.0;
058 endX = 0.0;
059 endY = 0.0;
060 drawBox = false;
061
062 drawPointer = false;
063 drawAxis = true;
064 xPos = 0;
065 yPos = 0;
066 scaleX = 60;
067 scaleY = 60;
068 originX = 20;
069 originY = 20;
070
071 addMouseListener(new MouseAdapter() {
072 public void mousePressed(MouseEvent e) {
073 if (e.getButton() == MouseEvent.BUTTON1) {
074 mPressed(e.getX(), e.getY());
075 }
076 }
077 });
078
079 addMouseListener(new MouseAdapter() {
080 public void mouseReleased(MouseEvent e) {
081 if (e.getButton() == MouseEvent.BUTTON1) {
082 mReleased();
083 }
084 }
085 });
086
087 addMouseMotionListener(new MouseMotionAdapter() {
088 public void mouseDragged(MouseEvent e) {
089 if (drawBox) {
090 mDragged(e.getX(), e.getY());
091 }
092 }
093 });
094 }
095
096 public AxesPanel(boolean showAxis) {
097 this();
098 drawAxis = showAxis;
099 scaleX = 0;
100 scaleY = 0;
101 originX = 0;
102 originY = 0;
103 }
104
105 /**
106 * Mouse pressed.
107 *
108 * @param x position on X-axis
109 * @param y position on Y-axis
110 */
111 private void mPressed(int x, int y) {
112 if (image != null) {
113 int w = getWidth();
114 int h = getHeight();
115 startX = ((double)(x - 20)) / ((double)(w - 60));
116 startY = ((double)(y - 40)) / ((double)(h - 60));
117 endX = ((double)(x - 20)) / ((double)(w - 60));
118 endY = ((double)(y - 40)) / ((double)(h - 60));
119 drawBox = true;
120 repaint();
121 }
122 }
123
124 /**
125 * Mouse released.
126 */
127 private void mReleased() {
128 if (image != null) {
129 drawBox = false;
130 }
131 }
132
133 /**
134 * Mouse dragged.
135 *
136 * @param x position on X-axis
137 * @param y position on Y-axis
138 */
139 private void mDragged(int x, int y) {
140 if (image != null) {
141 int w = getWidth();
142 int h = getHeight();
143 endX = ((double)(x - 20)) / ((double)(w - 60));
144 endY = ((double)(y - 40)) / ((double)(h - 60));
145 repaint();
146 }
147 }
148
149 /**
150 * Sets the names of the axes.
151 *
152 * @param xName name of the X-axis
153 * @param yName name of the Y-axis
154 */
155 public void setName(String xName, String yName) {
156 this.xName = xName;
157 this.yName = yName;
158 }
159
160 /**
161 * Sets the content of the panel.
162 *
163 * @param image content
164 */
165 public void setImage(BufferedImage image) {
166 this.image = image;
167
168 startX = 0.0;
169 startY = 0.0;
170 endX = 0.0;
171 endY = 0.0;
172 drawBox = false;
173 }
174
175 /**
176 * Draws the panel.
177 *
178 * @param g graphics
179 */
180 public void paintComponent(Graphics g) {
181 super.paintComponent(g);
182
183 Graphics2D g2 = (Graphics2D)g;
184
185 int w = getWidth();
186 int h = getHeight();
187
188 if (drawAxis) {
189 g2.setColor(Color.white);
190 g2.fillRect(0, 0, w, h);
191
192 g2.setColor(Color.black);
193 g2.drawLine(20, h - 20, w - 20, h - 20);
194 g2.drawLine(w - 20, h - 20, w - 30, h - 15);
195 g2.drawLine(w - 20, h - 20, w - 30, h - 25);
196 g2.drawLine(20, h - 20, 20, 20);
197 g2.drawLine(20, 20, 15, 30);
198 g2.drawLine(20, 20, 25, 30);
199
200
201 Font font = new Font("Arial", Font.PLAIN, 12);
202 g2.setFont(font);
203 g2.drawString(xName, w - g2.getFontMetrics().stringWidth(xName) - 40, h - 5);
204 g2.rotate(-Math.PI / 2.0);
205 g2.drawString(yName, -40 - g2.getFontMetrics().stringWidth(yName), 15);
206 g2.rotate(Math.PI / 2.0);
207 }
208 if (image != null) {
209 AffineTransform tf = g2.getTransform();
210 g2.translate(originX+1, (h - originY));
211 g2.scale((double)(w - scaleX) / (double)(image.getWidth()), -(double)(h - scaleY) / (double)(image.getHeight()));
212 g2.drawImage(image, 0, 0, null);
213 g2.setTransform(tf);
214
215 g2.setColor(Color.blue);
216 double x1 = (startX < endX) ? startX : endX;
217 double x2 = (startX > endX) ? startX : endX;
218 double y1 = (startY < endY) ? startY : endY;
219 double y2 = (startY > endY) ? startY : endY;
220 g2.drawRect((int)(x1 * ((double)(w - scaleX))) + 20, (int)(y1 * ((double)(h - scaleY))) + 40, (int)((x2 - x1) * ((double)(w - scaleX))), (int)((y2 - y1) * ((double)(h - scaleY))));
221 }
222 if (drawPointer) {
223 g2.setColor(Color.black);
224 g2.drawLine(xPos,yPos,xPos+20,yPos+20);
225 g2.drawLine(xPos,yPos,xPos+10,yPos+5);
226 g2.drawLine(xPos,yPos,xPos+5,yPos+10);
227 }
228
229 }
230
231 /**
232 * Gets the X-axis value of the image.
233 *
234 * @param x X-axis value of the panel
235 * @return X-axis value of the image
236 */
237 public int getImageX(int x) {
238 int w = getWidth();
239 if ((image == null)||(w-scaleX==0)) {
240 return -1;
241 } else {
242 return (x - originX) * image.getWidth() / (w - scaleX);
243 }
244 }
245
246 public double getScreenXDelta(double delta) {
247 int w = getWidth();
248 return (delta*w/image.getWidth());
249 }
250
251 /**
252 * Gets the Y-axis value of the image.
253 *
254 * @param y Y-axis value of the panel
255 * @return Y-axis value of the image
256 */
257 public int getImageY(int y) {
258 int h = getHeight();
259 if ((image == null)||(h-scaleY==0)) {
260 return -1;
261 } else {
262 return (h - originY - y) * image.getHeight() / (h - scaleY);
263 }
264 }
265
266 public double getScreenYDelta(double delta) {
267 int h = getHeight();
268 return (delta*(h-delta)/image.getHeight());
269 }
270
271 public int getScreenY(int y) {
272 int guessedY;
273 int h = getHeight();
274
275 guessedY = h-20-y*(h-60)/image.getHeight();
276 for (int j = guessedY-20; j< guessedY+20; j++) {
277 if (getImageY(j) == y) {
278 guessedY = j;
279 break;
280 }
281 }
282 return guessedY;
283 }
284
285 /**
286 * Gets the start position of the selection box on X-axis.
287 *
288 * @return start position of the selection box on X-axis
289 */
290 public int getStartX() {
291 int w = getWidth();
292 double x = (startX < endX) ? startX : endX;
293 return getImageX((int)(x * ((double)(w - 60))) + 20);
294 }
295
296 /**
297 * Gets the end position of the selection box on X-axis.
298 *
299 * @return end position of the selection box on X-axis
300 */
301 public int getEndX() {
302 int w = getWidth();
303 double x = (startX > endX) ? startX : endX;
304 return getImageX((int)(x * ((double)(w - 60))) + 20);
305 }
306
307 /**
308 * Gets the start position of the selection box on Y-axis.
309 *
310 * @return start position of the selection box on Y-axis
311 */
312 public int getStartY() {
313 int h = getHeight();
314 double y = (startY < endY) ? startY : endY;
315 return getImageY((int)(y * ((double)(h - 60))) + 40);
316 }
317
318 /**
319 * Gets the end position of the selection box on Y-axis.
320 *
321 * @return end position of the selection box on Y-axis
322 */
323 public int getEndY() {
324 int h = getHeight();
325 double y = (startY > endY) ? startY : endY;
326 return getImageY((int)(y * ((double)(h - 60))) + 40);
327 }
328
329 public void drawPointer(boolean draw) {
330 drawPointer = draw;
331 }
332
333 public void setPointerPosition(int xPos, int yPos) {
334 this.xPos = xPos;
335 this.yPos = yPos;
336 }
337
338 public void drawZoomingArea(int x, int y) {
339 double deltaX = getScreenXDelta(10);
340 double deltaY = getScreenYDelta(10);
341 int w = getWidth(), h = getHeight();
342
343 startX = (x - deltaX-20)/(double)(w-scaleX);
344 startY = (y -deltaY-40)/(double)(h-scaleY);
345 endX = (x + deltaX-20)/(double)(w-scaleX);
346 endY = (y + deltaY-40)/(double)(h-scaleY);
347
348 drawBox = true;
349 repaint();
350 drawBox = false;
351 }
352 }
353
354
355 /*
356 public void setParent(Visualization visual) {
357 parent = visual;
358 }
359
360 public void drawCallLines(ArrayList coord) {
361 Graphics2D g2 = (Graphics2D)this.getGraphics();
362 int x1,y1,x2,y2;
363
364 if (coord == null) {// clear the viz
365 coords = null;
366 repaint();
367 return;
368 }
369
370
371 for (int j=0; j<coord.size()/2 -1; j++) {
372 x1 = ((Integer)coord.get(j*2)).intValue();
373 y1 = ((Integer)coord.get(j*2+1)).intValue();
374 x2 = ((Integer)coord.get(j*2+2)).intValue();
375 y2 = ((Integer)coord.get(j*2+3)).intValue();
376 g2.drawLine(x1,y1,x2,y2);
377 double len = java.lang.Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
378 double angle = java.lang.Math.asin(java.lang.Math.abs(y1-y2)/len);
379
380 if (x1>x2) {
381 if (y1 < y2)
382 angle = 2*java.lang.Math.PI - angle;
383 } else {
384 if (y1 > y2)
385 angle = java.lang.Math.PI - angle;
386 else
387 angle = java.lang.Math.PI + angle;
388 }
389 g2.drawLine(x2,y2,(int)(x2+15*java.lang.Math.cos(angle-0.5236)),(int)(y2+15*java.lang.Math.sin(angle-0.5236)));
390 g2.drawLine(x2,y2,(int)(x2+15*java.lang.Math.cos(angle+0.5236)),(int)(y2+15*java.lang.Math.sin(angle+0.5236)));
391
392 //System.out.println("draw from "+x1+","+y1+" to "+x2+","+y2 );
393 }
394
395 if (coords == null) coords = new ArrayList();
396 coords.add(coord);
397 } */
398
399 /*
400 /*if (parent != null) {
401 ReferenceDimension xAxis = (ReferenceDimension) parent.getDimension()[0];
402 int X = this.getImageX(x);
403 int Y = this.getImageY(y);
404 if ((Y >= 0) && (Y < xAxis.getEntityNumber()) && (X >= 0) && (X < xAxis.getEntityNumber())) {
405 Color color = parent.getImage().getSortedColor(xAxis,xAxis,X,Y);
406 //if (color==null) coords = null;
407 }
408 }
409
410 if (coords == null) return;
411 int x1,x2,y1,y2;
412 x1=x2=y1=y2=0;
413
414 g2.setColor(Color.black);
415 for (int i=0; i< coords.size(); i++) {
416 ArrayList coord = (ArrayList)coords.get(i);
417 for (int j=0; j<coord.size()/2 -1; j++) {
418 x1 = ((Integer)coord.get(j*2)).intValue();
419 y1 = ((Integer)coord.get(j*2+1)).intValue();
420 x2 = ((Integer)coord.get(j*2+2)).intValue();
421 y2 = ((Integer)coord.get(j*2+3)).intValue();
422 g2.drawLine(x1,y1,x2,y2);
423 double len = java.lang.Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
424 double angle = java.lang.Math.asin(java.lang.Math.abs(y1-y2)/len);
425 if (len == 0) continue;
426 if (x1>x2) {
427 if (y1 < y2)
428 angle = 2*java.lang.Math.PI - angle;
429 } else {
430 if (y1 > y2)
431 angle = java.lang.Math.PI - angle;
432 else
433 angle = java.lang.Math.PI + angle;
434 }
435 g2.drawLine(x2,y2,(int)(x2+10*java.lang.Math.cos(angle-0.5236)),(int)(y2+10*java.lang.Math.sin(angle-0.5236)));
436 g2.drawLine(x2,y2,(int)(x2+10*java.lang.Math.cos(angle+0.5236)),(int)(y2+10*java.lang.Math.sin(angle+0.5236)));
437 }
438 }*/