View Javadoc
1 /* ------------------------------------------------------------------- 2 GeoVISTA Center (Penn State, Dept. of Geography) 3 Java source file for the class Map 4 Copyright (c), 2002, GeoVISTA Center 5 All Rights Reserved. 6 Original Author: Frank Hardisty 7 $Author: dxg231 $ 8 $Id: MapCanvas.java,v 1.11 2003/09/04 21:11:59 dxg231 Exp $ 9 $Date: 2003/09/04 21:11:59 $ 10 Reference: Document no: 11 ___ ___ 12 ------------------------------------------------------------------- * 13 */ 14 package edu.psu.geovista.app.map; 15 16 import edu.psu.geovista.app.coordinator.*; 17 import edu.psu.geovista.data.condition.*; 18 import edu.psu.geovista.data.geog.*; 19 import edu.psu.geovista.symbolization.*; 20 import edu.psu.geovista.ui.*; 21 import edu.psu.geovista.ui.Fisheyes; 22 import edu.psu.geovista.ui.cursor.*; 23 import edu.psu.geovista.ui.event.*; 24 25 import java.awt.*; 26 import java.awt.event.*; 27 import java.awt.geom.*; 28 29 import java.util.*; 30 31 import javax.swing.*; 32 33 /*** 34 * This class handles the rendering of layer-independent objects like 35 * tooltips and the image used for buffering, and manages the layers, 36 * which render themselves to the image. 37 * 38 * This class also transforms spatial data into user space. 39 * 40 * This class is intended to be used inside other components like the 41 * GeoMap or the PlotMatrix. 42 */ 43 public class MapCanvas 44 extends JPanel 45 implements ComponentListener, 46 ActionListener, MouseListener, 47 MouseMotionListener, 48 SelectionListener, 49 IndicationListener, 50 DataSetListener, 51 SpatialExtentListener, 52 ExcentricLabelClient { 53 private static final int CLASSIFIER_TYPE_BIVARIATE = 0; 54 private static final int CLASSIFIER_TYPE_UNIVARIATE = 1; 55 public static int MODE_SELECT = 0; //default mode 56 public static int MODE_ZOOM_IN = 1; 57 public static int MODE_ZOOM_OUT = 2; 58 public static int MODE_PAN = 3; 59 public static int MODE_EXCENTRIC = 4; 60 public static int MODE_FISHEYE = 5; 61 public static int MODE_MAGNIFYING = 6; 62 transient private int mouseX1; 63 transient private int mouseX2; 64 transient private int mouseY1; 65 transient private int mouseY2; 66 private transient DataSetForApps dataSet; 67 68 //private transient Vector userSpaceSpatialData = new Vector(); 69 private transient Vector spatialDataTypes = new Vector(); 70 private transient Vector shapeLayers; 71 private transient int indication = Integer.MIN_VALUE; 72 private transient int activeLayer; 73 private transient ShapeTransformer transformer; 74 private transient int[] classification; 75 private transient int[] conditionArray; 76 77 //todo: add this 78 //private int[] focus; 79 private transient int[] selectedObservations; 80 private transient Color[] objectColors; 81 private transient String[] variableNames; 82 private transient int currColorColumnX = -1; 83 private transient int currColorColumnY = -1; 84 85 //Colors 86 private transient double[] dataColorX; 87 private transient double[] dataColorY; 88 private transient Color colorSelection = Color.yellow; 89 private transient boolean selOriginalColorMode = true; 90 private transient Color colorIndication = Color.blue; 91 92 //todo: add these as functional types 93 //private Color colorNull = Color.darkGray; 94 //private Color colorOutOfFocus = Color.black; 95 //private Color colorNotInStudyArea = Color.black; 96 protected transient BivariateColorSymbolClassificationSimple 97 bivarColorClasser = 98 new BivariateColorSymbolClassificationSimple(); 99 100 //private Color colorLine; 101 //private float lineWidth; 102 private transient Rectangle2D savedSrc = null; 103 private transient Image drawingBuff; 104 private transient Image[] drawingBuff2; 105 private transient AffineTransform panningXForm = new AffineTransform(); 106 private transient Rectangle2D spatialDataFullExtent; 107 protected transient ExcentricLabels exLabels; 108 private transient String tipText = ""; 109 private transient Font tipFont; 110 private transient boolean drawTip = true; 111 private transient boolean drawBox = false; 112 private transient int mode; 113 private transient GeoCursors cursors = new GeoCursors(); 114 private transient float[] dash = new float[] { 115 5f, 7f, 5f}; 116 private transient BasicStroke dashStroke = new BasicStroke( (float) 2.0, 117 BasicStroke.CAP_ROUND, 118 BasicStroke.JOIN_ROUND, 119 (float) 10.0, dash, 0); 120 private transient BasicStroke solidStroke = new BasicStroke(2f); 121 protected transient boolean autofit = false; 122 private transient boolean fitOnce = false; 123 protected Fisheyes fisheyes; 124 125 public MapCanvas() { 126 super(); 127 this.setPreferredSize(new Dimension(300, 300)); 128 shapeLayers = new Vector(); 129 this.addComponentListener(this); 130 this.transformer = new ShapeAffineTransform(); 131 this.addMouseListener(this); 132 this.addMouseMotionListener(this); 133 mouseX1 = -2; 134 this.drawTip = true; 135 this.mode = this.MODE_SELECT; 136 137 int greyAmt = 170; 138 Color bgColor = new Color(greyAmt, greyAmt, greyAmt); 139 this.setBackground(bgColor); 140 141 //this.exLabels = new ExcentricLabels(); 142 //this.fisheyes = new Fisheyes(); 143 //fisheyes.setLensType(Fisheyes.LENS_GAUSSIAN); 144 } 145 146 147 /**** 148 * Set colors for observations. Normally this method is called by other components 149 * that classify or cluster data observations and assign colors. 150 */ 151 public void setObservationColors(Color[] obsColors) { 152 if (this.shapeLayers.size() < 1 || this.dataSet == null) { 153 return; 154 } 155 156 if (this.dataSet.getNumObservations() != obsColors.length) 157 { 158 System.out.println("###ERROR: obsColors.length != number of observations!!!" + 159 this.dataSet.getNumObservations()+" != "+obsColors.length); 160 return; 161 } 162 163 this.objectColors = obsColors; 164 165 LayerShape ls = (LayerShape) this.shapeLayers.get(this.activeLayer); 166 ls.setObjectColors(this.objectColors); 167 168 paintDrawingBuff(); 169 this.repaint(); 170 } 171 172 173 private void sendSpatialDataToLayer(LayerShape l, Shape[] spatialData) { 174 l.setSpatialData(spatialData); 175 l.setParentSize(this.getHeight(), this.getWidth()); 176 } 177 178 public Shape[] findUserSpaceSpatialData(Shape[] originalShapes, 179 Rectangle2D dest, boolean useSavedSrc) { 180 Shape[] originalData = originalShapes; 181 182 //two cases for finding src rectangle: second or later set of shapes, or first. 183 Rectangle2D src = null; 184 185 if (useSavedSrc && (savedSrc != null)) { 186 src = this.savedSrc; 187 } 188 else { 189 src = findFullExtentRect(originalShapes); 190 191 //src = this.savedSrc; 192 } 193 194 AffineTransform xForm = AffineTransformModifier.makeGeogAffineTransform(src, 195 dest, 196 true, 197 true); 198 Shape[] returnShapes = this.transformer.makeTransformedShapes( 199 originalShapes, xForm); 200 201 return returnShapes; 202 } 203 204 private Rectangle2D findFullExtentRect(Shape[] someShapes) { 205 Shape[] someData = someShapes; 206 double xMax; 207 double xMin; 208 double yMax; 209 double yMin; 210 xMax = Double.MAX_VALUE * -1; 211 xMin = Double.MAX_VALUE; 212 yMax = Double.MAX_VALUE * -1; 213 yMin = Double.MAX_VALUE; 214 215 for (int i = 0; i < someData.length; i++) { 216 Rectangle2D bounding = someData[i].getBounds2D(); 217 218 if (bounding.getMaxX() > xMax) { 219 xMax = bounding.getMaxX(); 220 } 221 222 if (bounding.getMinX() < xMin) { 223 xMin = bounding.getMinX(); 224 } 225 226 if (bounding.getMaxY() > yMax) { 227 yMax = bounding.getMaxY(); 228 } 229 230 if (bounding.getMinY() < yMin) { 231 yMin = bounding.getMinY(); 232 } 233 } 234 235 Rectangle2D src = new Rectangle2D.Double(xMin, yMin, xMax - xMin, 236 yMax - yMin); 237 this.savedSrc = src; 238 239 //this.spatialDataFullExtent = src; 240 return src; 241 } 242 243 public Shape[] findFullExtentSpatialData(Shape[] originalShapes, 244 boolean useSavedSrc) { 245 Rectangle2D dest = new Rectangle2D.Float(0, 0, this.getWidth(), 246 this.getHeight()); 247 Shape[] returnShapes = this.findUserSpaceSpatialData(originalShapes, dest, 248 useSavedSrc); 249 250 return returnShapes; 251 } 252 253 private void zoomNewExtent(Rectangle2D dest) { 254 for (Enumeration e = this.shapeLayers.elements(); e.hasMoreElements(); ) { 255 LayerShape ls = (LayerShape) e.nextElement(); 256 Shape[] originalShapes = ls.getOriginalSpatialData(); 257 Shape[] returnShapes = this.findUserSpaceSpatialData(originalShapes, dest, 258 ls.getIsAuxiliary()); 259 this.sendSpatialDataToLayer(ls, returnShapes); 260 } 261 262 paintDrawingBuff(); 263 this.repaint(); 264 } 265 266 public void zoomFullExtent() { 267 for (Enumeration e = this.shapeLayers.elements(); e.hasMoreElements(); ) { 268 LayerShape ls = (LayerShape) e.nextElement(); 269 270 //start print centroids 271 // System.out.println("Centroids:"); 272 // for (int i = 0; i < this.dataSet.getNumObservations(); i++){ 273 // Point p = ls.findCentroid(i); 274 // System.out.println(p.x + ","+p.y); 275 // } 276 //end print centroids 277 Shape[] originalShapes = ls.getOriginalSpatialData(); 278 Shape[] returnShapes = this.findFullExtentSpatialData(originalShapes, 279 ls.getIsAuxiliary()); 280 this.sendSpatialDataToLayer(ls, returnShapes); 281 } 282 283 paintDrawingBuff(); 284 this.repaint(); 285 286 LayerShape activeLayer = (LayerShape)this.shapeLayers.get(this.activeLayer); 287 Rectangle2D rect = this.findFullExtentRect(activeLayer.getSpatialData()); 288 this.fireSpatialExtentChanged(rect); 289 } 290 291 public void spatialExtentChanged(SpatialExtentEvent e) { 292 Rectangle2D rect = e.getSpatialExtent(); 293 this.zoomNewExtent(rect); 294 } 295 296 public void zoomIn(int x1, int x2, int y1, int y2) { 297 if (x1 > x2) { 298 int temp = x1; 299 x1 = x2; 300 x2 = temp; 301 } 302 303 if (y1 > y2) { 304 int temp = y1; 305 y1 = y2; 306 y2 = temp; 307 } 308 309 int diffX = x2 - x1; 310 int diffY = y2 - y1; 311 int boxTolerance = 10; 312 313 if ( (diffX < boxTolerance) && (diffY < boxTolerance)) { //accidental box, should have been a click 314 x2 = x1; 315 y2 = y1; 316 } 317 318 if ( (x1 == x2) && (y1 == y2)) { 319 //single click, we want to zoom in a bit with the click as the center 320 float scaleFactor = 0.45f; 321 int center = x1; 322 x1 = center - (int) ( (float)this.getWidth() * scaleFactor); 323 x2 = center + (int) ( (float)this.getWidth() * scaleFactor); 324 center = y1; 325 y1 = center - (int) ( (float)this.getHeight() * scaleFactor); 326 y2 = center + (int) ( (float)this.getHeight() * scaleFactor); 327 } 328 329 Rectangle2D src = new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1); 330 Rectangle2D dest = new Rectangle2D.Float(0, 0, this.getWidth(), 331 this.getHeight()); 332 AffineTransform xForm = AffineTransformModifier.makeZoomingAffineTransform( 333 src, dest); 334 335 for (Enumeration e = this.shapeLayers.elements(); e.hasMoreElements(); ) { 336 LayerShape ls = (LayerShape) e.nextElement(); 337 338 Shape[] originalShapes = ls.getSpatialData(); 339 Shape[] returnShapes = this.transformer.makeTransformedShapes( 340 originalShapes, xForm); 341 342 this.sendSpatialDataToLayer(ls, returnShapes); 343 } 344 345 paintDrawingBuff(); 346 this.repaint(); 347 348 LayerShape activeLayer = (LayerShape)this.shapeLayers.get(this.activeLayer); 349 Rectangle2D rect = this.findFullExtentRect(activeLayer.getSpatialData()); 350 this.fireSpatialExtentChanged(rect); 351 } 352 353 public void zoomOut(int x1, int x2, int y1, int y2) { 354 if (x1 > x2) { 355 int temp = x1; 356 x1 = x2; 357 x2 = temp; 358 } 359 360 if (y1 > y2) { 361 int temp = y1; 362 y1 = y2; 363 y2 = temp; 364 } 365 366 Rectangle2D src = new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1); 367 Rectangle2D dest = new Rectangle2D.Float(0, 0, this.getWidth(), 368 this.getHeight()); 369 AffineTransform xForm = AffineTransformModifier.makeZoomingAffineTransform( 370 dest, src); 371 372 for (Enumeration e = this.shapeLayers.elements(); e.hasMoreElements(); ) { 373 LayerShape ls = (LayerShape) e.nextElement(); 374 375 Shape[] originalShapes = ls.getSpatialData(); 376 Shape[] returnShapes = this.transformer.makeTransformedShapes( 377 originalShapes, xForm); 378 379 this.sendSpatialDataToLayer(ls, returnShapes); 380 } 381 382 paintDrawingBuff(); 383 this.repaint(); 384 385 LayerShape activeLayer = (LayerShape)this.shapeLayers.get(this.activeLayer); 386 Rectangle2D rect = this.findFullExtentRect(activeLayer.getSpatialData()); 387 this.fireSpatialExtentChanged(rect); 388 } 389 390 public void pan(int x1, int x2, int y1, int y2) { 391 int xDiff = x2 - x1; 392 int yDiff = y2 - y1; 393 394 Rectangle2D dest = new Rectangle2D.Float(0 + xDiff, 0 + yDiff, 395 this.getWidth(), this.getHeight()); 396 Rectangle2D src = new Rectangle2D.Float(0, 0, this.getWidth(), 397 this.getHeight()); 398 AffineTransform xForm = AffineTransformModifier.makeGeogAffineTransform(src, 399 dest, 400 false, 401 false); 402 403 for (Enumeration e = this.shapeLayers.elements(); e.hasMoreElements(); ) { 404 LayerShape ls = (LayerShape) e.nextElement(); 405 406 Shape[] originalShapes = ls.getSpatialData(); 407 Shape[] returnShapes = this.transformer.makeTransformedShapes( 408 originalShapes, xForm); 409 410 this.sendSpatialDataToLayer(ls, returnShapes); 411 } 412 413 paintDrawingBuff(); 414 this.repaint(); 415 416 LayerShape activeLayer = (LayerShape)this.shapeLayers.get(this.activeLayer); 417 Rectangle2D rect = this.findFullExtentRect(activeLayer.getSpatialData()); 418 this.fireSpatialExtentChanged(rect); 419 } 420 421 public void panBuff(int x1, int x2, int y1, int y2) { 422 int xDiff = x2 - x1; 423 int yDiff = y2 - y1; 424 425 //AffineTransform panningXForm = new AffineTransform(); 426 panningXForm = panningXForm.getTranslateInstance(xDiff, yDiff); 427 } 428 429 private void sendColorsToLayers(int numObs) { 430 if (this.shapeLayers.size() < 1) { 431 return; 432 } 433 434 if (this.dataColorX == null) { 435 return; 436 } 437 438 if (this.dataColorY == null) { 439 return; 440 } 441 442 if ( (this.objectColors == null) || (this.objectColors.length != numObs)) { 443 this.objectColors = new Color[numObs]; 444 } 445 446 this.objectColors = this.bivarColorClasser.symbolize(this.dataColorX, 447 this.dataColorY); 448 449 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 450 ls.setObjectColors(this.objectColors); 451 paintDrawingBuff(); 452 this.repaint(); 453 } //end method 454 455 private void makeToolTip(int arrayIndex) { 456 if (arrayIndex < 0) { 457 tipText = ""; 458 } 459 else if (this.currColorColumnX == this.currColorColumnY) { 460 String xVal = String.valueOf(dataSet.getNumericValueAsDouble( 461 this.currColorColumnX, arrayIndex)); 462 String s = ""; 463 String[] observationNames = this.dataSet.getObservationNames(); 464 465 if (observationNames != null) { 466 s = s + "Name = " + observationNames[arrayIndex] + "\n"; 467 } 468 469 s = s + variableNames[currColorColumnX - 1] + " = " + xVal; 470 471 this.tipText = s; 472 } 473 else if ( (this.currColorColumnX > 0) && (this.currColorColumnY > 0)) { 474 //setting multi-line tool tip 475 //b.setToolTipText("<html>ToolTip : 1st Line<br>2nd Line<br> 3rd Line </html>"); 476 String xVal = String.valueOf(dataSet.getNumericValueAsDouble( 477 this.currColorColumnX, arrayIndex)); 478 String yVal = String.valueOf(dataSet.getNumericValueAsDouble( 479 this.currColorColumnY, arrayIndex)); 480 String s = ""; 481 String[] observationNames = this.dataSet.getObservationNames(); 482 483 if (observationNames != null) { 484 s = s + "Name = " + observationNames[arrayIndex] + "\n"; 485 } 486 487 s = s + variableNames[currColorColumnX - 1] + " = " + xVal + "\n" + 488 variableNames[currColorColumnY - 1] + " = " + yVal; 489 490 this.tipText = s; 491 } //if 492 } 493 494 //start component event handling 495 //note: this class only listens to itself 496 public void componentHidden(ComponentEvent e) { 497 498 } 499 500 protected void tickleColors() { 501 //egregious hack 502 this.setCurrColorColumnX(this.currColorColumnX); 503 this.setCurrColorColumnY(this.currColorColumnY); 504 } 505 506 public void componentShown(ComponentEvent e) { 507 this.componentResized(e); 508 System.out.println("showing component"); 509 510 // LayerShape aLayer = (LayerShape) this.shapeLayers.get(this.activeLayer); 511 // if (aLayer.colorsRecieved == false){ 512 // this.sendColorsToLayers(this.dataColorX.length); 513 // 514 // } 515 } 516 517 public void componentMoved(ComponentEvent e) { 518 519 } 520 521 private void autoFitShapes() { 522 for (int i = 0; i < this.shapeLayers.size(); i++) { 523 LayerShape ls = (LayerShape)this.shapeLayers.get(i); 524 Integer layerTypeInt = (Integer)this.spatialDataTypes.get(i); 525 int layerType = layerTypeInt.intValue(); 526 527 if (layerType == DataSetForApps.SPATIAL_TYPE_POLYGON) { 528 Shape[] originalShapes = ls.getOriginalSpatialData(); 529 boolean useSavedSrc = ls.getIsAuxiliary(); 530 Shape[] userShapes = this.findFullExtentSpatialData(originalShapes, 531 useSavedSrc); 532 this.sendSpatialDataToLayer(ls, userShapes); 533 534 //this.sendColorsToLayers(this.dataSet.getNumObservations()); 535 } 536 else if (layerType == DataSetForApps.SPATIAL_TYPE_POINT) { 537 Shape[] originalShapes = ls.getOriginalSpatialData(); 538 boolean useSavedSrc = ls.getIsAuxiliary(); 539 Shape[] userShapes = this.findFullExtentSpatialData(originalShapes, 540 useSavedSrc); 541 LayerPoint lp = new LayerPoint(); 542 Point2D[] points = lp.shapesToPoints(userShapes); 543 userShapes = lp.findShapesForPoints(points); 544 545 //userSpaceSpatialData.add(userShapes); 546 this.sendSpatialDataToLayer(ls, userShapes); 547 this.sendColorsToLayers(this.dataSet.getNumObservations()); 548 } //end if layerType 549 } //next layer 550 551 this.fitOnce = true; 552 } 553 554 public void componentResized(ComponentEvent e) { 555 if ( (this.shapeLayers.size() > 0) && (this.getWidth() > 0) && 556 (this.getHeight() > 0)) { 557 this.drawingBuff = this.createImage(this.getWidth(), this.getHeight()); 558 559 for (int i = 0; i < this.shapeLayers.size(); i++) { 560 LayerShape ls = (LayerShape)this.shapeLayers.get(i); 561 ls.setParentSize(this.getHeight(), this.getWidth()); 562 } //next layer 563 564 if (this.autofit || !this.fitOnce) { 565 this.autoFitShapes(); 566 } //end if autofit 567 568 if (this.fisheyes != null) { 569 float width = (float)this.getWidth(); 570 this.fisheyes.setLensRadius(width / 5f); 571 572 //System.out.println(this.fisheyes.getLensRadius()); 573 } 574 //hack 575 //this.sendColorsToLayers(this.dataColorX.length); 576 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 577 ls.setObjectColors(this.objectColors); 578 //previous line results in sending colors to layers 579 paintDrawingBuff(); 580 //this.repaint(); 581 } //end if layers exist and size is > 0 582 //System.out.println("resizing component"); 583 } 584 585 //end component event handling 586 //start accessors 587 public void setMode(int mode) { 588 if (mode == this.MODE_SELECT) { 589 this.fisheyes = null; 590 this.exLabels = null; 591 this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); 592 } 593 else if (mode == this.MODE_PAN) { 594 this.setCursor(cursors.getCursor(GeoCursors.CURSOR_PAN)); 595 } 596 else if (mode == this.MODE_ZOOM_IN) { 597 this.setCursor(cursors.getCursor(GeoCursors.CURSOR_ZOOM_IN)); 598 } 599 else if (mode == this.MODE_ZOOM_OUT) { 600 this.setCursor(cursors.getCursor(GeoCursors.CURSOR_ZOOM_OUT)); 601 } 602 else if (mode == this.MODE_EXCENTRIC) { 603 this.exLabels = new ExcentricLabels(); 604 this.initExcentricLabels(); 605 //this.exLabels.setVisible(true); 606 this.fisheyes = null; 607 this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); 608 } 609 else if (mode == this.MODE_FISHEYE) { 610 this.exLabels = null; 611 this.fisheyes = new Fisheyes(); 612 fisheyes.setLensType(Fisheyes.LENS_GAUSSIAN); 613 this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); 614 } 615 616 else { 617 throw new IllegalArgumentException( 618 "MapCanvas.setMode, ecountered unknown mode"); 619 } 620 621 this.mode = mode; 622 } 623 624 public void setBivarColorClasser(BivariateColorSymbolClassification 625 bivarColorClasser) { 626 this.bivarColorClasser = (BivariateColorSymbolClassificationSimple) 627 bivarColorClasser; 628 629 if (this.dataSet != null) { 630 this.sendColorsToLayers(this.dataSet.getNumObservations()); 631 } 632 } 633 634 public void setAuxiliarySpatialData(Object[] spatialDataIn) { 635 //System.out.println("got spatial data 1"); 636 if (spatialDataIn == null) { 637 return; 638 } 639 DataSetForApps auxData = new DataSetForApps(); 640 auxData.setDataObject(spatialDataIn); 641 this.setAuxiliarySpatialData(auxData); 642 } 643 644 public void setAuxiliarySpatialData(DataSetForApps auxData) { 645 //System.out.println("got spatial data 2"); 646 if (auxData == null) { 647 return; 648 } 649 LayerShape ls = null; 650 int layerType = auxData.getSpatialType(); 651 652 if (layerType == DataSetForApps.SPATIAL_TYPE_POLYGON) { 653 ls = new LayerPolygon(); 654 ls.setOriginalSpatialData(auxData.getShapeData()); 655 spatialDataTypes.add(new Integer(DataSetForApps.SPATIAL_TYPE_POLYGON)); 656 657 Shape[] userShapes = auxData.getShapeData(); 658 userShapes = this.findFullExtentSpatialData(userShapes, true); 659 this.sendSpatialDataToLayer(ls, userShapes); 660 } 661 else if (layerType == DataSetForApps.SPATIAL_TYPE_POINT) { 662 LayerPoint lp = new LayerPoint(); 663 Shape[] pointShapesOriginal = lp.pointsToShapes(auxData.getPoint2DData()); 664 Shape[] pointShapesUser = this.findFullExtentSpatialData( 665 pointShapesOriginal, true); 666 Point2D[] userSpacePoints = lp.shapesToPoints(pointShapesUser); 667 Shape[] circleShapes = lp.findShapesForPoints(userSpacePoints); 668 ls.setOriginalSpatialData(pointShapesOriginal); 669 spatialDataTypes.add(new Integer(DataSetForApps.SPATIAL_TYPE_POINT)); 670 671 //userSpaceSpatialData.add(circleShapes); 672 lp.setSpatialData(circleShapes); 673 ls = lp; 674 } 675 else { 676 throw new IllegalArgumentException( 677 "unexpected layer type ecountered in MapCanvas.setAuxiliarySpatialData"); 678 } 679 680 //ok, default behaviours here: 681 //new layer goes on top of previous layer 682 //so add it to the end 683 //new layer has no fill 684 ls.setIsAuxiliary(true); 685 this.shapeLayers.add(ls); 686 ls.setParentSize(this.getHeight(), this.getWidth()); 687 this.paintDrawingBuff(); 688 this.repaint(); 689 } 690 691 public void setDataSet(Object[] dataSetIn) { 692 String[] attributeArrays = (String[]) dataSetIn[0]; 693 int len = attributeArrays.length; 694 this.dataSet = new DataSetForApps(); 695 this.dataSet.setDataObject(dataSetIn); 696 697 if (dataSetIn[len + 1] == null) { 698 this.dataSet.setObservationNames(null); 699 } 700 else if (dataSetIn[len + 1] instanceof String[]) { 701 this.dataSet.setObservationNames( (String[]) dataSetIn[len + 1]); 702 } 703 704 this.setDataSet(this.dataSet); 705 this.initExcentricLabels(); 706 707 //this.sendColorsToLayers(this.dataSet.getNumObservations()); 708 } 709 710 public void setDataSet(DataSetForApps dataSet) { 711 this.dataColorX = null; 712 this.dataColorY = null; 713 this.currColorColumnX = -1; 714 this.currColorColumnY = -1; 715 716 this.dataSet = dataSet; 717 this.shapeLayers.removeAllElements(); 718 this.variableNames = this.dataSet.getAttributeNamesNumeric(); 719 720 int layerType = dataSet.getSpatialType(); 721 LayerShape ls = null; 722 String[] attNames = dataSet.getAttributeNamesNumeric(); 723 int numAttributes = attNames.length; 724 725 if (layerType == DataSetForApps.SPATIAL_TYPE_POLYGON) { 726 ls = new LayerPolygon(); 727 ls.setOriginalSpatialData(dataSet.getShapeData()); 728 spatialDataTypes.add(new Integer(DataSetForApps.SPATIAL_TYPE_POLYGON)); 729 730 Shape[] userShapes = dataSet.getShapeData(); 731 userShapes = this.findFullExtentSpatialData(userShapes, false); 732 733 //userSpaceSpatialData.add(userShapes); 734 this.sendSpatialDataToLayer(ls, userShapes); 735 } 736 else if (layerType == DataSetForApps.SPATIAL_TYPE_POINT) { 737 LayerPoint lp = new LayerPoint(); 738 Shape[] pointShapesOriginal = lp.pointsToShapes(dataSet.getPoint2DData()); 739 Shape[] pointShapesUser = this.findFullExtentSpatialData( 740 pointShapesOriginal, false); 741 Point2D[] userSpacePoints = lp.shapesToPoints(pointShapesUser); 742 Shape[] circleShapes = lp.findShapesForPoints(userSpacePoints); 743 lp.setOriginalSpatialData(pointShapesOriginal); 744 spatialDataTypes.add(new Integer(DataSetForApps.SPATIAL_TYPE_POINT)); 745 746 //userSpaceSpatialData.add(circleShapes); 747 lp.setSpatialData(circleShapes); 748 ls = lp; 749 } 750 //System.out.println("activeLayer = " + activeLayer); 751 752 shapeLayers.add(ls); 753 754 //set default data to get color from 755 if ( (this.drawingBuff == null) && (this.getWidth() > 0) && 756 (this.getHeight() > 0)) { 757 this.drawingBuff = this.createImage(this.getWidth(), this.getHeight()); 758 } 759 760 if (this.drawingBuff != null) { 761 } 762 763 //resizing will autofit if this.autofit = true 764 //resizing resizes the drawing buffer, and repaints it 765 boolean realAutofit = this.autofit; 766 this.autofit = true; 767 this.componentResized(new ComponentEvent(this, 0)); 768 this.autofit = realAutofit; 769 770 //this.sendColorsToLayers(this.dataSet.getNumObservations()); 771 //paintDrawingBuff(); 772 //repaint(); 773 } 774 775 public void setTransformer(ShapeTransformer transformer) { 776 this.transformer = transformer; 777 } 778 779 public void setCurrColorColumnX(int currColorColumnX) { 780 if ( (this.dataSet != null) && 781 (currColorColumnX <= dataSet.getNumberNumericAttributes())) { 782 this.currColorColumnX = currColorColumnX; 783 //XXX getNumericDataAsDouble has changed... 784 this.dataColorX = this.dataSet.getNumericDataAsDouble(currColorColumnX - 785 1); 786 this.sendColorsToLayers(this.dataColorX.length); 787 } 788 } 789 790 public int getCurrColorColumnX() { 791 return this.currColorColumnX; 792 } 793 794 public Color[] getColors() { 795 if (this.shapeLayers.size() == 0) { 796 return new Color[0]; 797 } 798 799 LayerShape ls = (LayerShape)this.shapeLayers.elementAt(this.activeLayer); 800 801 return ls.getColors(); 802 } 803 804 public void setCurrColorColumnY(int currColorColumnY) { 805 if ( (this.dataSet != null) && 806 (currColorColumnY <= dataSet.getNumberNumericAttributes())) { 807 this.currColorColumnY = currColorColumnY; 808 //XXX getNumericDataAsDouble has changed... 809 this.dataColorY = this.dataSet.getNumericDataAsDouble(currColorColumnY - 810 1); 811 this.sendColorsToLayers(this.dataColorY.length); 812 } 813 } 814 815 public int getCurrColorColumnY() { 816 return this.currColorColumnY; 817 } 818 819 public void setIndication(int indication) { 820 if (fisheyes != null) { 821 //if we have fisheyes, this is too expensive!!! 822 //bail 823 return; 824 } 825 826 if (indication != this.indication) { 827 this.indication = indication; 828 829 if (shapeLayers.size() > 0) { 830 LayerShape ls = (LayerShape) shapeLayers.get(this.activeLayer); 831 ls.setIndication(indication); 832 833 if (indication >= 0 && indication < dataSet.getNumObservations()) { 834 this.drawTip = true; 835 836 Point p = ls.findCentroid(indication); 837 this.mouseX2 = (int) p.getX(); 838 this.mouseY2 = (int) p.getY(); 839 } 840 else { 841 this.drawTip = false; 842 } 843 844 this.makeToolTip(indication); 845 } //if we have at least one layer 846 847 //paintDrawingBuff(); 848 this.repaint(); 849 } //if indication is new 850 } 851 852 public void setSelectedObservations(Vector selectedObservations) { 853 this.selectedObservations = new int[selectedObservations.size()]; 854 855 int i = 0; 856 857 for (Enumeration e = selectedObservations.elements(); e.hasMoreElements(); ) { 858 Integer bigIint = (Integer) e.nextElement(); 859 this.selectedObservations[i] = bigIint.intValue(); 860 i++; 861 } 862 863 this.setSelectedObservationsInt(this.selectedObservations); 864 } 865 866 public Vector getSelectedObservations() { 867 Vector v = new Vector(); 868 869 for (int i = 0; i < selectedObservations.length; i++) { 870 v.add(new Integer(selectedObservations[i])); 871 } 872 873 return v; 874 } 875 876 public void setSelections(int[] selections) { 877 Vector v = new Vector(); 878 879 for (int i = 0; i < selections.length; i++) { 880 if (selections[i] == 1) { 881 v.add(new Integer(i)); 882 } 883 } 884 885 this.selectedObservations = new int[v.size()]; 886 887 int i = 0; 888 889 for (Enumeration e = v.elements(); e.hasMoreElements(); ) { 890 Integer bigIint = (Integer) e.nextElement(); 891 this.selectedObservations[i] = bigIint.intValue(); 892 i++; 893 } 894 895 this.setSelectedObservationsInt(this.selectedObservations); 896 } 897 898 public int[] getSelections() { 899 int[] selections = new int[this.dataColorX.length]; 900 if (this.selectedObservations == null) { 901 this.selectedObservations = new int[0]; 902 } 903 for (int i = 0; i < this.selectedObservations.length; i++) { 904 selections[this.selectedObservations[i]] = 1; 905 } 906 907 return selections; 908 } 909 910 public void selectionChanged(SelectionEvent e) { 911 int[] sel = e.getSelection(); 912 this.setSelectedObservationsInt(sel); 913 } 914 915 public void indicationChanged(IndicationEvent e) { 916 if (this == e.getSource()) { 917 return; 918 } 919 920 int indication = e.getIndication(); 921 this.setIndication(indication); 922 } 923 924 public void dataSetChanged(DataSetEvent e) { 925 this.setDataSet(e.getDataSet()); 926 } 927 928 public void setSelectedObservationsInt(int[] selectedObservations) { 929 this.selectedObservations = selectedObservations; 930 931 if (selectedObservations == null) { 932 return; 933 } 934 935 if ( (shapeLayers.size() > 0) && (this.drawingBuff != null)) { 936 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 937 ls.setSelectedObservations(this.selectedObservations); 938 paintDrawingBuff(); 939 this.repaint(); 940 } 941 else if ( (shapeLayers.size() > 0) && (this.drawingBuff == null) && 942 (this.selectedObservations.length > 1)) { //means we have data but are not visible yet 943 944 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 945 ls.setSelectedObservations(this.selectedObservations); 946 } 947 } 948 949 public int[] getSelectedObservationsInt() { 950 return this.selectedObservations; 951 } 952 953 public void setColorSelection(Color colorSelection) { 954 this.colorSelection = colorSelection; 955 956 if (shapeLayers.size() > 0) { 957 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 958 LayerShape ls = (LayerShape) e.nextElement(); 959 ls.setColorSelection(colorSelection); 960 } 961 962 paintDrawingBuff(); 963 this.repaint(); 964 } 965 } 966 967 public boolean getSelOriginalColorMode() { 968 return selOriginalColorMode; 969 } 970 971 public void setSelOriginalColorMode(boolean selOriginalColorMode) { 972 this.selOriginalColorMode = selOriginalColorMode; 973 if (shapeLayers == null) { 974 return; 975 } 976 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 977 LayerShape ls = (LayerShape) e.nextElement(); 978 ls.setSelOriginalColorMode(selOriginalColorMode); 979 } 980 981 paintDrawingBuff(); 982 this.repaint(); 983 984 } 985 986 public void setBackground(Color c) { 987 super.setBackground(c); 988 if (shapeLayers == null) { 989 return; 990 } 991 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 992 LayerShape ls = (LayerShape) e.nextElement(); 993 ls.setColorBackground(c); 994 } 995 996 paintDrawingBuff(); 997 this.repaint(); 998 999 } 1000 1001 /*** 1002 * put your documentation comment here 1003 * @param conditionArray 1004 */ 1005 public void setConditionArray(int[] conditionArray) { 1006 if (shapeLayers.size() > 0 && drawingBuff != null) { 1007 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 1008 LayerShape ls = (LayerShape) e.nextElement(); 1009 ls.setConditionArray(conditionArray); 1010 } 1011 1012 paintDrawingBuff(); 1013 this.repaint(); 1014 } 1015 } 1016 1017 //end accessors 1018 public void actionPerformed(ActionEvent e) { 1019 //* this method used for testing only... 1020 String source = e.getSource().toString(); 1021 String command = e.getActionCommand(); 1022 1023 if (e.getSource()instanceof ConditionManager) { 1024 ConditionManager cm = (ConditionManager) e.getSource(); 1025 int[] conditionArray = cm.getConditionResults(); 1026 this.setConditionArray(conditionArray); 1027 } 1028 1029 //*/ 1030 } 1031 1032 //start mouse event handling 1033 1034 /*** 1035 * Draws a bounding box for selection. 1036 * @param e 1037 */ 1038 public void mouseDragged(MouseEvent e) { 1039 this.drawBox = true; 1040 this.drawTip = false; 1041 1042 if (mode == this.MODE_PAN) { 1043 Cursor grabCur = cursors.getCursor(GeoCursors.CURSOR_GRAB); 1044 1045 if (this.getCursor() != grabCur) { 1046 this.setCursor(grabCur); 1047 } 1048 } 1049 1050 mouseX2 = e.getX(); 1051 mouseY2 = e.getY(); 1052 1053 if (mode == this.MODE_PAN) { 1054 panBuff(mouseX1, mouseX2, mouseY1, mouseY2); 1055 } 1056 1057 repaint(); 1058 } 1059 1060 /*** 1061 * Activates a tool tip. 1062 * @param e 1063 */ 1064 public void mouseMoved(MouseEvent e) { 1065 if (this.shapeLayers.size() < 1) { 1066 return; 1067 } 1068 1069 if (fisheyes != null) { 1070 fisheyes.setFocus(e.getX(), e.getY()); 1071 repaint(); 1072 } 1073 1074 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 1075 int indic = ls.findIndication(e.getX(), e.getY()); 1076 1077 if (indic != indication) { 1078 this.setIndication(indic); 1079 1080 int xClass = -1; 1081 int yClass = -1; 1082 1083 if (indic > 0) { 1084 xClass = this.bivarColorClasser.getClassX(indic); 1085 yClass = this.bivarColorClasser.getClassY(indic); 1086 } 1087 1088 this.fireIndicationChanged(indic, xClass, yClass); 1089 } 1090 1091 mouseX2 = e.getX(); 1092 mouseY2 = e.getY(); 1093 } 1094 1095 /*** 1096 * Inits selection bounding box. 1097 * @param e 1098 */ 1099 public void mousePressed(MouseEvent e) { 1100 mouseX1 = e.getX(); 1101 mouseY1 = e.getY(); 1102 mouseX2 = e.getX(); 1103 mouseY2 = e.getY(); 1104 } 1105 1106 /*** 1107 * Makes selection. 1108 * @param e 1109 */ 1110 public void mouseReleased(MouseEvent e) { 1111 if (this.dataSet == null) { 1112 return; 1113 } 1114 1115 if (mode == this.MODE_PAN) { 1116 this.setCursor(cursors.getCursor(GeoCursors.CURSOR_PAN)); 1117 } 1118 1119 panningXForm.setToIdentity(); 1120 1121 mouseX2 = e.getX(); 1122 mouseY2 = e.getY(); 1123 1124 if (mode == this.MODE_SELECT) { 1125 if (mouseX1 > mouseX2) { 1126 int temp = mouseX1; 1127 mouseX1 = mouseX2; 1128 mouseX2 = temp; 1129 } 1130 1131 if (mouseY1 > mouseY2) { 1132 int temp = mouseY1; 1133 mouseY1 = mouseY2; 1134 mouseY2 = temp; 1135 } 1136 1137 if (e.isShiftDown()) { 1138 this.makeSelectionShift(mouseX1, mouseX2 + 1, mouseY1, mouseY2 + 1); 1139 } 1140 else { 1141 this.makeSelection(mouseX1, mouseX2 + 1, mouseY1, mouseY2 + 1); 1142 } 1143 } 1144 else if (mode == this.MODE_ZOOM_IN) { 1145 this.zoomIn(mouseX1, mouseX2, mouseY1, mouseY2); 1146 } 1147 else if (mode == this.MODE_ZOOM_OUT) { 1148 this.zoomOut(mouseX1, mouseX2, mouseY1, mouseY2); 1149 } 1150 else if (mode == this.MODE_PAN) { 1151 this.pan(mouseX1, mouseX2, mouseY1, mouseY2); 1152 } 1153 1154 this.drawBox = false; 1155 repaint(); 1156 } 1157 1158 /*** 1159 * makes crosshair cursor 1160 * @param e 1161 */ 1162 public void mouseEntered(MouseEvent e) { 1163 } 1164 1165 /*** 1166 * resets cursor 1167 * @param e 1168 */ 1169 public void mouseExited(MouseEvent e) { 1170 e.consume(); 1171 this.drawTip = false; //prevents toolip from drawing 1172 this.drawBox = false; 1173 this.repaint(); 1174 this.setIndication( -1); 1175 this.fireIndicationChanged( -1, 0, 0); 1176 1177 if (fisheyes != null) { 1178 fisheyes.setFocus( -1000f, -1000f); 1179 } 1180 } 1181 1182 /*** 1183 * pop up a detail map 1184 * @param e 1185 */ 1186 public void mouseClicked(MouseEvent e) { 1187 if ( (e.getSource() == this) && (e.getClickCount() > 1)) { // This is a double-click or triple... 1188 1189 //if (dataIndices[0] != dataIndices[1]) { //why this??? I guess we don't want to pop up one from the 1190 //diagonal if we are a scatterplot 1191 GeoMap detailMap = new GeoMap(); 1192 detailMap.setBackground(this.getBackground()); 1193 detailMap.setDataSet(this.dataSet.getDataObjectOriginal()); 1194 detailMap.setBivarColorClasser(this.bivarColorClasser); 1195 detailMap.setSelectedObservations(this.getSelectedObservationsInt()); //need to do this here because 1196 1197 //otherwise the selection won't "take" 1198 detailMap.setXVariable(currColorColumnX); 1199 detailMap.setXChooserMode(GeoMap.VARIABLE_CHOOSER_MODE_FIXED); 1200 detailMap.setYVariable(currColorColumnY); 1201 detailMap.setYChooserMode(GeoMap.VARIABLE_CHOOSER_MODE_FIXED); 1202 1203 JFrame dummyFrame = new JFrame(); 1204 JDialog detailMapFrame = new JDialog(dummyFrame, "Detail Map", true); 1205 1206 detailMapFrame.setLocation(300, 300); 1207 detailMapFrame.setSize(300, 300); 1208 detailMapFrame.getContentPane().setLayout(new BorderLayout()); 1209 detailMapFrame.getContentPane().add(detailMap, BorderLayout.CENTER); 1210 1211 CoordinationManager cm = new CoordinationManager(); 1212 cm.addBean(this); 1213 cm.addBean(detailMap); 1214 1215 detailMapFrame.show(); 1216 1217 //}//end dataIndeces 1218 } //end if doubleclick 1219 } //end method 1220 1221 private void makeSelection(int x1, int x2, int y1, int y2) { 1222 int xDiff = Math.abs(x2 - x1); 1223 int yDiff = Math.abs(y2 - y1); 1224 int minPixels = 3; 1225 1226 if ( (xDiff < minPixels) && (yDiff < minPixels)) { 1227 return; 1228 } 1229 1230 if (shapeLayers.size() > 0) { 1231 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 1232 ls.findSelection(x1, x2, y1, y2); 1233 this.selectedObservations = ls.getSelectedObservations(); 1234 1235 //let's try just redrawing the selection 1236 //for (int i = 0; i < selectedObservations.length; i++) { 1237 ls.setSelectedObservations(selectedObservations); 1238 1239 this.fireActionPerformed(LayerShape.COMMAND_SELECTION); 1240 this.fireSelectionChanged(this.selectedObservations); 1241 1242 //unfortunately, we need to completely redraw any aux layers 1243 this.paintAuxLayers(); 1244 1245 //XXX shouldn't have to do this 1246 paintDrawingBuff(); 1247 this.repaint(); 1248 } 1249 } //method 1250 1251 private void makeSelectionShift(int x1, int x2, int y1, int y2) { 1252 if (shapeLayers.size() > 0) { 1253 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 1254 LayerShape ls = (LayerShape) e.nextElement(); 1255 ls.findSelectionShift(x1, x2, y1, y2); 1256 this.selectedObservations = ls.getSelectedObservations(); 1257 } 1258 1259 this.fireActionPerformed(LayerShape.COMMAND_SELECTION); 1260 paintDrawingBuff(); 1261 this.repaint(); 1262 } 1263 } 1264 1265 //end mouse event handling 1266 1267 /*** 1268 * Attention all layers! paint yourselves onto the buffer. 1269 * @param g 1270 */ 1271 private void paintDrawingBuff() { 1272 if (this.drawingBuff == null) { 1273 return; 1274 } 1275 1276 Graphics g = this.drawingBuff.getGraphics(); 1277 Graphics2D g2 = (Graphics2D) g; 1278 g.setColor(this.getBackground()); 1279 g.fillRect(0, 0, this.getWidth(), this.getHeight()); 1280 1281 if (shapeLayers.size() > 0) { 1282 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 1283 LayerShape ls = (LayerShape) e.nextElement(); 1284 ls.fisheyes = this.fisheyes; 1285 ls.render(g2); //paint your whole self 1286 } //next element 1287 } //end if 1288 } 1289 1290 /*** 1291 * Attention all auxiliary layers! paint yourselves onto the buffer. 1292 * @param g 1293 */ 1294 private void paintAuxLayers() { 1295 if (this.drawingBuff == null) { 1296 return; 1297 } 1298 1299 Graphics g = this.drawingBuff.getGraphics(); 1300 Graphics2D g2 = (Graphics2D) g; 1301 1302 if (shapeLayers.size() > 0) { 1303 for (Enumeration e = shapeLayers.elements(); e.hasMoreElements(); ) { 1304 LayerShape ls = (LayerShape) e.nextElement(); 1305 1306 if (ls.getIsAuxiliary()) { //if you are aux 1307 ls.fisheyes = this.fisheyes; 1308 ls.render(g2); //paint your whole self 1309 } //end if aux 1310 } //next element 1311 } //end if 1312 } 1313 1314 /*** 1315 * paints buffer, then drawing box 1316 * @param g 1317 */ 1318 public void paintComponent(Graphics g) { 1319 super.paintComponent(g); 1320 Graphics2D g2 = (Graphics2D) g; 1321 1322 if ( (this.drawingBuff == null) || (this.fisheyes != null)) { 1323 this.drawingBuff = this.createImage(this.getWidth(), this.getHeight()); 1324 paintDrawingBuff(); 1325 } 1326 1327 if (this.drawingBuff != null) { 1328 g2.drawImage(this.drawingBuff, this.panningXForm, this); 1329 1330 //g.drawImage(this.drawingBuff,0,0,this); 1331 } 1332 else { 1333 g.fillRect(0, 0, this.getWidth(), this.getHeight()); 1334 } 1335 1336 if ( (this.indication != Integer.MIN_VALUE) && (shapeLayers.size() > 0) && 1337 (this.mode != this.MODE_PAN) && (this.fisheyes == null)) { 1338 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 1339 ls.renderObservation(indication, g2); 1340 } 1341 1342 drawSelectionBox(g2); 1343 1344 //this.toolTip.paint(g); 1345 if (this.drawTip && (exLabels != null) && 1346 (this.exLabels.isVisible() == false)) { 1347 drawTooltip(g2, this.tipText, this.mouseX2, this.mouseY2, Color.lightGray); 1348 } 1349 1350 if (exLabels != null) { 1351 exLabels.paint(g2, getBounds()); 1352 } 1353 } 1354 1355 /*** 1356 * Helper function to draw a "tooltip" on the given graphics object. 1357 * 1358 * @param g2 The Graphics2D Object to draw on. 1359 * @param text The (multiline) text of the tooltip. 1360 * @param x The x coordinate. 1361 * @param y The y coordinate. 1362 * @param col The background color. 1363 */ 1364 private void drawTooltip(Graphics2D g2, String text, int x, int y, Color col) { 1365 if (!drawTip) { 1366 return; 1367 } 1368 1369 int i; 1370 int mheight; 1371 int mwidth = 0; 1372 int numLines; 1373 int lineHeight; 1374 Font f = g2.getFont(); 1375 tipFont = f.deriveFont(9f); 1376 g2.setFont(tipFont); 1377 1378 StringTokenizer tok = new StringTokenizer(text, "\n"); 1379 numLines = tok.countTokens(); 1380 1381 String[] lines = new String[numLines]; 1382 1383 for (i = 0; i < numLines; i++) { 1384 lines[i] = tok.nextToken(); 1385 1386 int tempwidth = g2.getFontMetrics().stringWidth(lines[i]) + 6; 1387 1388 if (tempwidth > mwidth) { 1389 mwidth = tempwidth; 1390 } 1391 } 1392 1393 lineHeight = g2.getFontMetrics().getHeight(); 1394 mheight = (numLines * lineHeight) + 2; 1395 1396 x += 10; 1397 y += 10; 1398 1399 //if we are too close to the right side.... 1400 if ( (x + mwidth) > this.getWidth()) { 1401 x -= (mwidth + 20); 1402 } 1403 1404 //if we are too close to the bottom... 1405 if ( (y + mheight) > this.getHeight()) { 1406 y -= (mheight + 20); 1407 } 1408 1409 AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1410 0.7f); 1411 g2.setComposite(ac); 1412 1413 g2.setStroke(new BasicStroke(0.5f)); 1414 g2.setColor(new Color(0.2f, 0.2f, 0.2f, 0.7f)); 1415 1416 //g2.drawRect(x, y, mwidth, mheight); 1417 g2.setColor(col); 1418 g2.fillRect(x + 1, y + 1, mwidth - 1, mheight - 1); 1419 1420 g2.setColor(Color.black); 1421 1422 ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); 1423 g2.setComposite(ac); 1424 1425 for (i = 0; i < numLines; i++) { 1426 g2.drawString(lines[i], x + 3, (y + ( (i + 1) * lineHeight)) - 4); 1427 } 1428 } 1429 1430 private void drawSelectionBox(Graphics2D g2) { 1431 //draw selection box 1432 if (!drawBox) { 1433 return; 1434 } 1435 1436 Stroke tempStroke = g2.getStroke(); 1437 Stroke boxStroke = null; 1438 1439 if (this.mode == this.MODE_SELECT) { 1440 boxStroke = this.dashStroke; 1441 } 1442 else if ( (this.mode == this.MODE_ZOOM_IN) || 1443 (this.mode == this.MODE_ZOOM_OUT)) { 1444 boxStroke = this.solidStroke; 1445 } 1446 else { 1447 return; 1448 } 1449 1450 g2.setStroke(boxStroke); 1451 g2.setPaintMode(); 1452 g2.setColor(Color.black); 1453 g2.setXORMode(Color.white); 1454 1455 //let's take drawing the selection rectangle by cases 1456 //not elegant, but the alternative is introducing more class variables 1457 int selectX = 0; 1458 int selectY = 0; 1459 int selectWidth = 0; 1460 int selectHeight = 0; 1461 1462 if ( (mouseX1 <= mouseX2) && (mouseY1 <= mouseY2)) { 1463 selectX = mouseX1; 1464 selectY = mouseY1; 1465 selectWidth = mouseX2 - mouseX1; 1466 selectHeight = mouseY2 - mouseY1; 1467 } 1468 1469 if ( (mouseX2 < mouseX1) && (mouseY1 <= mouseY2)) { 1470 selectX = mouseX2; 1471 selectY = mouseY1; 1472 selectWidth = mouseX1 - mouseX2; 1473 selectHeight = mouseY2 - mouseY1; 1474 } 1475 1476 if ( (mouseX1 <= mouseX2) && (mouseY2 < mouseY1)) { 1477 selectX = mouseX1; 1478 selectY = mouseY2; 1479 selectWidth = mouseX2 - mouseX1; 1480 selectHeight = mouseY1 - mouseY2; 1481 } 1482 1483 if ( (mouseX2 < mouseX1) && (mouseY2 < mouseY1)) { 1484 selectX = mouseX2; 1485 selectY = mouseY2; 1486 selectWidth = mouseX1 - mouseX2; 1487 selectHeight = mouseY1 - mouseY2; 1488 } 1489 1490 g2.drawRect(selectX, selectY, selectWidth, selectHeight); 1491 g2.setStroke(tempStroke); 1492 } 1493 1494 //start excentric labeling stuff 1495 private void initExcentricLabels() { 1496 if (exLabels != null) { 1497 this.exLabels = new ExcentricLabels(); 1498 exLabels.setComponent(this); 1499 exLabels.setOpaque(true); 1500 1501 Color halfWhite = new Color(255, 255, 255, 123); 1502 exLabels.setBackgroundColor(halfWhite); 1503 this.addMouseListener(exLabels); 1504 } 1505 } 1506 1507 public String getObservationLabel(int i) { 1508 String[] labels = this.dataSet.getObservationNames(); 1509 String label = labels[i]; 1510 1511 return label; 1512 } 1513 1514 public Shape getShapeAt(int i) { 1515 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 1516 Shape shp = ls.getSpatialData()[i]; 1517 1518 return shp; 1519 } 1520 1521 public int[] pickAll(Rectangle2D hitBox) { 1522 LayerShape ls = (LayerShape)this.shapeLayers.get(this.activeLayer); 1523 int[] selObs = ls.findSelection(hitBox); 1524 1525 return selObs; 1526 } 1527 1528 //end excentric labeling stuff 1529 1530 /*** 1531 * implements ActionListener 1532 */ 1533 public void addActionListener(ActionListener l) { 1534 listenerList.add(ActionListener.class, l); 1535 } 1536 1537 /*** 1538 * removes an ActionListener from the button 1539 */ 1540 public void removeActionListener(ActionListener l) { 1541 listenerList.remove(ActionListener.class, l); 1542 } 1543 1544 /*** 1545 * Notify all listeners that have registered interest for 1546 * notification on this event type. The event instance 1547 * is lazily created using the parameters passed into 1548 * the fire method. 1549 * @see EventListenerList 1550 */ 1551 protected void fireActionPerformed(String command) { 1552 // Guaranteed to return a non-null array 1553 Object[] listeners = listenerList.getListenerList(); 1554 ActionEvent e = null; 1555 1556 // Process the listeners last to first, notifying 1557 // those that are interested in this event 1558 for (int i = listeners.length - 2; i >= 0; i -= 2) { 1559 if (listeners[i] == ActionListener.class) { 1560 // Lazily create the event: 1561 if (e == null) { 1562 e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command); 1563 } 1564 1565 ( (ActionListener) listeners[i + 1]).actionPerformed(e); 1566 } 1567 } 1568 } 1569 1570 /*** 1571 * adds an IndicationListener 1572 */ 1573 public void addIndicationListener(IndicationListener l) { 1574 listenerList.add(IndicationListener.class, l); 1575 } 1576 1577 /*** 1578 * removes an IndicationListener from the component 1579 */ 1580 public void removeIndicationListener(IndicationListener l) { 1581 listenerList.remove(IndicationListener.class, l); 1582 } 1583 1584 /*** 1585 * Notify all listeners that have registered interest for 1586 * notification on this event type. The event instance 1587 * is lazily created using the parameters passed into 1588 * the fire method. 1589 * @see EventListenerList 1590 */ 1591 private void fireIndicationChanged(int newIndication, int xClass, int yClass) { 1592 // Guaranteed to return a non-null array 1593 Object[] listeners = listenerList.getListenerList(); 1594 IndicationEvent e = null; 1595 1596 // Process the listeners last to first, notifying 1597 // those that are interested in this event 1598 for (int i = listeners.length - 2; i >= 0; i -= 2) { 1599 if (listeners[i] == IndicationListener.class) { 1600 // Lazily create the event: 1601 if (e == null) { 1602 e = new IndicationEvent(this, newIndication, xClass, yClass); 1603 } 1604 1605 ( (IndicationListener) listeners[i + 1]).indicationChanged(e); 1606 } 1607 } //next i 1608 } 1609 1610 /*** 1611 * adds an SelectionListener 1612 */ 1613 public void addSelectionListener(SelectionListener l) { 1614 //System.out.println("mapCan, selection listeners = " + listenerList.getListenerCount(SelectionListener.class)); 1615 listenerList.add(SelectionListener.class, l); 1616 } 1617 1618 /*** 1619 * removes an SelectionListener from the component 1620 */ 1621 public void removeSelectionListener(SelectionListener l) { 1622 //System.out.println("mapCan, removing a selection listener"); 1623 listenerList.remove(SelectionListener.class, l); 1624 } 1625 1626 /*** 1627 * Notify all listeners that have registered interest for 1628 * notification on this event type. The event instance 1629 * is lazily created using the parameters passed into 1630 * the fire method. 1631 * @see EventListenerList 1632 */ 1633 private void fireSelectionChanged(int[] newSelection) { 1634 // Guaranteed to return a non-null array 1635 Object[] listeners = listenerList.getListenerList(); 1636 SelectionEvent e = null; 1637 1638 // Process the listeners last to first, notifying 1639 // those that are interested in this event 1640 for (int i = listeners.length - 2; i >= 0; i -= 2) { 1641 if (listeners[i] == SelectionListener.class) { 1642 // Lazily create the event: 1643 if (e == null) { 1644 e = new SelectionEvent(this, newSelection); 1645 } 1646 1647 ( (SelectionListener) listeners[i + 1]).selectionChanged(e); 1648 } 1649 } //next i 1650 } 1651 1652 /*** 1653 * adds an SpatialExtentListener 1654 */ 1655 public void addSpatialExtentListener(SpatialExtentListener l) { 1656 listenerList.add(SpatialExtentListener.class, l); 1657 } 1658 1659 /*** 1660 * removes an SpatialExtentListener from the component 1661 */ 1662 public void removeSpatialExtentListener(SpatialExtentListener l) { 1663 listenerList.remove(SpatialExtentListener.class, l); 1664 } 1665 1666 /*** 1667 * Notify all listeners that have registered interest for 1668 * notification on this event type. The event instance 1669 * is lazily created using the parameters passed into 1670 * the fire method. 1671 * @see EventListenerList 1672 */ 1673 private void fireSpatialExtentChanged(Rectangle2D newSpatialExtent) { 1674 // Guaranteed to return a non-null array 1675 Object[] listeners = listenerList.getListenerList(); 1676 SpatialExtentEvent e = null; 1677 1678 // Process the listeners last to first, notifying 1679 // those that are interested in this event 1680 for (int i = listeners.length - 2; i >= 0; i -= 2) { 1681 if (listeners[i] == SpatialExtentListener.class) { 1682 // Lazily create the event: 1683 if (e == null) { 1684 e = new SpatialExtentEvent(this, newSpatialExtent); 1685 } 1686 1687 ( (SpatialExtentListener) listeners[i + 1]).spatialExtentChanged(e); 1688 } 1689 } //next i 1690 } 1691 }

This page was automatically generated by Maven