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 }*/