1 package jspecview.common; 2 3 4 import java.util.Hashtable; 5 6 import java.util.Map; 7 8 //import javajs.J2SRequireImport; 9 import javajs.api.GenericColor; 10 import javajs.util.BS; 11 import javajs.util.DF; 12 import javajs.util.Lst; 13 14 import org.jmol.api.GenericGraphics; 15 import org.jmol.util.Font; 16 import org.jmol.util.Logger; 17 import javajs.util.PT; 18 19 import jspecview.api.AnnotationData; 20 import jspecview.api.JSVPanel; 21 import jspecview.api.VisibleInterface; 22 import jspecview.common.Annotation.AType; 23 import jspecview.common.PanelData.LinkMode; 24 import jspecview.common.Spectrum.IRMode; 25 import jspecview.dialog.JSVDialog; 26 27 // should not be necessary, but "x.isDialog()" is requiring it. 28 29 //@J2SRequireImport(jspecview.dialog.JSVDialog.class) 30 class GraphSet implements XYScaleConverter { 31 32 private final static int ARROW_RESET = -1; 33 private final static int ARROW_HOME = 0; 34 private final static int ARROW_LEFT = 1; 35 private final static int ARROW_RIGHT = 2; 36 private final static int ARROW_UP = 3; 37 private final static int ARROW_DOWN = 4; 38 39 40 private GraphSet gs2dLinkedX; 41 private GraphSet gs2dLinkedY; 42 private boolean cur1D2Locked; 43 44 private Lst<Highlight> highlights = new Lst<Highlight>(); 45 Lst<Spectrum> spectra = new Lst<Spectrum>(); 46 47 private boolean isSplittable = true; 48 private boolean allowStacking = true; // not MS 49 50 private Lst<Annotation> annotations; 51 private MeasurementData selectedSpectrumMeasurements; 52 private MeasurementData selectedSpectrumIntegrals; 53 private Annotation lastAnnotation; 54 Measurement pendingMeasurement; 55 private Integral pendingIntegral; 56 private Lst<Spectrum> graphsTemp = new Lst<Spectrum>(); 57 private PlotWidget[] widgets; 58 private boolean isLinked; 59 private boolean haveSingleYScale; 60 61 final static double RT2 = Math.sqrt(2.0); 62 private static GenericColor veryLightGrey; 63 GraphSet(PanelData pd)64 GraphSet(PanelData pd) { 65 this.pd = pd; 66 jsvp = pd.jsvp; 67 g2d = pd.g2d; 68 } 69 70 /** 71 * iSpectrumMovedTo 72 * 73 * -- indicates spectrum moved to by user 74 * 75 * -- originally 0 76 * 77 * -- set in mouseMovedEvent only when nSpectra > 1: to iSpecBold if iSpecBold 78 * >= 0 or to -1 if showAllStacked or to getSplitPoint(yPixel) 79 * 80 * -- used in doZoom to set spectrum number for the new View object int iSpec 81 * = (iSpecBold >= 0 ? iSpecBold : iSpectrumMovedTo); 82 * 83 * -- used in drawAll to set the frame with the purple boundary int iSpec = 84 * (nSpectra == 1 ? 0 : !showAllStacked ? iSpectrumMovedTo : iSpecBold >= 0 ? 85 * iSpecBold : iSpectrumSelected); 86 * 87 */ 88 /* very */private int iSpectrumMovedTo; 89 setSpectrumMovedTo(int i)90 private int setSpectrumMovedTo(int i) { 91 return iSpectrumMovedTo = i; 92 } 93 94 /** 95 * iSpectrumClicked 96 * 97 * -- indicates spectrum clicked on by user -- when set T/F, also sets 98 * iSpectrumSelected T/F 99 * 100 * -- initially 0 101 * 102 * -- set in checkSpectrumClickEvent from PanelData.setCurrentGraphSet when 103 * nSplit == 1 && showAllStacked && isClick to spectrum number if on spectrum 104 * to -1 if click is not on a spectrum 105 * 106 * -- set in MouseClickEvent to previous spectrum clicked if it is a double 107 * click and the previous click was on a spectrum (also sets iSpectrumSelected 108 * in that case) 109 * 110 * -- set in processPendingMeasurement to index of previous pendingMeasurement 111 * when clickCount == 1 112 * 113 * -- used in mouseClickEvent if (iSpectrumClicked >= 0) { 114 * processPendingMeasurement(xPixel, yPixel, 2); } 115 * 116 * -- used in processPendingMeasurement pendingMeasurement = new 117 * Measurement(this, spectra.get(iSpectrumClicked)... 118 * 119 * 120 */ 121 /* very */private int iSpectrumClicked; 122 setSpectrumClicked(int i)123 private void setSpectrumClicked(int i) { 124 stackSelected = showAllStacked; 125 if (i < 0 || iSpectrumClicked != i) { 126 lastClickX = Double.NaN; 127 lastPixelX = Integer.MAX_VALUE; 128 } 129 iSpectrumClicked = setSpectrumSelected(setSpectrumMovedTo(i)); 130 } 131 132 /** 133 * iSpectrumSelected 134 * 135 * -- indicates current spectrum index selected -- by clicking Left/Right 136 * arrow -- by clicking on a spectrum -- 137 * 138 * -- originally -1 -- [0,nSpectra) indicates selected by clicking or peak 139 * picking -- Integer.MIN_VALUE -- none selected (and display none) 140 * 141 * -- set in PanelData.setCurrentGraphSet to currentSplitPoint when gs.nSplit 142 * > 1 && !gs.showAllStacked 143 * 144 * -- set in checkArrowLeftRightClick to selected spectrum if LEFT or RIGHT, 145 * or to -1 if HOME circle 146 * 147 * -- set in checkSpectrumClickEvent to spectrum clicked on, or to -1 if 148 * clicked off-spectrum 149 * 150 * -- set in mouseClickEvent along with iSpectrumClicked to the previously 151 * clicked spectrum when there is a double click. 152 * 153 * -- set in selectSpectrum based on filePath, type, and model to -1 if 154 * nSpectra == 1, or to the selected spectrum index if there is a match, or to 155 * Integer.MIN_VALUE if this isn't the current graph set and there is a 156 * selected spectrum already ?? 157 * 158 * -- used all over the place, in checkArrowLeftRightClick, 159 * checkArrowUpDownClick, checkSpectrum, doPlot, drawAll, drawPeakTabs, 160 * drawPlot, drawSpectrum, getFixedSelectedSpectrumIndex, isDrawNoSpectra, and 161 * selectSpectrum, 162 * 163 * -- used in doPlot to return true when a split is to be shown, or when 164 * showAllStacked is true, or when no spectrum is selected, or when this is 165 * the spectrum selected 166 * 167 */ 168 169 /* very */private int iSpectrumSelected = -1; 170 setSpectrumSelected(int i)171 private int setSpectrumSelected(int i) { 172 boolean isNew = (i != iSpectrumSelected); 173 iSpectrumSelected = i; 174 if (isNew) { 175 //hideAllDialogsExceptCurrent(); 176 getCurrentView(); 177 } 178 return iSpectrumSelected; 179 } 180 181 private boolean stackSelected = false; 182 private BS bsSelected = new BS(); 183 184 // needed by PanelData 185 186 ViewData viewData; 187 boolean reversePlot; 188 int nSplit = 1; 189 int yStackOffsetPercent = 0; 190 191 /** 192 * if nSplit > 1, then showAllStacked is false, but if nSplit == 1, then 193 * showAllStacked may be true or false 194 */ 195 boolean showAllStacked = true; 196 197 // needed by AwtGraphSet 198 199 Lst<ViewData> viewList; 200 ImageView imageView; 201 private PanelData pd; 202 private boolean sticky2Dcursor; 203 int nSpectra; // also needed by PanelData 204 closeDialogsExcept(AType type)205 void closeDialogsExcept(AType type) { 206 if (dialogs != null) 207 for (Map.Entry<String, AnnotationData> e : dialogs.entrySet()) { 208 AnnotationData ad = e.getValue(); 209 if (ad.isDialog() && (type == AType.NONE || ad.getAType() != type)) 210 ((JSVDialog) ad).setVisible(false); 211 } 212 } 213 dispose()214 void dispose() { 215 // for (int i = 0; i < spectra.size(); i++) 216 // spectra.get(i).dispose(); 217 spectra = null; 218 viewData = null; 219 viewList = null; 220 annotations = null; 221 lastAnnotation = null; 222 pendingMeasurement = null; 223 imageView = null; 224 graphsTemp = null; 225 widgets = null; 226 disposeImage(); 227 if (dialogs != null) 228 for (Map.Entry<String, AnnotationData> e : dialogs.entrySet()) { 229 AnnotationData ad = e.getValue(); 230 if (ad.isDialog()) 231 ((JSVDialog) ad).dispose(); 232 } 233 dialogs = null; 234 } 235 236 private double fracX = 1, fracY = 1, fX0 = 0, fY0 = 0; // take up full screen 237 238 private PlotWidget zoomBox1D, zoomBox2D, pin1Dx0, pin1Dx1, // ppm range -- 239 // horizontal bar 240 // on 1D spectrum 241 pin1Dy0, pin1Dy1, // y-scaling -- vertical bar on 1D spectrum and left of 242 // 2D when no 1D 243 pin1Dx01, pin1Dy01, // center pins for those 244 pin2Dx0, pin2Dx1, // ppm range -- horizontal bar on 2D spectrum 245 pin2Dy0, pin2Dy1, // subspectrum range -- vertical bar on 2D spectrum 246 pin2Dx01, pin2Dy01, // center pins for those 247 cur2Dx0, cur2Dx1, // 2D x cursors -- derived from pin1Dx0 and pin1Dx1 248 // values 249 cur1D2x1, cur1D2x2, // 1D cursors derived from 2D cursors 250 cur2Dy; // 2D y cursor -- points to currently displayed 1D slice 251 252 // for the 1D plot area: 253 private int xPixel0, yPixel0, xPixel1, yPixel1, xVArrows, xHArrows, yHArrows; 254 // for the overall panel section: 255 private int xPixel00, yPixel00, xPixel11, yPixel11, yPixel000; 256 private int xPixels, yPixels; 257 private int xPixel10, xPixels0; 258 259 private boolean allowStackedYScale = true; 260 private boolean drawXAxisLeftToRight; 261 private boolean xAxisLeftToRight = true; 262 private int iPreviousSpectrumClicked = -1; 263 private boolean haveSelectedSpectrum; 264 265 private boolean zoomEnabled; 266 private int currentZoomIndex; 267 268 private double lastClickX = Double.NaN; 269 private int lastPixelX = Integer.MAX_VALUE; 270 isDrawNoSpectra()271 private boolean isDrawNoSpectra() { 272 return (iSpectrumSelected == Integer.MIN_VALUE); 273 } 274 275 /** 276 * 277 * @return spectrum index selected by user from a peak pick, a spectrum pick 278 * with showAllStacked, but set to 0 if out of range 279 */ 280 getFixedSelectedSpectrumIndex()281 private int getFixedSelectedSpectrumIndex() { 282 return Math.max(iSpectrumSelected, 0); 283 } 284 285 private int height; 286 private int width; 287 private int right; 288 private int top; 289 private int left; 290 private int bottom; 291 292 private PeakInfo piMouseOver; 293 private final Coordinate coordTemp = new Coordinate(); 294 private final static int minNumOfPointsForZoom = 3; 295 296 final private int FONT_PLAIN = 0; 297 final private int FONT_BOLD = 1; 298 final private int FONT_ITALIC = 2; 299 300 private boolean is2DSpectrum; 301 getSpectrum()302 Spectrum getSpectrum() { 303 // could be a 2D spectrum or a set of mass spectra 304 return getSpectrumAt(getFixedSelectedSpectrumIndex()) 305 .getCurrentSubSpectrum(); 306 } 307 308 /** 309 * Returns the <code>Spectrum</code> at the specified index 310 * 311 * @param index 312 * the index of the <code>Spectrum</code> 313 * @return the <code>Spectrum</code> at the specified index 314 */ getSpectrumAt(int index)315 Spectrum getSpectrumAt(int index) { 316 return spectra.get(index); 317 } 318 getSpectrumIndex(Spectrum spec)319 int getSpectrumIndex(Spectrum spec) { 320 for (int i = spectra.size(); --i >= 0;) 321 if (spectra.get(i) == spec) 322 return i; 323 return -1; 324 } 325 addSpec(Spectrum spec)326 private void addSpec(Spectrum spec) { 327 spectra.addLast(spec); 328 nSpectra++; 329 } 330 splitStack(boolean doSplit)331 void splitStack(boolean doSplit) { 332 if (doSplit && isSplittable) { 333 nSplit = nSpectra; 334 showAllStacked = false; 335 setSpectrumClicked(iSpectrumSelected); 336 pd.currentSplitPoint = iSpectrumSelected; 337 } else { 338 nSplit = 1; 339 showAllStacked = allowStacking && !doSplit; 340 setSpectrumClicked(iSpectrumSelected); 341 } 342 stackSelected = false; 343 setFractionalPositions(pd, pd.graphSets, LinkMode.NONE); 344 pd.setTaintedAll(); 345 } 346 setPositionForFrame(int iSplit)347 private void setPositionForFrame(int iSplit) { 348 if (iSplit < 0) 349 iSplit = 0; 350 int marginalHeight = height - 50; 351 xPixel00 = (int) (width * fX0); 352 xPixel11 = (int) (xPixel00 + width * fracX - 1); 353 xHArrows = xPixel00 + 25; 354 xVArrows = xPixel11 - right / 2; 355 xPixel0 = xPixel00 + (int) ( left * (1 - fX0)); 356 xPixel10 = xPixel1 = xPixel11 - right; 357 xPixels0 = xPixels = xPixel1 - xPixel0 + 1; 358 // only the very top spectrum needs an offset 359 // -- to move it below the coordinate string 360 yPixel000 = (fY0 == 0 ? 25 : 0) + (int) (height * fY0); 361 yPixel00 = yPixel000 + (int) (marginalHeight * fracY * iSplit); 362 yPixel11 = yPixel00 + (int) (marginalHeight * fracY) - 1; 363 yHArrows = yPixel11 - 12; 364 yPixel0 = yPixel00 + top / 2; 365 yPixel1 = yPixel11 - bottom / 2; 366 yPixels = yPixel1 - yPixel0 + 1; 367 if (imageView != null && is2DSpectrum) { 368 setImageWindow(); 369 if (pd.display1D) { 370 double widthRatio = (pd.display1D ? 1.0 371 * (xPixels0 - imageView.xPixels) / xPixels0 : 1); 372 xPixels = (int) Math.floor(widthRatio * xPixels0 * 0.8); 373 xPixel1 = xPixel0 + xPixels - 1; 374 } else { 375 xPixels = 0; 376 xPixel1 = imageView.xPixel0 - 30; 377 } 378 } 379 } 380 hasPoint(int xPixel, int yPixel)381 private boolean hasPoint(int xPixel, int yPixel) { 382 return (xPixel >= xPixel00 && xPixel <= xPixel11 && yPixel >= yPixel000 && yPixel <= yPixel11 383 * nSplit); 384 } 385 isInPlotRegion(int xPixel, int yPixel)386 private boolean isInPlotRegion(int xPixel, int yPixel) { 387 return (xPixel >= xPixel0 && xPixel <= xPixel1 && yPixel >= yPixel0 && yPixel <= yPixel1); 388 } 389 getSplitPoint(int yPixel)390 int getSplitPoint(int yPixel) { 391 return Math.max(0, Math.min(((yPixel - yPixel000) / (yPixel11 - yPixel00)), 392 nSplit - 1)); 393 } 394 isSplitWidget(int xPixel, int yPixel)395 private boolean isSplitWidget(int xPixel, int yPixel) { 396 return isFrameBox(xPixel, yPixel, splitterX, splitterY); 397 // return (isSplittable && xPixel >= xPixel11 - 20 && yPixel >= yPixel00 + 1 398 ////&& xPixel <= xPixel11 - 10 && yPixel <= yPixel00 + 11); 399 } 400 isCloserWidget(int xPixel, int yPixel)401 private boolean isCloserWidget(int xPixel, int yPixel) { 402 return isFrameBox(xPixel, yPixel, closerX, closerY); 403 } 404 405 406 407 /** 408 * Initializes the graph set 409 * @param startIndex 410 * @param endIndex 411 */ 412 initGraphSet(int startIndex, int endIndex)413 private void initGraphSet(int startIndex, int endIndex) { 414 if (veryLightGrey == null) 415 veryLightGrey = g2d.getColor3(200, 200, 200); 416 setPlotColors(ColorParameters.defaultPlotColors); 417 xAxisLeftToRight = getSpectrumAt(0).shouldDisplayXAxisIncreasing(); 418 setDrawXAxis(); 419 int[] startIndices = new int[nSpectra]; 420 int[] endIndices = new int[nSpectra]; 421 bsSelected.setBits(0, nSpectra); 422 // null means use standard offset spectrumOffsets = new int[nSpectra]; 423 allowStackedYScale = true; 424 if (endIndex <= 0) 425 endIndex = Integer.MAX_VALUE; 426 isSplittable = (nSpectra > 1);// for now, could be: 427 // getSpectrumAt(0).isSplitable(); 428 allowStacking = (spectra.get(0).isStackable()); 429 showAllStacked = allowStacking && (nSpectra > 1); 430 for (int i = 0; i < nSpectra; i++) { 431 int iLast = spectra.get(i).getXYCoords().length - 1; 432 startIndices[i] = Coordinate.intoRange(startIndex, 0, iLast); 433 endIndices[i] = Coordinate.intoRange(endIndex, 0, iLast); 434 allowStackedYScale &= (spectra.get(i).getYUnits().equals( 435 spectra.get(0).getYUnits()) 436 && spectra.get(i).getUserYFactor() == spectra.get(0).getUserYFactor() 437 ); 438 } 439 getView(0, 0, 0, 0, startIndices, endIndices, null, null); 440 viewList = new Lst<ViewData>(); 441 viewList.addLast(viewData); 442 } 443 getView(double x1, double x2, double y1, double y2, int[] startIndices, int[] endIndices, ScaleData[] viewScales, ScaleData[] yScales)444 private synchronized void getView(double x1, double x2, double y1, double y2, 445 int[] startIndices, int[] endIndices, ScaleData[] viewScales, ScaleData[] yScales) { 446 Lst<Spectrum> graphs = (graphsTemp.size() == 0 ? spectra : graphsTemp); 447 Lst<Spectrum> subspecs = getSpectrumAt(0).getSubSpectra(); 448 boolean dontUseSubspecs = (subspecs == null || subspecs.size() == 2 449 && subspecs.get(1).isImaginary()); 450 // NMR real/imaginary 451 boolean is2D = !getSpectrumAt(0).is1D(); 452 boolean useFirstSubSpecOnly = false; 453 if (is2D && useFirstSubSpecOnly || dontUseSubspecs && y1 == y2) { 454 // 2D spectrum or startup 455 graphs = spectra; 456 } else if (y1 == y2) { 457 // start up, forced subsets (too many spectra) 458 viewData = new ViewData(subspecs, y1, y2, getSpectrum().isContinuous()); 459 graphs = null; 460 } 461 if (graphs != null) { 462 viewData = new ViewData(graphs, y1, y2, startIndices, endIndices, 463 getSpectrumAt(0).isContinuous(), is2D); 464 if (x1 != x2) 465 getScale().setXRange(x1, x2); 466 } 467 if (viewScales != null) { 468 ScaleData.copyScaleFactors(viewScales, viewData.getScaleData()); 469 if (yScales != null) 470 ScaleData.copyYScales(yScales, viewData.getScaleData()); 471 getCurrentView(); 472 } 473 } 474 isNearby(Coordinate a1, Coordinate a2, XYScaleConverter c, int range)475 private boolean isNearby(Coordinate a1, Coordinate a2, XYScaleConverter c, 476 int range) { 477 double x = a1.getXVal(); 478 int xp1 = c.toPixelX(x); 479 int yp1 = toPixelY(a1.getYVal()); 480 x = a2.getXVal(); 481 int xp2 = c.toPixelX(x); 482 int yp2 = toPixelY(a2.getYVal()); 483 return (Math.abs(xp1 - xp2) + Math.abs(yp1 - yp2) < range); 484 } 485 486 /** 487 * Displays plot in reverse if val is true 488 * 489 * @param val 490 * true or false 491 */ setReversePlot(boolean val)492 void setReversePlot(boolean val) { 493 reversePlot = val; 494 if (reversePlot) 495 closeDialogsExcept(AType.NONE); 496 setDrawXAxis(); 497 } 498 setDrawXAxis()499 private void setDrawXAxis() { 500 drawXAxisLeftToRight = xAxisLeftToRight ^ reversePlot; 501 for (int i = 0; i < spectra.size(); i++) 502 (spectra.get(i)).setExportXAxisDirection(drawXAxisLeftToRight); 503 } 504 isInTopBar(int xPixel, int yPixel)505 private boolean isInTopBar(int xPixel, int yPixel) { 506 return (xPixel == fixX(xPixel) && yPixel > pin1Dx0.yPixel0 - 2 && yPixel < pin1Dx0.yPixel1); 507 } 508 isInTopBar2D(int xPixel, int yPixel)509 private boolean isInTopBar2D(int xPixel, int yPixel) { 510 return (imageView != null && xPixel == imageView.fixX(xPixel) 511 && yPixel > pin2Dx0.yPixel0 - 2 && yPixel < pin2Dx0.yPixel1); 512 } 513 isInRightBar(int xPixel, int yPixel)514 private boolean isInRightBar(int xPixel, int yPixel) { 515 return (yPixel == fixY(yPixel) && xPixel > pin1Dy0.xPixel1 && xPixel < 516 pin1Dy0.xPixel0 + 2); 517 } 518 isInRightBar2D(int xPixel, int yPixel)519 private boolean isInRightBar2D(int xPixel, int yPixel) { 520 return (imageView != null && yPixel == fixY(yPixel) 521 && xPixel > pin2Dy0.xPixel1 && xPixel < pin2Dy0.xPixel0 + 2); 522 } 523 toX0(int xPixel)524 private double toX0(int xPixel) { 525 return viewList.get(0).getScale().toX0(fixX(xPixel), xPixel0, xPixel1, drawXAxisLeftToRight); 526 } 527 toY0(int yPixel)528 private double toY0(int yPixel) { 529 return viewList.get(0).getScale().toY0(fixY(yPixel), yPixel0, yPixel1); 530 } 531 532 @Override toX(int xPixel)533 public double toX(int xPixel) { 534 if (imageView != null && imageView.isXWithinRange(xPixel)) 535 return imageView.toX(xPixel); 536 return getScale().toX(fixX(xPixel), xPixel1, drawXAxisLeftToRight); 537 } 538 539 @Override toY(int yPixel)540 public double toY(int yPixel) { 541 return getScale().toY(yPixel, yPixel0); 542 } 543 544 @Override toPixelX(double dx)545 public int toPixelX(double dx) { 546 return getScale().toPixelX(dx, xPixel0, xPixel1, drawXAxisLeftToRight); 547 } 548 549 @Override toPixelY(double yVal)550 public int toPixelY(double yVal) { 551 return getScale().toPixelY(yVal, yPixel1); 552 } 553 toPixelX0(double x)554 private int toPixelX0(double x) { 555 return viewList.get(0).getScale().toPixelX0(x, xPixel0, xPixel1, drawXAxisLeftToRight); 556 } 557 toPixelY0(double y)558 private int toPixelY0(double y) { 559 return fixY(viewList.get(0).getScale().toPixelY0(y, yPixel0, yPixel1)); 560 } 561 562 @Override fixX(int xPixel)563 public int fixX(int xPixel) { 564 return Coordinate.intoRange(xPixel, xPixel0, xPixel1); 565 } 566 567 @Override fixY(int yPixel)568 public int fixY(int yPixel) { 569 return Coordinate.intoRange(yPixel, yPixel0, yPixel1); 570 } 571 572 @Override getXPixel0()573 public int getXPixel0() { 574 return xPixel0; 575 } 576 577 @Override getXPixels()578 public int getXPixels() { 579 return xPixels; 580 } 581 582 @Override getYPixels()583 public int getYPixels() { 584 return yPixels; 585 } 586 587 @Override getScale()588 public ScaleData getScale() { 589 return viewData.getScale(); 590 } 591 toPixelYint(double yVal)592 private int toPixelYint(double yVal) { 593 return yPixel1 594 - (int) (Double.isNaN(yVal) ? Integer.MIN_VALUE : yPixels * yVal); 595 } 596 findAnnotation2D(Coordinate xy)597 private Annotation findAnnotation2D(Coordinate xy) { 598 for (int i = annotations.size(); --i >= 0;) { 599 Annotation a = annotations.get(i); 600 if (isNearby(a, xy, imageView, 10)) 601 return a; 602 } 603 return null; 604 } 605 addAnnotation(Annotation annotation, boolean isToggle)606 private void addAnnotation(Annotation annotation, boolean isToggle) { 607 if (annotations == null) 608 annotations = new Lst<Annotation>(); 609 boolean removed = false; 610 for (int i = annotations.size(); --i >= 0;) 611 if (annotation.is2D ? isNearby(annotations.get(i), annotation, imageView, 612 10) : annotation.equals(annotations.get(i))) { 613 removed = true; 614 annotations.removeItemAt(i); 615 } 616 if (annotation.text.length() > 0 && (!removed || !isToggle)) 617 annotations.addLast(annotation); 618 } 619 setImageWindow()620 private void setImageWindow() { 621 imageView.setPixelWidthHeight((int) ((pd.display1D ? 0.6 : 1) * xPixels0), 622 yPixels); 623 imageView.setXY0(getSpectrumAt(0), (int) Math.floor(xPixel10 - imageView.xPixels), yPixel0); 624 } 625 626 private Measurement selectedMeasurement; 627 private Integral selectedIntegral; 628 629 private double lastXMax = Double.NaN; 630 private int lastSpecClicked = -1; 631 632 // private double getPeakCenter() { 633 // if (nSpectra > 1 && iSpectrumClicked < 0 || Double.isNaN(lastClickX)) 634 // return Double.NaN; 635 // return getSpectrum().findXForPeakNearest(lastClickX); 636 // } 637 findNearestMaxMin()638 private boolean findNearestMaxMin() { 639 if (nSpectra > 1 && iSpectrumClicked < 0) 640 return false; 641 xValueMovedTo = getSpectrum().findXForPeakNearest(xValueMovedTo); 642 setXPixelMovedTo(xValueMovedTo, Double.MAX_VALUE, 0, 0); 643 return !Double.isNaN(xValueMovedTo); 644 } 645 setXPixelMovedTo(double x1, double x2, int xPixel1, int xPixel2)646 void setXPixelMovedTo(double x1, double x2, int xPixel1, int xPixel2) { 647 if (x1 == Double.MAX_VALUE && x2 == Double.MAX_VALUE) { 648 xPixelMovedTo = xPixel1; 649 xPixelMovedTo2 = xPixel2; 650 if (isLinked && sticky2Dcursor) { 651 pd.setlinkedXMove(this, toX(xPixelMovedTo), false); 652 } 653 return; 654 } 655 if (x1 != Double.MAX_VALUE) { 656 xPixelMovedTo = toPixelX(x1); 657 if (fixX(xPixelMovedTo) != xPixelMovedTo) 658 xPixelMovedTo = -1; 659 xPixelMovedTo2 = -1; 660 if (x1 != 1e10) 661 setSpectrumClicked(getFixedSelectedSpectrumIndex()); 662 } 663 if (x2 != Double.MAX_VALUE) { 664 xPixelMovedTo2 = toPixelX(x2); 665 } 666 } 667 processPendingMeasurement(int xPixel, int yPixel, int clickCount)668 private void processPendingMeasurement(int xPixel, int yPixel, int clickCount) { 669 if (!isInPlotRegion(xPixel, yPixel) || is2dClick(xPixel, yPixel)) { 670 pendingMeasurement = null; 671 return; 672 } 673 double x = toX(xPixel); 674 double y = toY(yPixel); 675 double x0 = x; 676 Measurement m; 677 switch (clickCount) { 678 case 0: // move 679 pendingMeasurement.setPt2(toX(xPixel), toY(yPixel)); 680 break; 681 case 3: // ctrl-click 682 case 2: // 1st double-click 683 if (iSpectrumClicked < 0) 684 return; 685 Spectrum spec = spectra.get(iSpectrumClicked); 686 setScale(iSpectrumClicked); 687 if (clickCount == 3) { 688 } else { 689 m = findMeasurement(selectedSpectrumMeasurements, xPixel, yPixel, Measurement.PT_XY1); 690 if (m != null) { 691 x = m.getXVal(); 692 y = m.getYVal(); 693 } else if ((m = findMeasurement(selectedSpectrumMeasurements, xPixel, 694 yPixel, Measurement.PT_XY2)) != null) { 695 x = m.getXVal2(); 696 y = m.getYVal2(); 697 } else { 698 x = getNearestPeak(spec, x, y); 699 } 700 } 701 pendingMeasurement = new Measurement().setM1(x, y, spec); 702 pendingMeasurement.setPt2(x0, y); 703 pd.setTaintedAll(); 704 pd.repaint(); 705 break; 706 case 1: // single click -- save and continue 707 case -2: // second double-click -- save and quit 708 case -3: // second ctrl-click 709 boolean isOK = (pendingMeasurement != null && isVisible(getDialog(AType.Measurements, -1))); 710 while (isOK) { 711 setScale(getSpectrumIndex(pendingMeasurement.spec)); 712 if (clickCount != 3) { 713 if (!findNearestMaxMin()) { 714 isOK = false; 715 break; 716 } 717 xPixel = xPixelMovedTo; 718 } 719 x = toX(xPixel); 720 y = toY(yPixel); 721 pendingMeasurement.setPt2(x, y); 722 if (pendingMeasurement.text.length() == 0) { 723 isOK = false; 724 break; 725 } 726 setMeasurement(pendingMeasurement); 727 if (clickCount != 1) { 728 isOK = false; 729 break; 730 } 731 setSpectrumClicked(getSpectrumIndex(pendingMeasurement.spec)); 732 pendingMeasurement = new Measurement().setM1(x, y, 733 pendingMeasurement.spec); 734 break; 735 } 736 if (!isOK) 737 pendingMeasurement = null; 738 pd.setTaintedAll(); 739 pd.repaint(); 740 break; 741 case 5: // (old) control-click 742 if (findNearestMaxMin()) { 743 int iSpec = getFixedSelectedSpectrumIndex(); 744 if (Double.isNaN(lastXMax) || lastSpecClicked != iSpec 745 || pendingMeasurement == null) { 746 lastXMax = xValueMovedTo; 747 lastSpecClicked = iSpec; 748 pendingMeasurement = new Measurement().setM1(xValueMovedTo, 749 yValueMovedTo, spectra.get(iSpec)); 750 } else { 751 pendingMeasurement.setPt2(xValueMovedTo, yValueMovedTo); 752 if (pendingMeasurement.text.length() > 0) 753 setMeasurement(pendingMeasurement); 754 pendingMeasurement = null; 755 lastXMax = Double.NaN; 756 } 757 } else { 758 lastXMax = Double.NaN; 759 } 760 break; 761 } 762 } 763 checkIntegralNormalizationClick(int xPixel, int yPixel)764 private boolean checkIntegralNormalizationClick(int xPixel, int yPixel) { 765 if (selectedSpectrumIntegrals == null) 766 return false; 767 Integral integral = (Integral) findMeasurement(selectedSpectrumIntegrals, 768 xPixel, yPixel, Measurement.PT_INT_LABEL); 769 if (integral == null) 770 return false; 771 selectedIntegral = integral; 772 pd.normalizeIntegral(); 773 updateDialog(AType.Integration, -1); 774 setSpectrumClicked(getSpectrumIndex(integral.spec)); 775 return true; 776 } 777 778 /** 779 * search for the nearest peak above/below the given y value 780 * 781 * @param spec 782 * 783 * @param x 784 * @param y 785 * @return nearest x value 786 */ getNearestPeak(Spectrum spec, double x, double y)787 private double getNearestPeak(Spectrum spec, double x, double y) { 788 double x0 = Coordinate.getNearestXWithYAbove(spec.getXYCoords(), x, y, spec 789 .isInverted(), false); 790 double x1 = Coordinate.getNearestXWithYAbove(spec.getXYCoords(), x, y, spec 791 .isInverted(), true); 792 return (Double.isNaN(x0) ? x1 : Double.isNaN(x1) ? x0 793 : Math.abs(x0 - x) < Math.abs(x1 - x) ? x0 : x1); 794 } 795 findMeasurement(MeasurementData measurements, int xPixel, int yPixel, int iPt)796 private Measurement findMeasurement(MeasurementData measurements, int xPixel, 797 int yPixel, int iPt) { 798 if (measurements == null || measurements.size() == 0) 799 return null; 800 if (iPt == Measurement.PT_ON_LINE) { 801 Measurement m = findMeasurement(measurements, xPixel, yPixel, Measurement.PT_ON_LINE1); 802 if (m != null || measurements.get(0) instanceof Integral) 803 return m; 804 return findMeasurement(measurements, xPixel, yPixel, Measurement.PT_ON_LINE2); // lower bar, 805 // near baseline 806 } 807 for (int i = measurements.size(); --i >= 0;) { 808 Measurement m = measurements.get(i); 809 int x1, x2, y1, y2; 810 if (m instanceof Integral) { 811 x1 = x2 = toPixelX(m.getXVal2()); 812 y1 = toPixelYint(m.getYVal()); 813 y2 = toPixelYint(m.getYVal2()); 814 } else { 815 x1 = toPixelX(m.getXVal()); 816 x2 = toPixelX(m.getXVal2()); 817 y1 = y2 = (iPt == -2 ? yPixel1 - 2 : toPixelY(m.getYVal())); 818 } 819 switch (iPt) { 820 case Measurement.PT_XY1: 821 if (Math.abs(xPixel - x1) + Math.abs(yPixel - y1) < 4) 822 return m; 823 break; 824 case Measurement.PT_XY2: 825 if (Math.abs(xPixel - x2) + Math.abs(yPixel - y2) < 4) 826 return m; 827 break; 828 case Measurement.PT_INT_LABEL: // label for integral 829 y1 = y2 = (y1 + y2) / 2; 830 x2 = x1 + 20; // estimate only 831 //$FALL-THROUGH$ 832 default: 833 case Measurement.PT_ON_LINE1: 834 case Measurement.PT_ON_LINE2: 835 if (isOnLine(xPixel, yPixel, x1, y1, x2, y2)) 836 return m; 837 break; 838 } 839 840 } 841 return null; 842 } 843 setMeasurement(Measurement m)844 private void setMeasurement(Measurement m) { 845 int iSpec = getSpectrumIndex(m.spec); 846 AnnotationData ad = getDialog(AType.Measurements, iSpec); 847 if (ad == null) 848 addDialog(iSpec, AType.Measurements, ad = new MeasurementData( 849 AType.Measurements, m.spec)); 850 ad.getData().addLast(m.copyM()); 851 updateDialog(AType.Measurements, -1); 852 } 853 checkArrowUpDownClick(int xPixel, int yPixel)854 private boolean checkArrowUpDownClick(int xPixel, int yPixel) { 855 boolean ok = false; 856 double f = (isArrowClick(xPixel, yPixel, ARROW_UP) ? RT2 857 : isArrowClick(xPixel, yPixel, ARROW_DOWN) ? 1 / RT2 : 0); 858 if (f != 0) { 859 if (nSplit > 1) 860 setSpectrumSelected(iSpectrumMovedTo); 861 if ((nSpectra == 1 || iSpectrumSelected >= 0) 862 && spectra.get(getFixedSelectedSpectrumIndex()).isTransmittance()) 863 f = 1 / f; 864 viewData.scaleSpectrum(imageView == null ? iSpectrumSelected : -2, f); 865 ok = true; 866 } else if (isArrowClick(xPixel, yPixel, ARROW_RESET)) { 867 resetViewCompletely(); 868 ok = true; 869 } 870 871 if (ok) { 872 if (imageView != null) { 873 update2dImage(false); 874 resetPinsFromView(); 875 } 876 pd.setTaintedAll(); 877 } 878 return ok; 879 } 880 resetViewCompletely()881 void resetViewCompletely() { 882 // reset button between up/down arrows; 883 clearViews(); 884 if (showAllStacked && !stackSelected) 885 closeDialogsExcept(AType.NONE); 886 viewData.resetScaleFactors(); 887 // did not work: view.setScaleFactor(iSpectrumSelected, 1); 888 updateDialogs(); 889 } 890 checkArrowLeftRightClick(int xPixel, int yPixel)891 private boolean checkArrowLeftRightClick(int xPixel, int yPixel) { 892 if (haveLeftRightArrows) { 893 int dx = (isArrowClick(xPixel, yPixel, ARROW_LEFT) ? -1 : isArrowClick( 894 xPixel, yPixel, ARROW_RIGHT) ? 1 : 0); 895 if (dx != 0) { 896 int i = iSpectrumSelected + dx; 897 if (i < 0) 898 i = nSpectra - 1; 899 setSpectrumClicked(i % nSpectra); 900 return true; 901 } 902 if (isArrowClick(xPixel, yPixel, ARROW_HOME)) { 903 if (showAllStacked) { 904 showAllStacked = false; 905 setSpectrumClicked(getFixedSelectedSpectrumIndex()); 906 return true; 907 } 908 showAllStacked = allowStacking; 909 setSpectrumSelected(-1); // better to stay with the one we have, not reset. 910 stackSelected = false; 911 } 912 } 913 return false; 914 } 915 isArrowClick(int xPixel, int yPixel, int type)916 private boolean isArrowClick(int xPixel, int yPixel, int type) { 917 int pt; 918 switch (type) { 919 case ARROW_UP: 920 case ARROW_DOWN: 921 case ARROW_RESET: 922 pt = (yPixel00 + yPixel11) / 2 923 + (type == ARROW_UP ? -1 : type == ARROW_DOWN ? 1 : 0) * 15; 924 return (Math.abs(xVArrows - xPixel) < 10 && Math.abs(pt - yPixel) < 10); 925 case ARROW_LEFT: 926 case ARROW_RIGHT: 927 case ARROW_HOME: 928 pt = xHArrows 929 + (type == ARROW_LEFT ? -1 : type == ARROW_RIGHT ? 1 : 0) 930 * 15; 931 return (Math.abs(pt - xPixel) < 10 && Math.abs(yHArrows - yPixel) < 10); 932 } 933 return false; 934 } 935 936 private static final int MIN_DRAG_PIXELS = 5;// fewer than this means no zoom 937 // or reset 938 939 private boolean inPlotMove; 940 private int xPixelMovedTo = -1; 941 private int xPixelMovedTo2 = -1; 942 private double yValueMovedTo; 943 private double xValueMovedTo; 944 private boolean haveLeftRightArrows; 945 private int xPixelPlot1; 946 private int xPixelPlot0; 947 private int yPixelPlot0; 948 private int yPixelPlot1; 949 private Double nextClickForSetPeak; 950 private int closerX, closerY, splitterX, splitterY; 951 setWidgetValueByUser(PlotWidget pw)952 private void setWidgetValueByUser(PlotWidget pw) { 953 String sval; 954 if (pw == cur2Dy) 955 sval = "" + imageView.toSubspectrumIndex(pw.yPixel0); 956 else if (pw == pin1Dx01) 957 sval = "" + Math.min(pin1Dx0.getXVal(), pin1Dx1.getXVal()) + " - " 958 + Math.max(pin1Dx0.getXVal(), pin1Dx1.getXVal()); 959 else if (pw == pin1Dy01) 960 sval = "" + Math.min(pin1Dy0.getYVal(), pin1Dy1.getYVal()) + " - " 961 + Math.max(pin1Dy0.getYVal(), pin1Dy1.getYVal()); 962 else if (pw == pin2Dx01) 963 sval = "" + Math.min(pin2Dx0.getXVal(), pin2Dx1.getXVal()) + " - " 964 + Math.max(pin2Dx0.getXVal(), pin2Dx1.getXVal()); 965 else if (pw == pin2Dy01) 966 sval = "" + (int) Math.min(pin2Dy0.getYVal(), pin2Dy1.getYVal()) + " - " 967 + (int) Math.max(pin2Dy0.getYVal(), pin2Dy1.getYVal()); 968 else 969 sval = "" + pw.getValue(); 970 sval = pd.getInput("New value?", "Set Slider", sval); 971 if (sval == null) 972 return; 973 sval = sval.trim(); 974 try { 975 if (pw == pin1Dx01 || pw == pin1Dy01 || pw == pin2Dx01 || pw == pin2Dy01) { 976 int pt = sval.indexOf("-", 1); 977 if (pt < 0) 978 return; 979 double val1 = Double.valueOf(sval.substring(0, pt)).doubleValue(); 980 double val2 = Double.valueOf(sval.substring(pt + 1)).doubleValue(); 981 if (pw == pin1Dx01) { 982 doZoom(val1, pin1Dy0.getYVal(), val2, pin1Dy1.getYVal(), true, false, 983 false, true, true); 984 } else if (pw == pin1Dy01) { // also for 2D Z-range zoom 985 doZoom(pin1Dx0.getXVal(), val1, pin1Dx1.getXVal(), val2, imageView == null, imageView == null, 986 false, false, true); 987 } else if (pw == pin2Dx01) { 988 imageView.setView0(imageView.toPixelX0(val1), pin2Dy0.yPixel0, 989 imageView.toPixelX0(val2), pin2Dy1.yPixel0); 990 doZoom(val1, pin1Dy0.getYVal(), val2, pin1Dy1.getYVal(), false, false, 991 false, true, true); 992 } else if (pw == pin2Dy01) { 993 imageView.setView0(pin2Dx0.xPixel0, imageView.toPixelY0(val1), 994 pin2Dx1.xPixel0, imageView.toPixelY0(val2)); 995 doZoom(imageView.toX(imageView.xPixel0), getScale().minY, imageView 996 .toX(imageView.xPixel0 + imageView.xPixels - 1), getScale().maxY, 997 false, false, false, false, true); 998 } 999 } else { 1000 double val = Double.valueOf(sval).doubleValue(); 1001 if (pw.isXtype) { 1002 double val2 = (pw == pin1Dx0 || pw == cur2Dx0 || pw == pin2Dx0 ? pin1Dx1 1003 .getXVal() 1004 : pin1Dx0.getXVal()); 1005 // 1006 doZoom(val, 0, val2, 0, !pw.is2D, false, 1007 false, true, true); 1008 } else if (pw == cur2Dy) { 1009 setCurrentSubSpectrum((int) val); 1010 // pd.repaint(); 1011 } else if (pw == pin2Dy0 || pw == pin2Dy1) { 1012 int val2 = (pw == pin2Dy0 ? pin2Dy1.yPixel0 : pin2Dy0.yPixel0); 1013 imageView.setView0(pin2Dx0.xPixel0, imageView.subIndexToPixelY((int) val), 1014 pin2Dx1.xPixel0, val2); 1015 // pd.repaint(); 1016 } else { 1017 // 1D y-zoom 1018 double val2 = (pw == pin1Dy0 ? pin1Dy1.getYVal() : pin1Dy0.getYVal()); 1019 doZoom(pin1Dx0.getXVal(), val, pin1Dx1.getXVal(), val2, imageView == null, imageView == null, 1020 false, false, true); 1021 } 1022 } 1023 } catch (Exception e) { 1024 } 1025 } 1026 removeAllHighlights(Spectrum spec)1027 private void removeAllHighlights(Spectrum spec) { 1028 if (spec == null) 1029 highlights.clear(); 1030 else 1031 for (int i = highlights.size(); --i >= 0;) 1032 if (highlights.get(i).spectrum == spec) 1033 highlights.removeItemAt(i); 1034 } 1035 setCoordClicked(int xPixel, double x, double y)1036 private Coordinate setCoordClicked(int xPixel, double x, double y) { 1037 if (y == 0) 1038 nextClickForSetPeak = null; 1039 if (Double.isNaN(x)) { 1040 pd.coordClicked = null; 1041 pd.coordsClicked = null; 1042 return null; 1043 } 1044 pd.coordClicked = new Coordinate().set(lastClickX = x, y); 1045 pd.coordsClicked = getSpectrum().getXYCoords(); 1046 pd.xPixelClicked = (lastPixelX = xPixel); 1047 return pd.coordClicked; 1048 } 1049 1050 /** 1051 * PlotWidgets are zoom boxes and slider points that are draggable. Some are 1052 * derived from others (center points and the 2D subIndex pointer). The first 1053 * time through, we have to create new pins. When the frame is resized, we 1054 * need to reset their positions along the slider based on their values, and 1055 * we need to also move the sliders to the right place. 1056 * @param needNewPins 1057 * @param subIndex 1058 * @param doDraw1DObjects 1059 */ setWidgets(boolean needNewPins, int subIndex, boolean doDraw1DObjects)1060 private void setWidgets(boolean needNewPins, int subIndex, 1061 boolean doDraw1DObjects) { 1062 if (needNewPins || pin1Dx0 == null) { 1063 if (zoomBox1D == null) 1064 newPins(); 1065 else 1066 resetPinPositions(); 1067 } 1068 setDerivedPins(subIndex); 1069 setPinSliderPositions(doDraw1DObjects); 1070 } 1071 1072 /** 1073 * Create new pins and set their default values. Note that we are making a 1074 * distinction between view.minY and view.minYOnScale. For X these are now the 1075 * same, but for Y they are not. This produces a nicer grid, but also an odd 1076 * jumpiness in the Y slider that is not totally predictable. 1077 * 1078 */ newPins()1079 private void newPins() { 1080 zoomBox1D = new PlotWidget("zoomBox1D"); 1081 pin1Dx0 = new PlotWidget("pin1Dx0"); 1082 pin1Dx1 = new PlotWidget("pin1Dx1"); 1083 pin1Dy0 = new PlotWidget("pin1Dy0"); 1084 pin1Dy1 = new PlotWidget("pin1Dy1"); 1085 pin1Dx01 = new PlotWidget("pin1Dx01"); 1086 pin1Dy01 = new PlotWidget("pin1Dy01"); 1087 cur1D2x1 = new PlotWidget("cur1D2x1"); 1088 cur1D2x1.color = ScriptToken.PEAKTABCOLOR; 1089 cur1D2x2 = new PlotWidget("cur1D2x2"); 1090 cur1D2x2.color = ScriptToken.PEAKTABCOLOR; 1091 if (imageView != null) { 1092 zoomBox2D = new PlotWidget("zoomBox2D"); 1093 // these pins only present when no 1D is present 1094 pin2Dx0 = new PlotWidget("pin2Dx0"); 1095 pin2Dx1 = new PlotWidget("pin2Dx1"); 1096 pin2Dy0 = new PlotWidget("pin2Dy0"); 1097 pin2Dy1 = new PlotWidget("pin2Dy1"); 1098 pin2Dx01 = new PlotWidget("pin2Dx01"); 1099 pin2Dy01 = new PlotWidget("pin2Dy01"); 1100 // these pins only present when 1D and 2D 1101 cur2Dx0 = new PlotWidget("cur2Dx0"); 1102 // these pins only present whenever 2D present 1103 cur2Dx1 = new PlotWidget("cur2Dx1"); 1104 cur2Dy = new PlotWidget("cur2Dy"); 1105 pin2Dy0.setY(0, imageView.toPixelY0(0)); 1106 int n = getSpectrumAt(0).getSubSpectra().size(); 1107 pin2Dy1.setY(n, imageView.toPixelY0(n)); 1108 } 1109 setWidgetX(pin1Dx0, getScale().minX); 1110 setWidgetX(pin1Dx1, getScale().maxX); 1111 setWidgetY(pin1Dy0, getScale().minY); 1112 setWidgetY(pin1Dy1, getScale().maxY); 1113 1114 widgets = new PlotWidget[] { zoomBox1D, zoomBox2D, pin1Dx0, pin1Dx01, 1115 pin1Dx1, pin1Dy0, pin1Dy01, pin1Dy1, pin2Dx0, pin2Dx01, pin2Dx1, 1116 pin2Dy0, pin2Dy01, pin2Dy1, cur2Dx0, cur2Dx1, cur2Dy, cur1D2x1, cur1D2x2 }; 1117 } 1118 setWidgetX(PlotWidget pw, double x)1119 private void setWidgetX(PlotWidget pw, double x) { 1120 pw.setX(x, toPixelX0(x)); 1121 } 1122 setWidgetY(PlotWidget pw, double y)1123 private void setWidgetY(PlotWidget pw, double y) { 1124 pw.setY(y, toPixelY0(y)); 1125 } 1126 resetPinsFromView()1127 private void resetPinsFromView() { 1128 if (pin1Dx0 == null) 1129 return; 1130 setWidgetX(pin1Dx0, getScale().minXOnScale); 1131 setWidgetX(pin1Dx1, getScale().maxXOnScale); 1132 setWidgetY(pin1Dy0, getScale().minYOnScale); 1133 setWidgetY(pin1Dy1, getScale().maxYOnScale); 1134 } 1135 1136 /** 1137 * use the pin values to find their positions along the slider 1138 * 1139 */ resetPinPositions()1140 private void resetPinPositions() { 1141 resetX(pin1Dx0); 1142 resetY(pin1Dy0); 1143 resetY(pin1Dy1); 1144 if (imageView == null) { 1145 if (gs2dLinkedX != null) 1146 resetX(cur1D2x1); 1147 if (gs2dLinkedY != null) 1148 resetX(cur1D2x2); 1149 } else { 1150 pin2Dy0.setY(pin2Dy0.getYVal(), imageView.toPixelY0(pin2Dy0.getYVal())); 1151 pin2Dy1.setY(pin2Dy1.getYVal(), imageView.toPixelY0(pin2Dy1.getYVal())); 1152 } 1153 } 1154 resetX(PlotWidget p)1155 private void resetX(PlotWidget p) { 1156 setWidgetX(p, p.getXVal()); 1157 } 1158 resetY(PlotWidget p)1159 private void resetY(PlotWidget p) { 1160 setWidgetY(p, p.getYVal()); 1161 } 1162 1163 /** 1164 * realign sliders to proper locations after resizing 1165 * 1166 * @param doDraw1DObjects 1167 * 1168 */ setPinSliderPositions(boolean doDraw1DObjects)1169 private void setPinSliderPositions(boolean doDraw1DObjects) { 1170 pin1Dx0.yPixel0 = pin1Dx1.yPixel0 = pin1Dx01.yPixel0 = yPixel0 - 5; 1171 pin1Dx0.yPixel1 = pin1Dx1.yPixel1 = pin1Dx01.yPixel1 = yPixel0; 1172 cur1D2x1.yPixel1 = cur1D2x2.yPixel1 = yPixel0 - 5; 1173 cur1D2x1.yPixel0 = cur1D2x2.yPixel0 = yPixel1 + 6; 1174 if (imageView == null) { 1175 pin1Dy0.xPixel0 = pin1Dy1.xPixel0 = pin1Dy01.xPixel0 = xPixel1 + 5; 1176 pin1Dy0.xPixel1 = pin1Dy1.xPixel1 = pin1Dy01.xPixel1 = xPixel1; 1177 } else { 1178 pin1Dy0.xPixel0 = pin1Dy1.xPixel0 = pin1Dy01.xPixel0 = imageView.xPixel1 + 15; 1179 pin1Dy0.xPixel1 = pin1Dy1.xPixel1 = pin1Dy01.xPixel1 = imageView.xPixel1 + 10; 1180 pin2Dx0.yPixel0 = pin2Dx1.yPixel0 = pin2Dx01.yPixel0 = yPixel0 - 5; 1181 pin2Dx0.yPixel1 = pin2Dx1.yPixel1 = pin2Dx01.yPixel1 = yPixel0; 1182 pin2Dy0.xPixel0 = pin2Dy1.xPixel0 = pin2Dy01.xPixel0 = imageView.xPixel1 + 5; 1183 pin2Dy0.xPixel1 = pin2Dy1.xPixel1 = pin2Dy01.xPixel1 = imageView.xPixel1; 1184 cur2Dx0.yPixel0 = cur2Dx1.yPixel0 = yPixel1 + 6; 1185 cur2Dx0.yPixel1 = cur2Dx1.yPixel1 = yPixel0 - 5; 1186 cur2Dx0.yPixel0 = cur2Dx1.yPixel0 = yPixel1 + 6; 1187 cur2Dx1.yPixel1 = cur2Dx1.yPixel1 = yPixel0 - 5; 1188 cur2Dy.xPixel0 = (doDraw1DObjects ? (xPixel1 + imageView.xPixel0) / 2 1189 : imageView.xPixel0 - 6); 1190 cur2Dy.xPixel1 = imageView.xPixel1 + 5; 1191 } 1192 } 1193 1194 /** 1195 * The center pins and the 2D subspectrum slider values are derived from other 1196 * data 1197 * 1198 * @param subIndex 1199 */ setDerivedPins(int subIndex)1200 private void setDerivedPins(int subIndex) { 1201 widgetsAreSet = true; 1202 if (gs2dLinkedX != null) 1203 cur1D2x1.setX(cur1D2x1.getXVal(), toPixelX(cur1D2x1.getXVal())); 1204 if (gs2dLinkedY != null) 1205 cur1D2x2.setX(cur1D2x2.getXVal(), toPixelX(cur1D2x2.getXVal())); 1206 1207 pin1Dx01.setX(0, (pin1Dx0.xPixel0 + pin1Dx1.xPixel0) / 2); 1208 pin1Dy01.setY(0, (pin1Dy0.yPixel0 + pin1Dy1.yPixel0) / 2); 1209 pin1Dx01.setEnabled(Math.min(pin1Dx0.xPixel0, pin1Dx1.xPixel0) > xPixel0 1210 || Math.max(pin1Dx0.xPixel0, pin1Dx1.xPixel0) < xPixel1); 1211 // note that toPixelY uses userYFactor, which is spectrum-dependent. 1212 // in a stacked set, this will be wrong. Perhaps no showing this pin1Dy01 1213 // then? 1214 pin1Dy01.setEnabled(Math.min(pin1Dy0.yPixel0, pin1Dy1.yPixel0) > Math.min( 1215 toPixelY(getScale().minY), toPixelY(getScale().maxY)) 1216 || Math.max(pin1Dy0.yPixel0, pin1Dy1.yPixel0) < Math.max( 1217 toPixelY(getScale().minY), toPixelY(getScale().maxY))); 1218 if (imageView == null) 1219 return; 1220 double x = pin1Dx0.getXVal(); 1221 cur2Dx0.setX(x, imageView.toPixelX(x)); 1222 x = pin1Dx1.getXVal(); 1223 cur2Dx1.setX(x, imageView.toPixelX(x)); 1224 1225 x = imageView.toX(imageView.xPixel0); 1226 pin2Dx0.setX(x, imageView.toPixelX0(x)); 1227 x = imageView.toX(imageView.xPixel1); 1228 pin2Dx1.setX(x, imageView.toPixelX0(x)); 1229 pin2Dx01.setX(0, (pin2Dx0.xPixel0 + pin2Dx1.xPixel0) / 2); 1230 1231 double y = imageView.imageHeight - 1 - imageView.yView1; 1232 pin2Dy0.setY(y, imageView.toPixelY0(y)); 1233 y = imageView.imageHeight - 1 - imageView.yView2; 1234 pin2Dy1.setY(y, imageView.toPixelY0(y)); 1235 pin2Dy01.setY(0, (pin2Dy0.yPixel0 + pin2Dy1.yPixel0) / 2); 1236 1237 cur2Dy.yPixel0 = cur2Dy.yPixel1 = imageView.subIndexToPixelY(subIndex); 1238 1239 pin2Dx01 1240 .setEnabled(Math.min(pin2Dx0.xPixel0, pin2Dx1.xPixel0) != imageView.xPixel0 1241 || Math.max(pin2Dx0.xPixel0, pin2Dx1.xPixel1) != imageView.xPixel1); 1242 pin2Dy01.setEnabled(Math.min(pin2Dy0.yPixel0, pin2Dy1.yPixel0) != yPixel0 1243 || Math.max(pin2Dy0.yPixel0, pin2Dy1.yPixel1) != yPixel1); 1244 } 1245 1246 /** 1247 * Zooms the spectrum between two coordinates 1248 * 1249 * @param initX 1250 * the X start coordinate of the zoom area 1251 * @param initY 1252 * the Y start coordinate of the zoom area 1253 * @param finalX 1254 * the X end coordinate of the zoom area 1255 * @param finalY 1256 * the Y end coordinate of the zoom area 1257 * @param is1D 1258 * TODO 1259 * @param is1DY TODO 1260 * @param checkRange 1261 * @param checkLinked TODO 1262 * @param addZoom 1263 */ 1264 synchronized void doZoom(double initX, double initY, double finalX, 1265 double finalY, boolean is1D, boolean is1DY, 1266 boolean checkRange, boolean checkLinked, boolean addZoom) { 1267 if (initX == finalX) { 1268 initX = getScale().minXOnScale; 1269 finalX = getScale().maxXOnScale; 1270 } else if (isLinked && checkLinked) 1271 pd.doZoomLinked(this, initX, finalX, addZoom, checkRange, is1D); 1272 if (initX > finalX) { 1273 double tempX = initX; 1274 initX = finalX; 1275 finalX = tempX; 1276 } 1277 if (initY > finalY) { 1278 double tempY = initY; 1279 initY = finalY; 1280 finalY = tempY; 1281 } 1282 1283 boolean is2DGrayScaleChange = (!is1D && imageView != null && (imageView.minZ != initY || imageView.maxZ != finalY)); 1284 1285 if (!zoomEnabled && !is2DGrayScaleChange) 1286 return; 1287 1288 // determine if the range of the area selected for zooming is within the 1289 // plot 1290 // area and if not ensure that it is 1291 1292 if (checkRange) { 1293 if (!getScale().isInRangeX(initX) 1294 && !getScale().isInRangeX(finalX)) 1295 return; 1296 if (!getScale().isInRangeX(initX)) { 1297 initX = getScale().minX; 1298 } else if (!getScale().isInRangeX(finalX)) { 1299 finalX = getScale().maxX; 1300 } 1301 } else { 1302 //viewData = viewList.get(0); 1303 } 1304 pd.setTaintedAll(); 1305 ScaleData[] viewScales = viewData.getScaleData(); 1306 int[] startIndices = new int[nSpectra]; 1307 int[] endIndices = new int[nSpectra]; 1308 graphsTemp.clear(); 1309 Lst<Spectrum> subspecs = getSpectrumAt(0).getSubSpectra(); 1310 boolean dontUseSubspecs = (subspecs == null || subspecs.size() == 2); 1311 // NMR real/imaginary 1312 boolean is2D = !getSpectrumAt(0).is1D(); 1313 if (!is2D && !dontUseSubspecs) { 1314 graphsTemp.addLast(getSpectrum()); 1315 if (!ScaleData.setDataPointIndices(graphsTemp, initX, finalX, 1316 minNumOfPointsForZoom, startIndices, endIndices)) 1317 return; 1318 } else { 1319 if (!ScaleData.setDataPointIndices(spectra, initX, finalX, 1320 minNumOfPointsForZoom, startIndices, endIndices)) 1321 return; 1322 } 1323 double y1 = initY; 1324 double y2 = finalY; 1325 boolean isXOnly = (y1 == y2); 1326 if (isXOnly) { 1327 double f = (!is2DGrayScaleChange && is1D ? f = getScale().spectrumScaleFactor : 1); 1328 if (Math.abs(f - 1) < 0.0001) { 1329 y1 = getScale().minYOnScale; 1330 y2 = getScale().maxYOnScale; 1331 } 1332 } 1333 ScaleData[] yScales = null; 1334 if (isXOnly || is1DY) { 1335 getCurrentView(); 1336 yScales = viewData.getNewScales(iSpectrumSelected, isXOnly, y1, y2); 1337 } 1338 getView(initX, finalX, y1, y2, startIndices, endIndices, viewScales, yScales); 1339 setXPixelMovedTo(1E10, Double.MAX_VALUE, 0, 0); 1340 setWidgetX(pin1Dx0, initX); 1341 setWidgetX(pin1Dx1, finalX); 1342 setWidgetY(pin1Dy0, y1); 1343 setWidgetY(pin1Dy1, y2); 1344 if (imageView == null) { 1345 updateDialogs(); 1346 } else { 1347 int isub = getSpectrumAt(0).getSubIndex(); 1348 int ifix = imageView.fixSubIndex(isub); 1349 if (ifix != isub) 1350 setCurrentSubSpectrum(ifix); 1351 if (is2DGrayScaleChange) 1352 update2dImage(false); 1353 } 1354 if (addZoom) 1355 addCurrentZoom(); 1356 // if (doRepaint) 1357 // pd.repaint(); 1358 } 1359 updateDialogs()1360 private void updateDialogs() { 1361 updateDialog(AType.PeakList, -1); 1362 updateDialog(AType.Measurements, -1); 1363 } 1364 setCurrentSubSpectrum(int i)1365 private void setCurrentSubSpectrum(int i) { 1366 Spectrum spec0 = getSpectrumAt(0); 1367 i = spec0.setCurrentSubSpectrum(i); 1368 if (spec0.isForcedSubset()) 1369 viewData.setXRangeForSubSpectrum(getSpectrum().getXYCoords()); 1370 pd.notifySubSpectrumChange(i, getSpectrum()); 1371 } 1372 addCurrentZoom()1373 private void addCurrentZoom() { 1374 // add to and clean the zoom list 1375 if (viewList.size() > currentZoomIndex + 1) 1376 for (int i = viewList.size() - 1; i > currentZoomIndex; i--) 1377 viewList.removeItemAt(i); 1378 viewList.addLast(viewData); 1379 currentZoomIndex++; 1380 } 1381 setZoomTo(int i)1382 private void setZoomTo(int i) { 1383 //imageView = null; 1384 currentZoomIndex = i; 1385 viewData = viewList.get(i); 1386 resetPinsFromView(); 1387 } 1388 1389 /** 1390 * Clears all views in the zoom list 1391 */ clearViews()1392 void clearViews() { 1393 if (isLinked) { 1394 pd.clearLinkViews(this); 1395 } 1396 setZoom(0, 0, 0, 0); 1397 // leave first zoom 1398 for (int i = viewList.size(); --i >= 1;) 1399 viewList.removeItemAt(i); 1400 } 1401 1402 /** 1403 * Principal drawing method 1404 * 1405 * @param gMain 1406 * @param gFront 1407 * @param gBack 1408 * @param iSplit 1409 * @param needNewPins 1410 * @param doAll 1411 * @param pointsOnly 1412 */ drawAll(Object gMain, Object gFront, Object gBack, int iSplit, boolean needNewPins, boolean doAll, boolean pointsOnly)1413 private void drawAll(Object gMain, Object gFront, Object gBack, int iSplit, 1414 boolean needNewPins, boolean doAll, boolean pointsOnly) { 1415 g2d = pd.g2d; // may change when printing and testing JsPdfCreator 1416 this.gMain = gMain; 1417 Spectrum spec0 = getSpectrumAt(0); 1418 int subIndex = spec0.getSubIndex(); 1419 is2DSpectrum = (!spec0.is1D() 1420 && (isLinked || pd.getBoolean(ScriptToken.DISPLAY2D)) && (imageView != null || get2DImage(spec0))); 1421 if (imageView != null && doAll) { 1422 if (pd.isPrinting && g2d != pd.g2d0) 1423 g2d.newGrayScaleImage(gMain, image2D, imageView.imageWidth, 1424 imageView.imageHeight, imageView.getBuffer()); 1425 if (is2DSpectrum) 1426 setPositionForFrame(iSplit); 1427 draw2DImage(); 1428 } 1429 int iSelected = (stackSelected || !showAllStacked ? iSpectrumSelected : -1); 1430 boolean doYScale = (!showAllStacked || nSpectra == 1 || iSelected >= 0); 1431 boolean doDraw1DObjects = (imageView == null || pd.display1D); 1432 int n = (iSelected >= 0 ? 1 : 0); 1433 int iSpectrumForScale = getFixedSelectedSpectrumIndex(); 1434 if (doDraw1DObjects && doAll) { 1435 fillBox(gMain, xPixel0, yPixel0, xPixel1, yPixel1, 1436 ScriptToken.PLOTAREACOLOR); 1437 if (iSelected < 0) { 1438 doYScale = true; 1439 for (int i = 0; i < nSpectra; i++) 1440 if (doPlot(i, iSplit)) { 1441 if (n++ == 0) 1442 continue; 1443 doYScale &= viewData.areYScalesSame(i - 1, i); 1444 } 1445 } 1446 } 1447 int iSpecForFrame = (nSpectra == 1 ? 0 : !showAllStacked ? iSpectrumMovedTo 1448 : iSpectrumSelected); 1449 Object g2 = (gBack == gMain ? gFront : gBack); 1450 if (doAll) { 1451 boolean addCurrentBox = (pd.getCurrentGraphSet() == this && !isLinked // not if this is linked 1452 && (!isSplittable || (nSplit == 1 || pd.currentSplitPoint == iSplit))); 1453 boolean drawUpDownArrows = (zoomEnabled // must have zoom enabled 1454 && !isDrawNoSpectra() // must be drawing spectrum 1455 && pd.isCurrentGraphSet(this) // must be current 1456 && spectra.get(0).isScalable() // must be scalable 1457 && (addCurrentBox || nSpectra == 1) // must have a box or be just one 1458 // spectrum 1459 && (nSplit == 1 || pd.currentSplitPoint == iSpectrumMovedTo) // must have 1460 // one panel 1461 // or be the 1462 // spectrum 1463 // moved to 1464 ); 1465 boolean addSplitBox = isSplittable; 1466 drawFrame(gMain, iSpecForFrame, addCurrentBox, addSplitBox, 1467 drawUpDownArrows); 1468 } 1469 if (pd.isCurrentGraphSet(this) // is current set 1470 && iSplit == pd.currentSplitPoint && (n < 2 // just one spectrum to show 1471 || iSpectrumSelected >= 0 // stacked and selected 1472 )) 1473 haveSelectedSpectrum = true; 1474 haveSingleYScale = (showAllStacked && nSpectra > 1 ? allowStackedYScale 1475 && doYScale : true); 1476 if (doDraw1DObjects) { 1477 int yOffsetPixels = (int) (yPixels * (yStackOffsetPercent / 100f)); 1478 haveLeftRightArrows = false; 1479 for (int i = 0, offset = 0; i < nSpectra; i++) { 1480 if (!doPlot(i, iSplit)) 1481 continue; 1482 boolean isGrey = (stackSelected && iSpectrumSelected >= 0 && iSpectrumSelected != i); 1483 IntegralData ig = (!reversePlot 1484 && getShowAnnotation(AType.Integration, i) 1485 && (!showAllStacked || iSpectrumSelected == i) ? (IntegralData) getDialog( 1486 AType.Integration, i).getData() 1487 : null); 1488 setScale(i); 1489 Spectrum spec = spectra.get(i); 1490 if (nSplit > 1) { 1491 iSpectrumForScale = i; 1492 } 1493 boolean doDrawWidgets = !isGrey 1494 && (nSplit == 1 || showAllStacked || iSpectrumSelected == iSplit); 1495 boolean doDraw1DY = (doDrawWidgets && haveSelectedSpectrum && i == iSpectrumForScale); 1496 if (doDrawWidgets) { 1497 resetPinsFromView(); 1498 drawWidgets(gFront, g2, subIndex, needNewPins, doDraw1DObjects, 1499 doDraw1DY, false); 1500 } 1501 if (haveSingleYScale && i == iSpectrumForScale && doAll) { 1502 drawGrid(gMain); 1503 if (pd.isPrinting && nSplit > 1) 1504 drawSpectrumSource(gMain, i); 1505 } 1506 if (doDrawWidgets) 1507 drawWidgets(gFront, g2, subIndex, false, doDraw1DObjects, doDraw1DY, 1508 true); 1509 if (!isDrawNoSpectra() 1510 && (nSpectra == 1 || iSpectrumSelected >= 0) 1511 && (haveSingleYScale && i == iSpectrumForScale 1512 || showAllStacked 1513 && stackSelected && i == iSpectrumSelected)) 1514 drawHighlightsAndPeakTabs(gFront, g2, i); 1515 if (doAll) { 1516 if (n == 1 && iSpectrumSelected < 0 || iSpectrumSelected == i 1517 && pd.isCurrentGraphSet(this)) { 1518 if (pd.titleOn && !pd.titleDrawn) { 1519 pd.drawTitle(gMain, height, width, pd.getDrawTitle(pd.isPrinting)); 1520 pd.titleDrawn = true; 1521 } 1522 } 1523 if (haveSingleYScale && i == iSpectrumForScale) { 1524 if (pd.getBoolean(ScriptToken.YSCALEON)) 1525 drawYScale(gMain, this); 1526 if (pd.getBoolean(ScriptToken.YUNITSON)) 1527 drawYUnits(gMain); 1528 } 1529 } 1530 boolean isContinuous = spec.isContinuous(); 1531 boolean onSpectrum = ((nSplit > 1 ? i == iSpectrumMovedTo : isLinked 1532 || i == iSpectrumForScale) 1533 && !pd.isPrinting && isContinuous); 1534 boolean hasPendingIntegral = (!isGrey && pendingIntegral != null && spec == pendingIntegral.spec); 1535 if (doAll || hasPendingIntegral) { 1536 drawPlot(hasPendingIntegral && !doAll ? gFront : gMain, i, spec, isContinuous, offset, isGrey, null, onSpectrum, hasPendingIntegral, pointsOnly); 1537 } 1538 drawIntegration(gFront, i, offset, isGrey, ig, isContinuous, onSpectrum); 1539 drawMeasurements(gFront, i); 1540 if (pendingMeasurement != null && pendingMeasurement.spec == spec) 1541 drawMeasurement(gFront, pendingMeasurement); 1542 if (onSpectrum && xPixelMovedTo >= 0) { 1543 drawSpectrumPointer(gFront, spec, offset, ig); 1544 } 1545 if (nSpectra > 1 && nSplit == 1 && pd.isCurrentGraphSet(this) && doAll) { 1546 haveLeftRightArrows = true; 1547 if (!pd.isPrinting) { 1548 setScale(0); 1549 iSpecForFrame = (iSpectrumSelected); 1550 if (nSpectra != 2) { 1551 setPlotColor(gMain, (iSpecForFrame + nSpectra - 1) % nSpectra); 1552 fillArrow(gMain, ARROW_LEFT, yHArrows, xHArrows - 9, true); 1553 setCurrentBoxColor(gMain); 1554 fillArrow(gMain, ARROW_LEFT, yHArrows, xHArrows - 9, false); 1555 } 1556 if (iSpecForFrame >= 0) { 1557 setPlotColor(gMain, iSpecForFrame); 1558 fillCircle(gMain, xHArrows, yHArrows, true); 1559 } 1560 setCurrentBoxColor(gMain); 1561 fillCircle(gMain, xHArrows, yHArrows, false); 1562 setPlotColor(gMain, (iSpecForFrame + 1) % nSpectra); 1563 fillArrow(gMain, ARROW_RIGHT, yHArrows, xHArrows + 9, true); 1564 setCurrentBoxColor(gMain); 1565 fillArrow(gMain, ARROW_RIGHT, yHArrows, xHArrows + 9, false); 1566 } 1567 } 1568 offset -= yOffsetPixels; 1569 } 1570 if (doAll) { 1571 if (pd.getBoolean(ScriptToken.XSCALEON)) 1572 drawXScale(gMain, this); 1573 if (pd.getBoolean(ScriptToken.XUNITSON)) 1574 drawXUnits(gMain); 1575 } 1576 } else { 1577 if (doAll) { 1578 if (pd.getBoolean(ScriptToken.XSCALEON)) 1579 drawXScale(gMain, imageView); 1580 if (pd.getBoolean(ScriptToken.YSCALEON)) 1581 drawYScale(gMain, imageView); 1582 if (subIndex >= 0) 1583 draw2DUnits(gMain); 1584 } 1585 drawWidgets(gFront, g2, subIndex, needNewPins, doDraw1DObjects, true, 1586 false); 1587 // no 2D grid? 1588 drawWidgets(gFront, g2, subIndex, needNewPins, doDraw1DObjects, true, 1589 true); 1590 widgetsAreSet = true; 1591 } 1592 if (annotations != null) 1593 drawAnnotations(gFront, annotations, null); 1594 } 1595 drawSpectrumSource(Object g, int i)1596 private void drawSpectrumSource(Object g, int i) { 1597 pd.printFilePath(g, pd.thisWidth - pd.right, yPixel0, spectra.get(i).getFilePath()); 1598 } 1599 doPlot(int i, int iSplit)1600 private boolean doPlot(int i, int iSplit) { 1601 boolean isGrey = (stackSelected && iSpectrumSelected >= 0 && iSpectrumSelected != i); 1602 boolean ok = (showAllStacked || iSpectrumSelected == -1 || iSpectrumSelected == i); 1603 return (nSplit > 1 ? i == iSplit : ok && (!pd.isPrinting || !isGrey)); 1604 } 1605 1606 // private void hideAllDialogsExceptCurrent() { 1607 // if (dialogs == null) 1608 // return; 1609 // boolean getInt = false; 1610 // boolean getMeas = false; 1611 // boolean getPeak = false; 1612 // AnnotationData ad; 1613 // 1614 // for (Map.Entry<String, AnnotationData> e : dialogs.entrySet()) { 1615 // ad = e.getValue(); 1616 // if (isVisible(ad)) { 1617 // // ((AnnotationDialog) ad).setVisible(false); 1618 // switch (ad.getAType()) { 1619 // case Integration: 1620 // getInt = true; 1621 // break; 1622 // case Measurements: 1623 // getMeas = true; 1624 // break; 1625 // case PeakList: 1626 // getPeak = true; 1627 // break; 1628 // case NONE: 1629 // } 1630 // } 1631 // } 1632 // if (getInt) 1633 // ad = jsvp.showDialog(AType.Integration); 1634 // if (getMeas) 1635 // ad = jsvp.showDialog(AType.Measurements); 1636 // if (getPeak) 1637 // ad = jsvp.showDialog(AType.PeakList); 1638 // 1639 // } 1640 drawSpectrumPointer(Object gFront, Spectrum spec, int yOffset, IntegralData ig)1641 private void drawSpectrumPointer(Object gFront, Spectrum spec, 1642 int yOffset, IntegralData ig) { 1643 // short vertical cursor 1644 setColorFromToken(gFront, ScriptToken.PEAKTABCOLOR); 1645 int iHandle = pd.integralShiftMode; 1646 if (ig != null) { 1647 if ((!pd.ctrlPressed || pd.isIntegralDrag) 1648 && !isOnSpectrum(pd.mouseX, pd.mouseY, -1)) { 1649 ig = null; 1650 } else if (iHandle == 0) { 1651 iHandle = getShiftMode(pd.mouseX, pd.mouseY); 1652 if (iHandle == 0) 1653 iHandle = Integer.MAX_VALUE; 1654 } 1655 } 1656 double y0 = yValueMovedTo; 1657 yValueMovedTo = (ig == null ? spec.getYValueAt(xValueMovedTo) : ig 1658 .getPercentYValueAt(xValueMovedTo)); 1659 setCoordStr(xValueMovedTo, yValueMovedTo); 1660 if (iHandle != 0) { 1661 setPlotColor(gFront, iHandle == Integer.MAX_VALUE ? -1 : 0); 1662 if (iHandle < 0 || iHandle == Integer.MAX_VALUE) { 1663 drawHandle(gFront, xPixelPlot1, yPixelPlot0, 3, false); 1664 } 1665 if (iHandle > 0) { 1666 drawHandle(gFront, xPixelPlot0, yPixelPlot1, 3, false); 1667 } 1668 if (iHandle != Integer.MAX_VALUE) 1669 return; 1670 } 1671 if (ig != null) 1672 g2d.setStrokeBold(gFront, true); 1673 1674 if (Double.isNaN(y0) || pendingMeasurement != null) { 1675 g2d.drawLine(gFront, xPixelMovedTo, yPixel0, xPixelMovedTo, yPixel1); 1676 if (xPixelMovedTo2 >= 0) 1677 g2d.drawLine(gFront, xPixelMovedTo2, yPixel0, xPixelMovedTo2, yPixel1); 1678 yValueMovedTo = Double.NaN; 1679 } else { 1680 int y = (ig == null ? yOffset + toPixelY(yValueMovedTo) 1681 : toPixelYint(yValueMovedTo / 100)); 1682 if (y == fixY(y)) 1683 g2d.drawLine(gFront, xPixelMovedTo, y - 10, xPixelMovedTo, y + 10); 1684 } 1685 if (ig != null) 1686 g2d.setStrokeBold(gFront, false); 1687 } 1688 setScale(int i)1689 void setScale(int i) { 1690 viewData.setScale(i, xPixels, yPixels, spectra.get(i).isInverted()); 1691 } 1692 draw2DUnits(Object g)1693 private void draw2DUnits(Object g) { 1694 String nucleusX = getSpectrumAt(0).nucleusX; 1695 String nucleusY = getSpectrumAt(0).nucleusY; 1696 setColorFromToken(g, ScriptToken.PLOTCOLOR); 1697 drawUnits(g, nucleusX, imageView.xPixel1 + 5 * pd.scalingFactor, yPixel1, 1, 1.0); 1698 drawUnits(g, nucleusY, imageView.xPixel0 - 5 * pd.scalingFactor, yPixel0, 1, 0); 1699 } 1700 drawPeakTabs(Object gFront, Object g2, Spectrum spec)1701 private void drawPeakTabs(Object gFront, Object g2, Spectrum spec) { 1702 Lst<PeakInfo> list = (nSpectra == 1 || iSpectrumSelected >= 0 ? spec 1703 .getPeakList() : null); 1704 if (list != null && list.size() > 0) { 1705 if (piMouseOver != null && piMouseOver.spectrum == spec && pd.isMouseUp()) { 1706 g2d.setGraphicsColor(g2, g2d.getColor4(240, 240, 240, 140)); // very faint gray box 1707 drawPeak(g2, piMouseOver, 0); 1708 spec.setHighlightedPeak(piMouseOver); 1709 } else { 1710 spec.setHighlightedPeak(null); 1711 } 1712 setColorFromToken(gFront, ScriptToken.PEAKTABCOLOR); 1713 for (int i = list.size(); --i >= 0;) { 1714 PeakInfo p = list.get(i); 1715 drawPeak(gFront, p, p == spec.getSelectedPeak() ? 14 : 7); 1716 } 1717 } 1718 } 1719 drawPeak(Object g, PeakInfo pi, int tickSize)1720 private void drawPeak(Object g, PeakInfo pi, int tickSize) { 1721 if (pd.isPrinting) 1722 return; 1723 double xMin = pi.getXMin(); 1724 double xMax = pi.getXMax(); 1725 if (xMin == xMax) 1726 return; 1727 drawBar(g, pi, xMin, xMax, null, tickSize); 1728 } 1729 1730 /** 1731 * 1732 * Draw sliders, pins, and zoom boxes (only one of which would ever be drawn) 1733 * 1734 * @param gFront 1735 * @param gBack 1736 * @param subIndex 1737 * @param needNewPins 1738 * @param doDraw1DObjects 1739 * @param doDraw1DY 1740 * TODO 1741 * @param postGrid 1742 */ drawWidgets(Object gFront, Object gBack, int subIndex, boolean needNewPins, boolean doDraw1DObjects, boolean doDraw1DY, boolean postGrid)1743 private void drawWidgets(Object gFront, Object gBack, int subIndex, boolean needNewPins, 1744 boolean doDraw1DObjects, boolean doDraw1DY, boolean postGrid) { 1745 setWidgets(needNewPins, subIndex, doDraw1DObjects); 1746 if (pd.isPrinting && (imageView == null ? !cur1D2Locked : sticky2Dcursor)) 1747 return; 1748 // boolean allowPin1y = true;//(nSplit > 1 || iSpectrumSelected < 0 || 1749 // nSpectra == 1 || nSplit == 1 && !stackSelected); 1750 if (!pd.isPrinting && !postGrid) { 1751 // top/side slider bar backgrounds 1752 if (doDraw1DObjects) { 1753 fillBox(gFront, xPixel0, pin1Dx0.yPixel1, xPixel1, pin1Dx1.yPixel1 + 2, 1754 ScriptToken.GRIDCOLOR); 1755 fillBox(gFront, pin1Dx0.xPixel0, pin1Dx0.yPixel1, pin1Dx1.xPixel0, 1756 pin1Dx1.yPixel1 + 2, ScriptToken.PLOTCOLOR); 1757 } else { 1758 1759 fillBox(gFront, imageView.xPixel0, pin2Dx0.yPixel1, imageView.xPixel1, 1760 pin2Dx0.yPixel1 + 2, ScriptToken.GRIDCOLOR); 1761 fillBox(gFront, pin2Dx0.xPixel0, pin2Dx0.yPixel1, pin2Dx1.xPixel0, 1762 pin2Dx1.yPixel1 + 2, ScriptToken.PLOTCOLOR); 1763 fillBox(gFront, pin2Dy0.xPixel1, yPixel1, pin2Dy1.xPixel1 + 2, yPixel0, 1764 ScriptToken.GRIDCOLOR); 1765 fillBox(gFront, pin2Dy0.xPixel1, pin2Dy0.yPixel1, pin2Dy1.xPixel1 + 2, 1766 pin2Dy1.yPixel0, ScriptToken.PLOTCOLOR); 1767 } 1768 fillBox(gFront, pin1Dy0.xPixel1, yPixel1, pin1Dy1.xPixel1 + 2, yPixel0, 1769 ScriptToken.GRIDCOLOR); 1770 if (doDraw1DY) 1771 fillBox(gFront, pin1Dy0.xPixel1, pin1Dy0.yPixel1, pin1Dy1.xPixel1 + 2, 1772 pin1Dy1.yPixel0, ScriptToken.PLOTCOLOR); 1773 } 1774 for (int i = 0; i < widgets.length; i++) { 1775 PlotWidget pw = widgets[i]; 1776 if (pw == null || !pw.isPinOrCursor && !zoomEnabled) 1777 continue; 1778 boolean isLockedCursor = (pw == cur1D2x1 || pw == cur1D2x2 1779 || pw == cur2Dx0 || pw == cur2Dx1 || pw == cur2Dy); 1780 if ((pw.isPin || !pw.isPinOrCursor) == postGrid) 1781 continue; 1782 if (pw.is2D) { 1783 if (pw == cur2Dx0 && !doDraw1DObjects) 1784 continue; 1785 } else { 1786 boolean isPin1Dy = (pw == pin1Dy0 || pw == pin1Dy1 || pw == pin1Dy01); 1787 if ((imageView != null && doDraw1DObjects == isPin1Dy) 1788 || isPin1Dy && !doDraw1DY 1789 || pw == cur1D2x1 && gs2dLinkedX == null 1790 || pw == cur1D2x2 && gs2dLinkedY == null 1791 || pw == zoomBox1D && (pd.isIntegralDrag || pd.integralShiftMode != 0) 1792 ) { 1793 if (!isLinked || imageView != null) 1794 continue; 1795 } 1796 } 1797 if (pd.isPrinting && !isLockedCursor) 1798 continue; 1799 if (pw.isPinOrCursor) { 1800 setColorFromToken(gFront, pw.color); 1801 g2d.drawLine(gFront, pw.xPixel0, pw.yPixel0, pw.xPixel1, pw.yPixel1); 1802 pw.isVisible = true; 1803 if (pw.isPin) 1804 drawHandle(gFront, pw.xPixel0, pw.yPixel0, 2, !pw.isEnabled); 1805 } else if (pw.xPixel1 != pw.xPixel0) { 1806 1807 1808 fillBox(gBack, pw.xPixel0, pw.yPixel0, pw.xPixel1, pw.yPixel1, 1809 pw == zoomBox1D && pd.shiftPressed ? ScriptToken.ZOOMBOXCOLOR2 : ScriptToken.ZOOMBOXCOLOR); 1810 } 1811 } 1812 } 1813 1814 1815 /** 1816 * draw a bar, but not necessarily full height 1817 * 1818 * @param g 1819 * @param pi 1820 * @param xMin 1821 * units 1822 * @param xMax 1823 * units 1824 * @param whatColor 1825 * @param tickSize 1826 */ 1827 drawBar(Object g, PeakInfo pi, double xMin, double xMax, ScriptToken whatColor, int tickSize)1828 private void drawBar(Object g, PeakInfo pi, double xMin, double xMax, 1829 ScriptToken whatColor, int tickSize) { 1830 1831 double r = xMax + xMin; 1832 double d = Math.abs(xMax - xMin); 1833 double range = Math.abs(toX(xPixel1) - toX(xPixel0)); 1834 if (false && tickSize > 0 && d > range / 20) { 1835 d = range / 20; 1836 xMin = r / 2 - d/2; 1837 xMax = r / 2 + d/2; 1838 } 1839 1840 int x1 = toPixelX(xMin); 1841 int x2 = toPixelX(xMax); 1842 if (x1 > x2) { 1843 int tmp = x1; 1844 x1 = x2; 1845 x2 = tmp; 1846 } 1847 // if either pixel is outside of plot area 1848 x1 = fixX(x1); 1849 x2 = fixX(x2); 1850 if (x2 - x1 < 3) { 1851 x1 -= 2; 1852 x2 += 2; 1853 } 1854 if (pi != null) 1855 pi.setPixelRange(x1, x2); 1856 if (tickSize == 0) { 1857 fillBox(g, x1, yPixel0, x2, yPixel0 + yPixels, whatColor); 1858 } else { 1859 fillBox(g, x1, yPixel0+2, x2, yPixel0 + 5, whatColor); 1860 if (pi != null) { 1861 x1 = (x1 + x2) / 2; 1862 fillBox(g, x1 - 1, yPixel0 + 2, x1 + 1, yPixel0 + 2 + tickSize, whatColor); 1863 } 1864 } 1865 1866 } 1867 1868 /** 1869 * Draws the plot on the Panel 1870 * 1871 * @param gFront 1872 * the <code>Graphics</code> object 1873 * @param index 1874 * the index of the Spectrum to draw 1875 * @param yOffset 1876 * @param isGrey 1877 * @param iData 1878 * @param isContinuous 1879 * @param isSelected 1880 */ drawIntegration(Object gFront, int index, int yOffset, boolean isGrey, IntegralData iData, boolean isContinuous, boolean isSelected)1881 private void drawIntegration(Object gFront, int index, int yOffset, boolean isGrey, 1882 IntegralData iData, boolean isContinuous, boolean isSelected) { 1883 // Check if specInfo in null or xyCoords is null 1884 if (iData != null) { 1885 if (haveIntegralDisplayed(index)) 1886 drawPlot(gFront, index, spectra.get(index), true, yOffset, false, iData, true, false, false); 1887 drawIntegralValues(gFront, index, yOffset); 1888 } 1889 Lst<Annotation> ratios = getIntegrationRatios(index); 1890 if (ratios!= null) 1891 drawAnnotations(gFront, ratios, 1892 ScriptToken.INTEGRALPLOTCOLOR); 1893 } 1894 getMeasurements(AType type, int iSpec)1895 private MeasurementData getMeasurements(AType type, int iSpec) { 1896 AnnotationData ad = getDialog(type, iSpec); 1897 return (ad == null || ad.getData().size() == 0 || !ad.getState() ? null : ad.getData()); 1898 } 1899 drawPlot(Object g, int index, Spectrum spec, boolean isContinuous, int yOffset, boolean isGrey, IntegralData ig, boolean isSelected, boolean hasPendingIntegral, boolean pointsOnly)1900 private void drawPlot(Object g, int index, Spectrum spec, 1901 boolean isContinuous, int yOffset, boolean isGrey, IntegralData ig, 1902 boolean isSelected, boolean hasPendingIntegral, boolean pointsOnly) { 1903 Coordinate[] xyCoords = (ig == null ? spec.getXYCoords() 1904 : getIntegrationGraph(index).getXYCoords()); 1905 boolean isIntegral = (ig != null); 1906 BS bsDraw = (isIntegral ? ig.getBitSet() : null); 1907 boolean fillPeaks = (hasPendingIntegral || spec.fillColor != null 1908 && isSelected); 1909 int iColor = (isGrey ? COLOR_BLACK : isIntegral ? COLOR_INTEGRAL : !allowStacking ? 0 : index); 1910 setPlotColor(g, iColor); 1911 boolean plotOn = true; 1912 int y0 = toPixelY(0); 1913 if (isIntegral) 1914 fillPeaks &= (y0 == fixY(y0)); 1915 else 1916 y0 = fixY(y0); 1917 GenericColor cInt = (isIntegral || fillPeaks ? pd 1918 .getColor(ScriptToken.INTEGRALPLOTCOLOR) : null); 1919 GenericColor cFill = (cInt == null || spec.fillColor == null ? cInt 1920 : spec.fillColor); 1921 int iFirst = viewData.getStartingPointIndex(index); 1922 int iLast = viewData.getEndingPointIndex(index); 1923 if (isContinuous && !pointsOnly) { 1924 iLast--; 1925 // all graphics can do line to for now 1926 boolean doLineTo = (isIntegral || pendingIntegral != null) 1927 && g2d.canDoLineTo(); 1928 if (doLineTo) 1929 g2d.doStroke(g, true); 1930 boolean isDown = false; 1931 for (int i = iFirst; i <= iLast; i++) { 1932 Coordinate point1 = xyCoords[i]; 1933 Coordinate point2 = xyCoords[i + 1]; 1934 int y1 = (isIntegral ? toPixelYint(point1.getYVal()) : toPixelY(point1 1935 .getYVal())); 1936 if (y1 == Integer.MIN_VALUE) 1937 continue; 1938 int y2 = (isIntegral ? toPixelYint(point2.getYVal()) : toPixelY(point2 1939 .getYVal())); 1940 if (y2 == Integer.MIN_VALUE) 1941 continue; 1942 double xv1 = point1.getXVal(); 1943 double xv2 = point2.getXVal(); 1944 int x1 = toPixelX(xv1); 1945 int x2 = toPixelX(xv2); 1946 y1 = fixY(yOffset + y1); 1947 y2 = fixY(yOffset + y2); 1948 if (isIntegral) { 1949 if (i == iFirst) { 1950 xPixelPlot1 = x1; 1951 yPixelPlot0 = y1; 1952 } 1953 xPixelPlot0 = x2; 1954 yPixelPlot1 = y2; 1955 } 1956 if (x2 == x1 && y1 == y2) 1957 continue; 1958 if (fillPeaks && hasPendingIntegral 1959 && pendingIntegral.overlaps(xv1, xv2)) { 1960 if (cFill != null) { 1961 g2d.doStroke(g, false); 1962 g2d.setGraphicsColor(g, cFill); 1963 } 1964 g2d.fillRect(g, Math.min(x1, x2), Math.min(y0, y1), 1965 Math.max(1, Math.abs(x2 - x1)), Math.abs(y0 - y1)); 1966 if (cFill != null) { 1967 g2d.doStroke(g, false); 1968 g2d.doStroke(g, true); 1969 isDown = false; 1970 setPlotColor(g, iColor); 1971 } 1972 continue; 1973 } 1974 if (y1 == y2 && (y1 == yPixel0)) { 1975 continue; 1976 } 1977 if (bsDraw != null && bsDraw.get(i) != plotOn) { 1978 plotOn = bsDraw.get(i); 1979 if (doLineTo && isDown) { 1980 g2d.doStroke(g, false); 1981 g2d.doStroke(g, true); 1982 isDown = false; 1983 } 1984 if (!pd.isPrinting && pd.integralShiftMode != 0) 1985 setPlotColor(g, 0); 1986 else if (plotOn) 1987 setColorFromToken(g, ScriptToken.INTEGRALPLOTCOLOR); 1988 else 1989 setPlotColor(g, COLOR_GREY); 1990 } 1991 if (pd.isPrinting && !plotOn) 1992 continue; 1993 if (isDown) { 1994 g2d.lineTo(g, x2, y2); 1995 } else { 1996 g2d.drawLine(g, x1, y1, x2, y2); 1997 isDown = doLineTo; 1998 } 1999 } 2000 if (doLineTo) 2001 g2d.doStroke(g, false); 2002 } else { 2003 for (int i = iFirst; i <= iLast; i++) { 2004 Coordinate point = xyCoords[i]; 2005 int y2 = toPixelY(point.getYVal()); 2006 if (y2 == Integer.MIN_VALUE) 2007 continue; 2008 int x1 = toPixelX(point.getXVal()); 2009 int y1 = toPixelY(Math.max(getScale().minYOnScale, 0)); 2010 y1 = fixY(yOffset + y1); 2011 y2 = fixY(yOffset + y2); 2012 if (y1 == y2 && (y1 == yPixel0 || y1 == yPixel1)) 2013 continue; 2014 if (pointsOnly) 2015 g2d.fillRect(g, x1-1, y2-1, 3, 3); 2016 else 2017 g2d.drawLine(g, x1, y1, x1, y2); 2018 } 2019 if (!pointsOnly && getScale().isYZeroOnScale()) { 2020 int y = yOffset + toPixelY(getScale().spectrumYRef); 2021 if (y == fixY(y)) 2022 g2d.drawLine(g, xPixel1, y, xPixel0, y); 2023 } 2024 } 2025 } 2026 2027 /** 2028 * 2029 * @param g 2030 * @param iSpec 2031 * @param addCurrentBox 2032 * @param addSplitBox 2033 * @param drawUpDownArrows 2034 */ drawFrame(Object g, int iSpec, boolean addCurrentBox, boolean addSplitBox, boolean drawUpDownArrows)2035 private void drawFrame(Object g, int iSpec, 2036 boolean addCurrentBox, boolean addSplitBox, boolean drawUpDownArrows) { 2037 if (!pd.gridOn || pd.isPrinting) { 2038 setColorFromToken(g, ScriptToken.GRIDCOLOR); 2039 g2d.drawRect(g, xPixel0, yPixel0, xPixels, yPixels); 2040 if (pd.isPrinting) 2041 return; 2042 } 2043 2044 2045 setCurrentBoxColor(g); 2046 if (drawUpDownArrows) { 2047 if (iSpec >= 0) { 2048 setPlotColor(g, iSpec); 2049 fillArrow(g, ARROW_UP, xVArrows, 2050 (yPixel00 + yPixel11) / 2 - 9, true); 2051 fillArrow(g, ARROW_DOWN, xVArrows, 2052 (yPixel00 + yPixel11) / 2 + 9, true); 2053 setCurrentBoxColor(g); 2054 } 2055 fillArrow(g, ARROW_UP, xVArrows, (yPixel00 + yPixel11) / 2 - 9, 2056 false); 2057 fillCircle(g, xVArrows, (yPixel00 + yPixel11) / 2, false); 2058 fillArrow(g, ARROW_DOWN, xVArrows, 2059 (yPixel00 + yPixel11) / 2 + 9, false); 2060 } 2061 2062 if (imageView != null) 2063 return; 2064 if (addCurrentBox) { 2065 int x1 = xPixel00 + 10; 2066 int x2 = xPixel11 - 10; 2067 int y1 = yPixel00 + 1; 2068 int y2 = yPixel11 - 2; 2069 g2d.drawLine(g, x1, y1, x2, y1); 2070 g2d.drawLine(g, x2, y1, x2, y2); 2071 g2d.drawLine(g, x1, y2, x2, y2); 2072 splitterX = closerX = Integer.MIN_VALUE; 2073 drawBox(g, x2 - 10, y1, x2, y1 + 10, null); 2074 g2d.drawLine(g, x2 - 10, y1 + 10, x2, y1); 2075 g2d.drawLine(g, x2, y1 + 10, x2 - 10, y1); 2076 closerX = x2 - 10; 2077 closerY = y1; 2078 if (addSplitBox) { 2079 x2 -= 10; 2080 fillBox(g, x2 - 10, y1, x2, y1 + 10, null); 2081 splitterX = x2 - 10; 2082 splitterY = y1; 2083 2084 } 2085 2086 } 2087 } 2088 2089 /** 2090 * Draws the grid on the Panel 2091 * 2092 * @param g 2093 * the <code>Graphics</code> object 2094 */ drawGrid(Object g)2095 private void drawGrid(Object g) { 2096 if (!pd.gridOn || imageView != null) 2097 return; 2098 setColorFromToken(g, ScriptToken.GRIDCOLOR); 2099 double lastX; 2100 if (Double.isNaN(getScale().firstX)) { 2101 lastX = getScale().maxXOnScale + getScale().steps[0] / 2; 2102 for (double val = getScale().minXOnScale; val < lastX; val += getScale().steps[0]) { 2103 int x = toPixelX(val); 2104 g2d.drawLine(g, x, yPixel0, x, yPixel1); 2105 } 2106 } else { 2107 lastX = getScale().maxXOnScale * 1.0001; 2108 for (double val = getScale().firstX; val <= lastX; val += getScale().steps[0]) { 2109 int x = toPixelX(val); 2110 g2d.drawLine(g, x, yPixel0, x, yPixel1); 2111 } 2112 } 2113 for (double val = getScale().firstY; val < getScale().maxYOnScale 2114 + getScale().steps[1] / 2; val += getScale().steps[1]) { 2115 int y = toPixelY(val); 2116 if (y == fixY(y)) 2117 g2d.drawLine(g, xPixel0, y, xPixel1, y); 2118 } 2119 } 2120 2121 Map<Double, String> mapX = new Hashtable<Double, String>(); 2122 2123 /** 2124 * Draws the x Scale 2125 * 2126 * @param g 2127 * the <code>Graphics</code> object 2128 * @param c 2129 * could be 'this' or imageView 2130 */ drawXScale(Object g, XYScaleConverter c)2131 private void drawXScale(Object g, XYScaleConverter c) { 2132 2133 setColorFromToken(g, ScriptToken.SCALECOLOR); 2134 if (pd.isPrinting) 2135 g2d.drawLine(g, c.getXPixel0(), yPixel1, c.getXPixel0() + c.getXPixels() - 1, yPixel1); 2136 int precision = getScale().precision[0]; 2137 Font font = pd.setFont(g, c.getXPixels(), FONT_PLAIN, pd.isPrinting ? 10 : 12, false); 2138 int y1 = yPixel1; 2139 int y2 = yPixel1 + 4 * pd.scalingFactor; 2140 int y3 = yPixel1 + 2 * pd.scalingFactor; 2141 2142 int h = font.getHeight(); 2143 double dx = c.toPixelX(getScale().steps[0]) - c.toPixelX(0); 2144 double maxWidth = Math.abs(dx * 0.95); 2145 // we go overboard for ticks 2146 double firstX = getScale().firstX - getScale().steps[0]; 2147 double lastX = (getScale().maxXOnScale + getScale().steps[0]) * 1.0001; 2148 for (int pass = 0; pass < 2; pass++) { 2149 if (pass == 1) 2150 ScaleData.fixScale(mapX); 2151 double prevX = 1e10; 2152 for (double val = firstX; val <= lastX; val += getScale().steps[0]) { 2153 int x = c.toPixelX(val); 2154 Double d = Double.valueOf(val); 2155 String s; 2156 switch (pass) { 2157 case 0: 2158 s = DF.formatDecimalDbl(val, precision); 2159 mapX.put(d, s); 2160 drawTick(g, x, y1, y2, c); 2161 dx = Math.abs(prevX - val); 2162 int ntick = getScale().minorTickCounts[0]; 2163 if (ntick != 0) { 2164 double step = dx / ntick; 2165 for (int i = 1; i < ntick; i++) { 2166 double x1 = val - i * step; 2167 drawTick(g, c.toPixelX(x1), y1, y3, c); 2168 } 2169 } 2170 prevX = val; 2171 continue; 2172 case 1: 2173 s = mapX.get(d); 2174 if (s == null || x != c.fixX(x)) 2175 continue; 2176 int w = pd.getStringWidth(s); 2177 int n = (x + w / 2 == c.fixX(x + w / 2) ? 2 : 0); 2178 if (n > 0) 2179 g2d.drawString(g, s, x - w / n, y2 + h); 2180 val += Math.floor(w / maxWidth) * getScale().steps[0]; 2181 break; 2182 } 2183 } 2184 } 2185 mapX.clear(); 2186 } 2187 drawTick(Object g, int x, int y1, int y2, XYScaleConverter c)2188 private void drawTick(Object g, int x, int y1, int y2, XYScaleConverter c) { 2189 if (x == c.fixX(x)) 2190 g2d.drawLine(g, x, y1, x, y2); 2191 } 2192 2193 /** 2194 * Draws the y Scale 2195 * 2196 * @param g 2197 * the <code>Graphics</code> object 2198 * @param c 2199 */ drawYScale(Object g, XYScaleConverter c)2200 private void drawYScale(Object g, XYScaleConverter c) { 2201 2202 ScaleData sd = c.getScale(); 2203 int precision = sd.precision[1]; 2204 Font font = pd.setFont(g, c.getXPixels(), FONT_PLAIN, pd.isPrinting ? 10 : 12, false); 2205 int h = font.getHeight(); 2206 double max = sd.maxYOnScale + sd.steps[1] / 2; 2207 int yLast = Integer.MIN_VALUE; 2208 setColorFromToken(g, ScriptToken.SCALECOLOR); 2209 for (int pass = 0; pass < 2; pass++) { 2210 if (pass == 1) 2211 ScaleData.fixScale(mapX); 2212 for (double val = sd.firstY; val < max; val += sd.steps[1]) { 2213 Double d = Double.valueOf(val); 2214 int x1 = c.getXPixel0(); 2215 int y = c.toPixelY(val); 2216 if (y != c.fixY(y)) 2217 continue; 2218 String s; 2219 if (pass == 0) 2220 g2d.drawLine(g, x1, y, x1 - 3 * pd.scalingFactor, y); 2221 if (Math.abs(y - yLast) <= h) 2222 continue; 2223 yLast = y; 2224 switch (pass) { 2225 case 0: 2226 s = DF.formatDecimalDbl(val, precision); 2227 mapX.put(d, s); 2228 break; 2229 case 1: 2230 s = mapX.get(d); 2231 if (s == null) 2232 continue; 2233 if (s.startsWith("0") && s.contains("E")) 2234 s = "0"; 2235 g2d.drawString(g, s, (x1 - 4 * pd.scalingFactor - pd.getStringWidth(s)), y + h / 3); 2236 break; 2237 } 2238 } 2239 } 2240 mapX.clear(); 2241 } 2242 2243 /** 2244 * Draws the X Units 2245 * 2246 * @param g 2247 * the <code>Graphics</code> object 2248 */ drawXUnits(Object g)2249 private void drawXUnits(Object g) { 2250 String units = spectra.get(0).getAxisLabel(true); 2251 if (units != null) 2252 drawUnits(g, units, xPixel1 + 25 * pd.scalingFactor, yPixel1 + 5 * pd.scalingFactor, 1, 1); 2253 } 2254 drawUnits(Object g, String s, int x, int y, double hOff, double vOff)2255 private void drawUnits(Object g, String s, int x, int y, double hOff, 2256 double vOff) { 2257 setColorFromToken(g, ScriptToken.UNITSCOLOR); 2258 pd.setFont(g, (imageView == null ? this : imageView).getXPixels(), FONT_ITALIC | FONT_BOLD, 10, false); 2259 g2d.drawString(g, s, (int) (x - pd.getStringWidth(s) * hOff), 2260 (int) (y + pd.getFontHeight() * vOff)); 2261 2262 } 2263 2264 /** 2265 * Draws the Y Units 2266 * 2267 * @param g 2268 * the <code>Graphics</code> object 2269 */ drawYUnits(Object g)2270 private void drawYUnits(Object g) { 2271 String units = spectra.get(0).getAxisLabel(false); 2272 if (units != null) 2273 drawUnits(g, units, (pd.isPrinting ? 30 : 5) * pd.scalingFactor, yPixel0 + (pd.isPrinting ? 0 : 5) * pd.scalingFactor, 0, -1); 2274 } 2275 2276 /** 2277 * 2278 * @param gFront graphics for peak tabs 2279 * @param gBack graphics for highlight boxes 2280 * @param iSpec 2281 */ drawHighlightsAndPeakTabs(Object gFront, Object gBack, int iSpec)2282 private void drawHighlightsAndPeakTabs(Object gFront, Object gBack, int iSpec) { 2283 MeasurementData md = getMeasurements(AType.PeakList, iSpec); 2284 Spectrum spec = spectra.get(iSpec); 2285 if (pd.isPrinting) { 2286 if (md != null) { 2287 setColorFromToken(gFront, ScriptToken.PEAKTABCOLOR); 2288 printPeakList(gFront, spec, (PeakData) md); 2289 } 2290 return; 2291 } 2292 if (md == null) { 2293 for (int i = 0; i < highlights.size(); i++) { 2294 Highlight hl = highlights.get(i); 2295 if (hl.spectrum == spec) { 2296 pd.setHighlightColor(hl.color); 2297 drawBar(gBack, null, hl.x1, hl.x2, ScriptToken.HIGHLIGHTCOLOR, 0); 2298 } 2299 } 2300 if (pd.peakTabsOn) 2301 drawPeakTabs(gFront, gBack, spec); 2302 } 2303 int y; 2304 if (md != null) { 2305 y = (spec.isInverted() ? yPixel1 - 10 * pd.scalingFactor : yPixel0); 2306 setColorFromToken(gFront, ScriptToken.PEAKTABCOLOR); 2307 for (int i = md.size(); --i >= 0;) { 2308 Measurement m = md.get(i); 2309 int x = toPixelX(m.getXVal()); 2310 g2d.drawLine(gFront, x, y, x, y + 10 * pd.scalingFactor); 2311 } 2312 if (isVisible(getDialog(AType.PeakList, iSpec))) { 2313 y = toPixelY(((PeakData) md).getThresh()); 2314 if (y == fixY(y) && !pd.isPrinting) 2315 g2d.drawLine(gFront, xPixel0, y, xPixel1, y); 2316 } 2317 } 2318 } 2319 printPeakList(Object g, Spectrum spec, PeakData data)2320 private void printPeakList(Object g, Spectrum spec, PeakData data) { 2321 String[][] sdata = data.getMeasurementListArray(null); 2322 if (sdata.length == 0) 2323 return; 2324 pd.setFont(g, xPixels, FONT_PLAIN, 8, false); 2325 int h = pd.getFontHeight(); 2326 int[] xs = new int[data.size()]; 2327 int[] xs0 = new int[data.size()]; 2328 int dx = 0; 2329 int s5 = 5 * pd.scalingFactor; 2330 int s10 = 10 * pd.scalingFactor; 2331 int s15 = 15 * pd.scalingFactor; 2332 int s25 = 25 * pd.scalingFactor; 2333 for (int i = 0; i < sdata.length; i++) { 2334 xs0[i] = toPixelX(Double.parseDouble(sdata[i][1])); 2335 if (i == 0) { 2336 xs[i] = xs0[i]; 2337 continue; 2338 } 2339 xs[i] = Math.max(xs[i - 1] + h, xs0[i] + h); 2340 dx += (xs[i] - xs0[i]); 2341 } 2342 dx /= 2 * sdata.length; 2343 if (xs[0] - dx < xPixel0 + s25) 2344 dx = xs[0] - (xPixel0 + s25); 2345 for (int i = 0; i < sdata.length; i++) 2346 xs[i] -= dx; 2347 2348 boolean inverted = spec.isInverted(); 2349 int y4 = pd.getStringWidth("99.9999"); 2350 int y2 = (sdata[0].length >= 6 ? pd.getStringWidth("99.99") : 0); 2351 int f = (inverted ? -1 : 1); 2352 2353 int y = (inverted ? yPixel1 : yPixel0) + f * (y2 + y4 + s15); 2354 for (int i = 0; i < sdata.length; i++) { 2355 g2d.drawLine(g, xs[i], y, xs[i], y + s5 * f); 2356 g2d.drawLine(g, xs[i], y + s5 * f, xs0[i], y + s10 * f); 2357 g2d.drawLine(g, xs0[i], y + s10 * f, xs0[i], y + s15 * f); 2358 if (y2 > 0 && sdata[i][4].length() > 0) 2359 g2d.drawLine(g, (xs[i] + xs[i - 1]) / 2, y - y4 + s5, 2360 (xs[i] + xs[i - 1]) / 2, y - y4 - s5); 2361 } 2362 2363 y -= f * 2 * pd.scalingFactor; 2364 2365 if (y2 > 0) { 2366 drawStringRotated(g, -90, xs[0] - s15, y, " ppm"); 2367 drawStringRotated(g, -90, xs[0] - s15, y - y4 - s5, " Hz"); 2368 } 2369 for (int i = data.size(); --i >= 0;) { 2370 drawStringRotated(g, -90 * f, xs[i] + f * h / 3, y, sdata[i][1]); 2371 if (y2 > 0 && sdata[i][4].length() > 0) { 2372 int x = (xs[i] + xs[i - 1]) / 2 + h / 3; 2373 drawStringRotated(g, -90, x, y - y4 - s5, sdata[i][4]); 2374 } 2375 } 2376 } 2377 drawStringRotated(Object g, int angle, int x, int y, String s)2378 private void drawStringRotated(Object g, int angle, int x, int y, String s) { 2379 g2d.drawStringRotated(g, s, x, y, angle); 2380 } 2381 2382 // determine whether there are any ratio annotations to draw drawAnnotations(Object g, Lst<Annotation> annotations, ScriptToken whatColor)2383 private void drawAnnotations(Object g, Lst<Annotation> annotations, 2384 ScriptToken whatColor) { 2385 pd.setFont(g, xPixels, FONT_BOLD, 18, false); 2386 for (int i = annotations.size(); --i >= 0;) { 2387 Annotation note = annotations.get(i); 2388 setAnnotationColor(g, note, whatColor); 2389 XYScaleConverter c = (note.is2D ? imageView : this); 2390 int x = c.toPixelX(note.getXVal()); 2391 int y = (note.isPixels() ? (int) (yPixel0 + 10 + 10 * pd.scalingFactor - note.getYVal()) 2392 : note.is2D ? imageView.subIndexToPixelY((int) note.getYVal()) 2393 : toPixelY(note.getYVal())); 2394 g2d.drawString(g, note.text, x + note.offsetX * pd.scalingFactor, y - note.offsetY * pd.scalingFactor); 2395 } 2396 } 2397 drawIntegralValues(Object g, int iSpec, int yOffset)2398 private void drawIntegralValues(Object g, int iSpec, int yOffset) { 2399 MeasurementData integrals = getMeasurements(AType.Integration, iSpec); 2400 if (integrals != null) { 2401 if (pd.isPrinting) 2402 pd.setFont(g, xPixels, FONT_PLAIN, 8, false); 2403 else 2404 pd.setFont(g, xPixels, FONT_BOLD, 12, false); 2405 setColorFromToken(g, ScriptToken.INTEGRALPLOTCOLOR); 2406 int h = pd.getFontHeight(); 2407 g2d.setStrokeBold(g, true); 2408 for (int i = integrals.size(); --i >= 0;) { 2409 Measurement in = integrals.get(i); 2410 if (in.getValue() == 0) 2411 continue; 2412 int x = toPixelX(in.getXVal2()); 2413 int y1 = yOffset * pd.scalingFactor + toPixelYint(in.getYVal()); 2414 int y2 = yOffset * pd.scalingFactor + toPixelYint(in.getYVal2()); 2415 if (x != fixX(x) || y1 != fixY(y1) || y2 != fixY(y2)) 2416 continue; 2417 2418 if (!pd.isPrinting) 2419 g2d.drawLine(g, x, y1, x, y2); 2420 String s = " " + in.text; 2421 g2d.drawString(g, s, x, (y1 + y2) / 2 + h / 3); 2422 } 2423 g2d.setStrokeBold(g, false); 2424 } 2425 if (iSpec == getFixedSelectedSpectrumIndex()) 2426 selectedSpectrumIntegrals = integrals; 2427 } 2428 drawMeasurements(Object g, int iSpec)2429 private void drawMeasurements(Object g, int iSpec) { 2430 MeasurementData md = getMeasurements(AType.Measurements, iSpec); 2431 if (md != null) 2432 for (int i = md.size(); --i >= 0;) 2433 drawMeasurement(g, md.get(i)); 2434 if (iSpec == getFixedSelectedSpectrumIndex()) 2435 selectedSpectrumMeasurements = md; 2436 } 2437 drawMeasurement(Object g, Measurement m)2438 private void drawMeasurement(Object g, Measurement m) { 2439 if (m.text.length() == 0 && m != pendingMeasurement) 2440 return; 2441 pd.setFont(g, xPixels, FONT_BOLD, 12, false); 2442 g2d.setGraphicsColor(g, (m == pendingMeasurement ? pd 2443 .getColor(ScriptToken.PEAKTABCOLOR) : pd.BLACK)); 2444 int x1 = toPixelX(m.getXVal()); 2445 int y1 = toPixelY(m.getYVal()); 2446 int x2 = toPixelX(m.getXVal2()); 2447 if (Double.isNaN(m.getXVal()) || x1 != fixX(x1) || x2 != fixX(x2)) 2448 return; 2449 boolean drawString = (Math.abs(x1 - x2) >= 2); 2450 boolean drawBaseLine = getScale().isYZeroOnScale() && m.spec.isHNMR(); 2451 int x = (x1 + x2) / 2; 2452 g2d.setStrokeBold(g, true); 2453 if (drawString) 2454 g2d.drawLine(g, x1, y1, x2, y1); 2455 if (drawBaseLine) 2456 g2d.drawLine(g, x1 + 1, yPixel1 - 1, x2, yPixel1 - 1); 2457 g2d.setStrokeBold(g, false); 2458 if (drawString) 2459 g2d.drawString(g, m.text, x + m.offsetX, y1 - m.offsetY); 2460 if (drawBaseLine) { 2461 g2d.drawLine(g, x1, yPixel1, x1, yPixel1 - 6 * pd.scalingFactor); 2462 g2d.drawLine(g, x2, yPixel1, x2, yPixel1 - 6 * pd.scalingFactor); 2463 } 2464 } 2465 getPinSelected(int xPixel, int yPixel)2466 private PlotWidget getPinSelected(int xPixel, int yPixel) { 2467 if (widgets != null) 2468 for (int i = 0; i < widgets.length; i++) { 2469 if (widgets[i] != null && widgets[i].isPinOrCursor 2470 && widgets[i].selected(xPixel, yPixel)) { 2471 return widgets[i]; 2472 } 2473 } 2474 return null; 2475 } 2476 set2DCrossHairs(int xPixel, int yPixel)2477 void set2DCrossHairs(int xPixel, int yPixel) { 2478 double x; 2479 if (xPixel == imageView.fixX(xPixel) && yPixel == fixY(yPixel)) { 2480 pin1Dx1.setX(x = imageView.toX(xPixel), toPixelX(x)); 2481 cur2Dx1.setX(x, xPixel); 2482 setCurrentSubSpectrum(imageView.toSubspectrumIndex(yPixel)); 2483 if (isLinked) { 2484 double y = imageView.toY(yPixel); 2485 pd.set2DCrossHairsLinked(this, x, y, !sticky2Dcursor); 2486 } 2487 } 2488 } 2489 reset2D(boolean isX)2490 private void reset2D(boolean isX) { 2491 if (isX) { 2492 imageView.setView0(imageView.xPixel0, pin2Dy0.yPixel0, imageView.xPixel1, 2493 pin2Dy1.yPixel0); 2494 doZoom(0, getScale().minY, 0, getScale().maxY, 2495 true, false, false, false, true); 2496 } else { 2497 imageView.setView0(pin2Dx0.xPixel0, imageView.yPixel0, pin2Dx1.xPixel0, 2498 imageView.yPixel1); 2499 // pd.repaint(); 2500 } 2501 } 2502 setAnnotationText(Annotation a)2503 private boolean setAnnotationText(Annotation a) { 2504 String sval = pd.getInput("New text?", "Set Label", a.text); 2505 if (sval == null) 2506 return false; 2507 if (sval.length() == 0) 2508 annotations.removeObj(a); 2509 else 2510 a.text = sval; 2511 return true; 2512 } 2513 2514 /** 2515 * @param x1 start of integral or NaN to clear 2516 * @param x2 end of (pending) integral or NaN to split 2517 * @param isFinal 2518 * @return true if successful 2519 * 2520 * 2521 * 2522 */ checkIntegral(double x1, double x2, boolean isFinal)2523 private boolean checkIntegral(double x1, double x2, boolean isFinal) { 2524 AnnotationData ad = getDialog(AType.Integration, -1); 2525 if (ad == null) 2526 return false; 2527 Integral integral = ((IntegralData) ad.getData()).addIntegralRegion(x1, x2); 2528 if (isFinal && ad.isDialog()) 2529 ((JSVDialog) ad).update(null, 0, 0); 2530 2531 if (Double.isNaN(x2)) 2532 return false; 2533 pendingIntegral = (isFinal ? null : integral); 2534 pd.isIntegralDrag = !isFinal; 2535 selectedSpectrumIntegrals = null; 2536 return true; 2537 } 2538 setToolTipForPixels(int xPixel, int yPixel)2539 private void setToolTipForPixels(int xPixel, int yPixel) { 2540 2541 2542 if (iSpectrumMovedTo != iSpectrumClicked || pd.getCurrentGraphSet() != this) { 2543 pd.setToolTipText("click spectrum to activate"); 2544 return; 2545 } 2546 if (isSplitWidget(xPixel, yPixel)) { 2547 pd.setToolTipText("click to " + (nSplit > 1 ? "combine" : "split")); 2548 return; 2549 } 2550 if (isCloserWidget(xPixel, yPixel)) { 2551 pd.setToolTipText("click to close"); 2552 return; 2553 } 2554 2555 PlotWidget pw = getPinSelected(xPixel, yPixel); 2556 int precisionX = getScale().precision[0]; 2557 int precisionY = getScale().precision[1]; 2558 2559 if (pw != null) { 2560 if (setStartupPinTip()) 2561 return; 2562 String s; 2563 if (pw == pin1Dx01 || pw == pin2Dx01) { 2564 s = DF.formatDecimalDbl(Math.min(pin1Dx0.getXVal(), pin1Dx1.getXVal()), precisionX) 2565 + " - " 2566 + DF.formatDecimalDbl(Math.max(pin1Dx0.getXVal(), pin1Dx1.getXVal()), precisionX); 2567 } else if (pw == pin1Dy01) { 2568 s = DF.formatDecimalDbl(Math.min(pin1Dy0.getYVal(), pin1Dy1.getYVal()), precisionY) 2569 + " - " 2570 + DF.formatDecimalDbl(Math.max(pin1Dy0.getYVal(), pin1Dy1.getYVal()), precisionY); 2571 } else if (pw == cur2Dy) { 2572 int isub = imageView.toSubspectrumIndex(pw.yPixel0); 2573 s = get2DYLabel(isub, precisionX); 2574 } else if (pw == pin2Dy01) { 2575 s = "" + (int) Math.min(pin2Dy0.getYVal(), pin2Dy1.getYVal()) + " - " 2576 + (int) Math.max(pin2Dy0.getYVal(), pin2Dy1.getYVal()); 2577 } else if (pw.isXtype) { 2578 s = DF.formatDecimalDbl(pw.getXVal(), precisionX); 2579 } else if (pw.is2D) { 2580 s = "" + (int) pw.getYVal(); 2581 } else { 2582 s = DF.formatDecimalDbl(pw.getYVal(), precisionY); 2583 } 2584 pd.setToolTipText(s); 2585 return; 2586 } 2587 2588 double yPt; 2589 if (imageView != null) { 2590 if (imageView.fixX(xPixel) == xPixel && fixY(yPixel) == yPixel) { 2591 2592 int isub = imageView.toSubspectrumIndex(yPixel); 2593 String s = "y=" + get2DYLabel(isub, precisionX) + 2594 " / x=" + DF.formatDecimalDbl(imageView.toX(xPixel), precisionX) + " " 2595 + getSpectrum().getAxisLabel(true); 2596 pd.setToolTipText(s); 2597 pd.coordStr = s; 2598 return; 2599 } 2600 if (!pd.display1D) { 2601 pd.setToolTipText(""); 2602 pd.coordStr = ""; 2603 return; 2604 } 2605 } 2606 double xPt = toX(fixX(xPixel)); 2607 yPt = (imageView != null && imageView.isXWithinRange(xPixel) ? imageView 2608 .toSubspectrumIndex(fixY(yPixel)) : toY(fixY(yPixel))); 2609 String xx = setCoordStr(xPt, yPt); 2610 int iSpec = getFixedSelectedSpectrumIndex(); 2611 if (!isInPlotRegion(xPixel, yPixel)) { 2612 yPt = Double.NaN; 2613 } else if (nSpectra == 1) { 2614 // I have no idea what I was thinking here... 2615 // if (!getSpectrum().isHNMR()) { 2616 // yPt = spectra[0].getPercentYValueAt(xPt); 2617 // xx += ", " + formatterY.format(yPt); 2618 // } 2619 } else if (haveIntegralDisplayed(iSpec)) { 2620 yPt = getIntegrationGraph(iSpec).getPercentYValueAt(xPt); 2621 xx += ", " + DF.formatDecimalDbl(yPt, 1); 2622 } 2623 pd.setToolTipText( 2624 (selectedIntegral != null ? "click to set value" : 2625 pendingMeasurement != null || selectedMeasurement != null ? 2626 (pd.hasFocus() ? "Press ESC to delete " 2627 + (selectedIntegral != null ? "integral, DEL to delete all visible, or N to normalize" 2628 : pendingMeasurement == null ? "\"" + selectedMeasurement.text + "\" or DEL to delete all visible" 2629 : "measurement") 2630 : "") 2631 : Double.isNaN(yPt) ? null : xx) 2632 2633 // + " :" + iSpectrumSelected + " :" + iSpectrumMovedTo 2634 2635 ); 2636 } 2637 isFrameBox(int xPixel, int yPixel, int boxX, int boxY)2638 private boolean isFrameBox(int xPixel, int yPixel, int boxX, int boxY) { 2639 return Math.abs(xPixel - (boxX + 5)) < 5 && Math.abs(yPixel - (boxY + 5)) < 5; 2640 } 2641 setCoordStr(double xPt, double yPt)2642 private String setCoordStr(double xPt, double yPt) { 2643 String xx = DF.formatDecimalDbl(xPt, getScale().precision[0]); 2644 pd.coordStr = "(" 2645 + xx 2646 + (haveSingleYScale || iSpectrumSelected >= 0 ? ", " 2647 + DF.formatDecimalDbl(yPt, getScale().precision[1]) : "") + ")"; 2648 2649 return xx; 2650 } 2651 setStartupPinTip()2652 private boolean setStartupPinTip() { 2653 if (pd.startupPinTip == null) 2654 return false; 2655 pd.setToolTipText(pd.startupPinTip); 2656 pd.startupPinTip = null; 2657 return true; 2658 } 2659 get2DYLabel(int isub, int precision)2660 private String get2DYLabel(int isub, int precision) { 2661 Spectrum spec = getSpectrumAt(0).getSubSpectra().get(isub); 2662 return DF.formatDecimalDbl(spec.getY2DPPM(), precision) + " PPM" + 2663 (spec.y2DUnits.equals("HZ") ? " (" + DF.formatDecimalDbl(spec.getY2D(), precision) 2664 + " HZ) " : ""); 2665 } 2666 isOnSpectrum(int xPixel, int yPixel, int index)2667 private boolean isOnSpectrum(int xPixel, int yPixel, int index) { 2668 Coordinate[] xyCoords = null; 2669 boolean isContinuous = true; 2670 boolean isIntegral = (index < 0); 2671 2672 // ONLY getSpectrumAt(0).is1D(); 2673 if (isIntegral) { 2674 AnnotationData ad = getDialog(AType.Integration, -1); 2675 if (ad == null) 2676 return false; 2677 xyCoords = ((IntegralData) ad.getData()).getXYCoords(); 2678 index = getFixedSelectedSpectrumIndex(); 2679 } else { 2680 setScale(index); 2681 Spectrum spec = spectra.get(index); 2682 xyCoords = spec.xyCoords; 2683 isContinuous = spec.isContinuous(); 2684 } 2685 int yOffset = index * (int) (yPixels * (yStackOffsetPercent / 100f)); 2686 2687 int ix0 = viewData.getStartingPointIndex(index); 2688 int ix1 = viewData.getEndingPointIndex(index); 2689 if (isContinuous) { 2690 for (int i = ix0; i < ix1; i++) { 2691 Coordinate point1 = xyCoords[i]; 2692 Coordinate point2 = xyCoords[i + 1]; 2693 int x1 = toPixelX(point1.getXVal()); 2694 int x2 = toPixelX(point2.getXVal()); 2695 int y1 = (isIntegral ? toPixelYint(point1.getYVal()) : toPixelY(point1 2696 .getYVal())); 2697 int y2 = (isIntegral ? toPixelYint(point2.getYVal()) : toPixelY(point2 2698 .getYVal())); 2699 if (y1 == Integer.MIN_VALUE || y2 == Integer.MIN_VALUE) 2700 continue; 2701 y1 = fixY(y1) - yOffset; 2702 y2 = fixY(y2) - yOffset; 2703 if (isOnLine(xPixel, yPixel, x1, y1, x2, y2)) 2704 return true; 2705 } 2706 } else { 2707 for (int i = ix0; i <= ix1; i++) { 2708 Coordinate point = xyCoords[i]; 2709 int y2 = toPixelY(point.getYVal()); 2710 if (y2 == Integer.MIN_VALUE) 2711 continue; 2712 int x1 = toPixelX(point.getXVal()); 2713 int y1 = toPixelY(Math.max(getScale().minYOnScale, 0)); 2714 y1 = fixY(y1); 2715 y2 = fixY(y2); 2716 if (y1 == y2 && (y1 == yPixel0 || y1 == yPixel1)) 2717 continue; 2718 if (isOnLine(xPixel, yPixel, x1, y1, x1, y2)) 2719 return true; 2720 } 2721 } 2722 return false; 2723 } 2724 2725 // static methods 2726 distance(int dx, int dy)2727 private static double distance(int dx, int dy) { 2728 return Math.sqrt(dx * dx + dy * dy); 2729 } 2730 findCompatibleGraphSet(Lst<GraphSet> graphSets, Spectrum spec)2731 private static GraphSet findCompatibleGraphSet(Lst<GraphSet> graphSets, 2732 Spectrum spec) { 2733 for (int i = 0; i < graphSets.size(); i++) 2734 if (Spectrum.areXScalesCompatible(spec, graphSets.get(i).getSpectrum(), 2735 false, false)) 2736 return graphSets.get(i); 2737 return null; 2738 } 2739 isGoodEvent(PlotWidget zOrP, PlotWidget p, boolean asX)2740 private static boolean isGoodEvent(PlotWidget zOrP, PlotWidget p, boolean asX) { 2741 return (p == null ? (Math.abs(zOrP.xPixel1 - zOrP.xPixel0) > MIN_DRAG_PIXELS && Math 2742 .abs(zOrP.yPixel1 - zOrP.yPixel0) > MIN_DRAG_PIXELS) 2743 : asX ? Math.abs(zOrP.xPixel0 - p.xPixel0) > MIN_DRAG_PIXELS : Math 2744 .abs(zOrP.yPixel0 - p.yPixel0) > MIN_DRAG_PIXELS); 2745 } 2746 2747 private final static int ONLINE_CUTOFF = 2; 2748 isOnLine(int xPixel, int yPixel, int x1, int y1, int x2, int y2)2749 private static boolean isOnLine(int xPixel, int yPixel, int x1, int y1, 2750 int x2, int y2) { 2751 // near a point 2752 int dx1 = Math.abs(x1 - xPixel); 2753 if (dx1 < ONLINE_CUTOFF && Math.abs(y1 - yPixel) < ONLINE_CUTOFF) 2754 return true; 2755 int dx2 = x2 - xPixel; 2756 if (Math.abs(dx2) < ONLINE_CUTOFF && Math.abs(y2 - yPixel) < ONLINE_CUTOFF) 2757 return true; 2758 // between points 2759 int dy12 = y1 - y2; 2760 if (Math.abs(dy12) > ONLINE_CUTOFF && (y1 < yPixel) == (y2 < yPixel)) 2761 return false; 2762 int dx12 = x1 - x2; 2763 if (Math.abs(dx12) > ONLINE_CUTOFF && (x1 < xPixel) == (x2 < xPixel)) 2764 return false; 2765 return (distance(dx1, y1 - yPixel) + distance(dx2, yPixel - y2) < distance( 2766 dx12, dy12) 2767 + ONLINE_CUTOFF); 2768 } 2769 2770 /** 2771 * 2772 * @param pd 2773 * @param graphSets 2774 * @param linkMode 2775 * NONE - a vertical stack 2776 * AB - a COSY, with 1H on left and 2D on right 2777 * ABC - a HETCOR, with 1H and 13C on left, 2D on right 2778 * 2779 */ setFractionalPositions(PanelData pd, Lst<GraphSet> graphSets, LinkMode linkMode)2780 private static void setFractionalPositions(PanelData pd, Lst<GraphSet> graphSets, 2781 LinkMode linkMode) { 2782 2783 int n = graphSets.size(); 2784 double f = 0; 2785 int n2d = 1; 2786 GraphSet gs; 2787 double y = 0; 2788 pd.isLinked = (linkMode != LinkMode.NONE); 2789 if (linkMode == LinkMode.NONE) { 2790 // for now, just a vertical stack 2791 for (int i = 0; i < n; i++) { 2792 gs = graphSets.get(i); 2793 f += (gs.getSpectrumAt(0).is1D() ? 1 : n2d) * gs.nSplit; 2794 } 2795 f = 1 / f; 2796 for (int i = 0; i < n; i++) { 2797 gs = graphSets.get(i); 2798 gs.isLinked = false; 2799 double g = (gs.getSpectrumAt(0).is1D() ? f : n2d * f); 2800 gs.fX0 = 0; 2801 gs.fY0 = y; 2802 gs.fracX = 1; 2803 gs.fracY = g; 2804 y += g * gs.nSplit; 2805 } 2806 } else { 2807 GraphSet gs2d = null; 2808 int i2d = -1; 2809 if (n == 2 || n == 3) 2810 for (int i = 0; i < n; i++) { 2811 gs = graphSets.get(i); 2812 if (!gs.getSpectrum().is1D()) { 2813 gs2d = gs; 2814 if (i2d >= 0) 2815 i = -2; 2816 i2d = i; 2817 break; 2818 } 2819 } 2820 if (i2d == -2 || i2d == -1 && n != 2) { 2821 setFractionalPositions(pd, graphSets, LinkMode.NONE); 2822 return; 2823 } 2824 for (int i = 0; i < n; i++) { 2825 gs = graphSets.get(i); 2826 gs.isLinked = true; 2827 Spectrum s1 = gs.getSpectrumAt(0); 2828 boolean is1D = s1.is1D(); 2829 if (is1D) { 2830 if (gs2d != null) { 2831 Spectrum s2 = gs2d.getSpectrumAt(0); 2832 if (Spectrum.areLinkableX(s1, s2)) 2833 gs.gs2dLinkedX = gs2d; 2834 if (Spectrum.areLinkableY(s1, s2)) 2835 gs.gs2dLinkedY = gs2d; 2836 } 2837 gs.fX0 = 0; 2838 gs.fY0 = y; 2839 gs.fracX = (gs2d == null ? 1 : 0.5); 2840 gs.fracY = (n == 3 || gs2d == null ? 0.5 : 1); 2841 y += 0.5; 2842 } else { 2843 gs.fX0 = 0.5; 2844 gs.fY0 = 0; 2845 gs.fracX = 0.5; 2846 gs.fracY = 1; 2847 } 2848 } 2849 } 2850 2851 } 2852 // highlight class 2853 2854 /** 2855 * Private class to represent a Highlighted region of the spectrum display 2856 * <p> 2857 * Title: JSpecView 2858 * </p> 2859 * <p> 2860 * Description: JSpecView is a graphical viewer for chemical spectra specified 2861 * in the JCAMP-DX format 2862 * </p> 2863 * <p> 2864 * Copyright: Copyright (c) 2002 2865 * </p> 2866 * <p> 2867 * Company: Dept. of Chemistry, University of the West Indies, Mona Campus, 2868 * Jamaica 2869 * </p> 2870 * 2871 * @author Debbie-Ann Facey 2872 * @author Khari A. Bryan 2873 * @author Prof Robert.J. Lancashire 2874 * @version 1.0.017032006 2875 */ 2876 private class Highlight { 2877 double x1; 2878 double x2; 2879 GenericColor color; 2880 Spectrum spectrum; 2881 2882 2883 @Override toString()2884 public String toString() { 2885 return "highlight " + x1 + " " + x2 + " " + spectrum; 2886 } 2887 Highlight(double x1, double x2, Spectrum spec, GenericColor color)2888 Highlight(double x1, double x2, Spectrum spec, GenericColor color) { 2889 this.x1 = x1; 2890 this.x2 = x2; 2891 this.color = color; 2892 spectrum = spec; 2893 } 2894 2895 /** 2896 * Overides the equals method in class <code>Object</code> 2897 * 2898 * @param obj 2899 * the object that this <code>Highlight<code> is compared to 2900 * @return true if equal 2901 */ 2902 2903 @Override equals(Object obj)2904 public boolean equals(Object obj) { 2905 if (!(obj instanceof Highlight)) 2906 return false; 2907 Highlight hl = (Highlight) obj; 2908 return ((hl.x1 == this.x1) && (hl.x2 == this.x2)); 2909 } 2910 } 2911 2912 // called only by PanelData 2913 addAnnotation(Lst<String> args, String title)2914 String addAnnotation(Lst<String> args, String title) { 2915 if (args.size() == 0 || args.size() == 1 2916 && args.get(0).equalsIgnoreCase("none")) { 2917 annotations = null; 2918 lastAnnotation = null; 2919 return null; 2920 } 2921 if (args.size() < 4 && lastAnnotation == null) 2922 lastAnnotation = getAnnotation( 2923 (getScale().maxXOnScale + getScale().minXOnScale) / 2, 2924 (getScale().maxYOnScale + getScale().minYOnScale) / 2, title, false, 2925 false, 0, 0); 2926 Annotation annotation = getAnnotation(args, lastAnnotation); 2927 if (annotation == null) 2928 return null; 2929 if (annotations == null && args.size() == 1 2930 && args.get(0).charAt(0) == '\"') { 2931 String s = annotation.text; 2932 getSpectrum().setTitle(s); 2933 return s; 2934 } 2935 lastAnnotation = annotation; 2936 addAnnotation(annotation, false); 2937 return null; 2938 } 2939 2940 /** 2941 * Add information about a region of the displayed spectrum to be highlighted 2942 * 2943 * @param x1 2944 * the x value of the coordinate where the highlight should start 2945 * @param x2 2946 * the x value of the coordinate where the highlight should end 2947 * @param spec 2948 * @param color 2949 * the color of the highlight 2950 */ addHighlight(double x1, double x2, Spectrum spec, GenericColor color)2951 void addHighlight(double x1, double x2, Spectrum spec, GenericColor color) { 2952 if (spec == null) 2953 spec = getSpectrumAt(0); 2954 Highlight hl = new Highlight(x1, x2, spec, (color == null ? pd 2955 .getColor(ScriptToken.HIGHLIGHTCOLOR) : color)); 2956 if (!highlights.contains(hl)) 2957 highlights.addLast(hl); 2958 } 2959 addPeakHighlight(PeakInfo peakInfo)2960 void addPeakHighlight(PeakInfo peakInfo) { 2961 for (int i = spectra.size(); --i >= 0;) { 2962 Spectrum spec = spectra.get(i); 2963 removeAllHighlights(spec); 2964 if (peakInfo == null || peakInfo.isClearAll() 2965 || spec != peakInfo.spectrum) 2966 continue; 2967 String peak = peakInfo.toString(); 2968 if (peak == null) { 2969 continue; 2970 } 2971 String xMin = PT.getQuotedAttribute(peak, "xMin"); 2972 String xMax = PT.getQuotedAttribute(peak, "xMax"); 2973 if (xMin == null || xMax == null) 2974 return; 2975 float x1 = PT.parseFloat(xMin); 2976 float x2 = PT.parseFloat(xMax); 2977 if (Float.isNaN(x1) || Float.isNaN(x2)) 2978 return; 2979 pd.addHighlight(this, x1, x2, spec, 200, 140, 140, 100); 2980 spec.setSelectedPeak(peakInfo); 2981 if (getScale().isInRangeX(x1) 2982 || getScale().isInRangeX(x2) || x1 < getScale().minX 2983 && getScale().maxX < x2) { 2984 } else { 2985 setZoomTo(0); 2986 } 2987 } 2988 } 2989 advanceSubSpectrum(int dir)2990 void advanceSubSpectrum(int dir) { 2991 Spectrum spec0 = getSpectrumAt(0); 2992 int i = spec0.advanceSubSpectrum(dir); 2993 if (spec0.isForcedSubset()) 2994 viewData.setXRangeForSubSpectrum(getSpectrum().getXYCoords()); 2995 pd.notifySubSpectrumChange(i, getSpectrum()); 2996 } 2997 checkSpectrumClickedEvent(int xPixel, int yPixel, int clickCount)2998 synchronized boolean checkSpectrumClickedEvent(int xPixel, int yPixel, int clickCount) { 2999 if (nextClickForSetPeak != null) 3000 return false; 3001 //if (clickCount > 0 && checkArrowLeftRightClick(xPixel, yPixel)) 3002 //return true; 3003 if (clickCount > 1 || pendingMeasurement != null 3004 || !isInPlotRegion(xPixel, yPixel)) 3005 return false; 3006 // in the plot area 3007 3008 if (clickCount == 0) { 3009 // pressed 3010 3011 boolean isOnIntegral = isOnSpectrum(xPixel, yPixel, -1); 3012 pd.integralShiftMode = (isOnIntegral ? getShiftMode(xPixel, yPixel) : 0); 3013 pd.isIntegralDrag = (pd.integralShiftMode == 0 && (isOnIntegral || haveIntegralDisplayed(-1) 3014 && findMeasurement(getIntegrationGraph(-1), xPixel, yPixel, Measurement.PT_ON_LINE) != null)); 3015 if (pd.integralShiftMode != 0) 3016 return false; 3017 } 3018 3019 if (!showAllStacked) 3020 return false; 3021 // in the stacked plot area 3022 3023 stackSelected = false; 3024 for (int i = 0; i < nSpectra; i++) { 3025 if (!isOnSpectrum(xPixel, yPixel, i)) 3026 continue; 3027 //boolean isNew = (i != iSpectrumSelected); 3028 setSpectrumClicked(iPreviousSpectrumClicked = i); 3029 return false; 3030 } 3031 // but not on a spectrum 3032 if (isDialogOpen()) 3033 return false; 3034 setSpectrumClicked(-1); 3035 return stackSelected = false; 3036 } 3037 getShiftMode(int xPixel, int yPixel)3038 private int getShiftMode(int xPixel, int yPixel) { 3039 return (isStartEndIntegral(xPixel, false) ? yPixel : isStartEndIntegral( 3040 xPixel, true) ? -yPixel : 0); 3041 } 3042 isDialogOpen()3043 private boolean isDialogOpen() { 3044 return (isVisible(getDialog(AType.Integration, -1)) 3045 || isVisible(getDialog(AType.Measurements, -1)) || isVisible(getDialog( 3046 AType.PeakList, -1))); 3047 } 3048 isStartEndIntegral(int xPixel, boolean isEnd)3049 private boolean isStartEndIntegral(int xPixel, boolean isEnd) { 3050 return (isEnd ? xPixelPlot1 - xPixel < 20 : xPixel - xPixelPlot0 < 20); 3051 } 3052 3053 private boolean widgetsAreSet = true; 3054 private int lastIntDragX; 3055 private int nextClickMode; 3056 checkWidgetEvent(int xPixel, int yPixel, boolean isPress)3057 synchronized boolean checkWidgetEvent(int xPixel, int yPixel, boolean isPress) { 3058 if (!widgetsAreSet) 3059 return false; 3060 widgetsAreSet = false; 3061 PlotWidget widget; 3062 if (isPress) { 3063 if (pd.clickCount == 2 && lastIntDragX != xPixel && !is2dClick(xPixel, yPixel)) { 3064 if (pendingMeasurement == null) { 3065 if (iSpectrumClicked == -1 && iPreviousSpectrumClicked >= 0) { 3066 setSpectrumClicked(iPreviousSpectrumClicked); 3067 } 3068 processPendingMeasurement(xPixel, yPixel, 2); 3069 return true; 3070 } 3071 } else if (!is2dClick(xPixel, yPixel)){ 3072 if (isOnSpectrum(xPixel, yPixel, -1)) { 3073 // split 3074 checkIntegral(toX(xPixel), Double.NaN, false); 3075 } 3076 3077 if (lastIntDragX == xPixel) { 3078 // restart 3079 pd.isIntegralDrag = true; 3080 if (!checkIntegral(toX(xPixel), toX(xPixel), false)) 3081 return false; 3082 } 3083 } 3084 if (pendingMeasurement != null) 3085 return true; 3086 3087 widget = getPinSelected(xPixel, yPixel); 3088 if (widget == null) { 3089 yPixel = fixY(yPixel); 3090 if (xPixel < xPixel1) { 3091 if (pd.shiftPressed) 3092 setSpectrumClicked(iPreviousSpectrumClicked); 3093 xPixel = fixX(xPixel); 3094 if (zoomBox1D == null) 3095 newPins(); 3096 zoomBox1D.setX(toX(xPixel), xPixel); 3097 zoomBox1D.yPixel0 = yPixel; 3098 widget = zoomBox1D; 3099 } else if (imageView != null && xPixel < imageView.xPixel1) { 3100 zoomBox2D.setX(imageView.toX(xPixel), imageView.fixX(xPixel)); 3101 zoomBox2D.yPixel0 = yPixel; 3102 widget = zoomBox2D; 3103 } 3104 } 3105 pd.thisWidget = widget; 3106 return false; 3107 } 3108 nextClickForSetPeak = null; 3109 widget = pd.thisWidget; 3110 if (widget == null) 3111 return false; 3112 // mouse drag with widget 3113 if (widget == zoomBox1D) { 3114 zoomBox1D.xPixel1 = fixX(xPixel); 3115 zoomBox1D.yPixel1 = fixY(yPixel); 3116 if (pd.isIntegralDrag && zoomBox1D.xPixel0 != zoomBox1D.xPixel1) { 3117 if ((lastIntDragX <= xPixel) != (zoomBox1D.xPixel0 <= xPixel)) { 3118 // switched direction of integral drag 3119 zoomBox1D.xPixel0 = lastIntDragX; 3120 zoomBox1D.xPixel1 = xPixel; 3121 zoomBox1D.setXVal(toX(zoomBox1D.xPixel0)); 3122 } 3123 lastIntDragX = xPixel; 3124 checkIntegral(zoomBox1D.getXVal(), toX(zoomBox1D.xPixel1), false); 3125 } 3126 return false; 3127 } 3128 if (!zoomEnabled) 3129 return false; 3130 if (widget == zoomBox2D) { 3131 zoomBox2D.xPixel1 = imageView.fixX(xPixel); 3132 zoomBox2D.yPixel1 = fixY(yPixel); 3133 return true; 3134 } 3135 if (widget == cur2Dy) { 3136 yPixel = fixY(yPixel); 3137 cur2Dy.yPixel0 = cur2Dy.yPixel1 = yPixel; 3138 setCurrentSubSpectrum(imageView.toSubspectrumIndex(yPixel)); 3139 return true; 3140 } 3141 if (widget == cur2Dx0 || widget == cur2Dx1) { 3142 // xPixel = imageView.fixX(xPixel); 3143 // widget.setX(imageView.toX(xPixel), xPixel); 3144 // 2D x zoom change 3145 // doZoom(cur2Dx0.getXVal(), getScale().minY, cur2Dx1.getXVal(), 3146 // getScale().maxY, false, false, false, true); 3147 return false; 3148 } 3149 if (widget == pin1Dx0 || widget == pin1Dx1 || widget == pin1Dx01) { 3150 xPixel = fixX(xPixel); 3151 widget.setX(toX0(xPixel), xPixel); 3152 if (widget == pin1Dx01) { 3153 int dp = xPixel - ((pin1Dx0.xPixel0 + pin1Dx1.xPixel0) / 2); 3154 int dp1 = (dp < 0 ? dp : dp); 3155 int dp2 = (dp < 0 ? dp : dp); 3156 xPixel = pin1Dx0.xPixel0 + dp2; 3157 int xPixel1 = pin1Dx1.xPixel0 + dp1; 3158 if (dp == 0 || fixX(xPixel) != xPixel || fixX(xPixel1) != xPixel1) 3159 return true; 3160 pin1Dx0.setX(toX0(xPixel), xPixel); 3161 pin1Dx1.setX(toX0(xPixel1), xPixel1); 3162 3163 } 3164 // 1D x zoom change 3165 doZoom(pin1Dx0.getXVal(), 0, pin1Dx1.getXVal(), 0, true, false, false, 3166 true, false); 3167 return true; 3168 } 3169 if (widget == pin1Dy0 || widget == pin1Dy1 || widget == pin1Dy01) { 3170 yPixel = fixY(yPixel); 3171 widget.setY(toY0(yPixel), yPixel); 3172 if (widget == pin1Dy01) { 3173 int dp = yPixel - (pin1Dy0.yPixel0 + pin1Dy1.yPixel0) / 2 + 1; 3174 yPixel = pin1Dy0.yPixel0 + dp; 3175 int yPixel1 = pin1Dy1.yPixel0 + dp; 3176 double y0 = toY0(yPixel); 3177 double y1 = toY0(yPixel1); 3178 if (Math.min(y0, y1) == getScale().minY 3179 || Math.max(y0, y1) == getScale().maxY) 3180 return true; 3181 pin1Dy0.setY(y0, yPixel); 3182 pin1Dy1.setY(y1, yPixel1); 3183 } 3184 // y-only zoom 3185 doZoom(0, pin1Dy0.getYVal(), 0, pin1Dy1.getYVal(), imageView == null, 3186 imageView == null, false, false, false); 3187 return true; 3188 } 3189 if (widget == pin2Dx0 || widget == pin2Dx1 || widget == pin2Dx01) { 3190 xPixel = imageView.fixX(xPixel); 3191 widget.setX(imageView.toX0(xPixel), xPixel); 3192 if (widget == pin2Dx01) { 3193 int dp = xPixel - (pin2Dx0.xPixel0 + pin2Dx1.xPixel0) / 2 + 1; 3194 xPixel = pin2Dx0.xPixel0 + dp; 3195 int xPixel1 = pin2Dx1.xPixel0 + dp; 3196 if (imageView.fixX(xPixel) != xPixel 3197 || imageView.fixX(xPixel1) != xPixel1) 3198 return true; 3199 pin2Dx0.setX(imageView.toX0(xPixel), xPixel); 3200 pin2Dx1.setX(imageView.toX0(xPixel1), xPixel1); 3201 } 3202 if (!isGoodEvent(pin2Dx0, pin2Dx1, true)) { 3203 reset2D(true); 3204 return true; 3205 } 3206 imageView.setView0(pin2Dx0.xPixel0, pin2Dy0.yPixel0, pin2Dx1.xPixel0, 3207 pin2Dy1.yPixel0); 3208 // 2D x zoom 3209 doZoom(pin2Dx0.getXVal(), getScale().minY, pin2Dx1.getXVal(), 3210 getScale().maxY, false, false, false, true, false); 3211 return true; 3212 } 3213 if (widget == pin2Dy0 || widget == pin2Dy1 || widget == pin2Dy01) { 3214 yPixel = fixY(yPixel); 3215 widget.setY(imageView.toSubspectrumIndex(yPixel), yPixel); 3216 if (widget == pin2Dy01) { 3217 int dp = yPixel - (pin2Dy0.yPixel0 + pin2Dy1.yPixel0) / 2 + 1; 3218 yPixel = pin2Dy0.yPixel0 + dp; 3219 int yPixel1 = pin2Dy1.yPixel0 + dp; 3220 if (yPixel != fixY(yPixel) || yPixel1 != fixY(yPixel1)) 3221 return true; 3222 pin2Dy0.setY(imageView.toSubspectrumIndex(yPixel), yPixel); 3223 pin2Dy1.setY(imageView.toSubspectrumIndex(yPixel1), yPixel1); 3224 } 3225 if (!isGoodEvent(pin2Dy0, pin2Dy1, false)) { 3226 reset2D(false); 3227 return true; 3228 } 3229 imageView.setView0(pin2Dx0.xPixel0, pin2Dy0.yPixel0, pin2Dx1.xPixel1, 3230 pin2Dy1.yPixel1); 3231 // update2dImage(false); 3232 return true; 3233 } 3234 return false; 3235 } 3236 clearIntegrals()3237 void clearIntegrals() { 3238 checkIntegral(Double.NaN, 0, false); 3239 } 3240 clearMeasurements()3241 void clearMeasurements() { 3242 removeDialog(getFixedSelectedSpectrumIndex(), AType.Measurements); 3243 } 3244 createGraphSetsAndSetLinkMode(PanelData pd, JSVPanel jsvp, Lst<Spectrum> spectra, int startIndex, int endIndex, LinkMode linkMode)3245 static Lst<GraphSet> createGraphSetsAndSetLinkMode(PanelData pd, JSVPanel jsvp, 3246 Lst<Spectrum> spectra, int startIndex, int endIndex, LinkMode linkMode) { 3247 Lst<GraphSet> graphSets = new Lst<GraphSet>(); 3248 for (int i = 0; i < spectra.size(); i++) { 3249 Spectrum spec = spectra.get(i); 3250 GraphSet graphSet = (linkMode == LinkMode.NONE ? findCompatibleGraphSet(graphSets, spec) : null); 3251 if (graphSet == null) 3252 graphSets.addLast(graphSet = new GraphSet(jsvp.getPanelData())); 3253 graphSet.addSpec(spec); 3254 } 3255 setFractionalPositions(pd, graphSets, linkMode); 3256 for (int i = graphSets.size(); --i >= 0;) { 3257 graphSets.get(i).initGraphSet(startIndex, endIndex); 3258 Logger.info("JSVGraphSet " + (i + 1) + " nSpectra = " 3259 + graphSets.get(i).nSpectra); 3260 } 3261 return graphSets; 3262 } 3263 3264 /** 3265 * 3266 * entry point for a repaint 3267 * 3268 * @param gMain primary canvas 3269 * @param gFront front-pane (glass pane) canvas 3270 * @param gBack back-pane canvas 3271 * @param width 3272 * @param height 3273 * @param left 3274 * @param right 3275 * @param top 3276 * @param bottom 3277 * @param isResized 3278 * @param taintedAll 3279 * @param pointsOnly 3280 */ drawGraphSet(Object gMain, Object gFront, Object gBack, int width, int height, int left, int right, int top, int bottom, boolean isResized, boolean taintedAll, boolean pointsOnly)3281 synchronized void drawGraphSet(Object gMain, Object gFront, Object gBack, 3282 int width, int height, int left, int right, int top, int bottom, 3283 boolean isResized, boolean taintedAll, boolean pointsOnly) { 3284 3285 zoomEnabled = pd.getBoolean(ScriptToken.ENABLEZOOM); 3286 this.height = height * pd.scalingFactor; 3287 this.width = width * pd.scalingFactor; 3288 this.left = left * pd.scalingFactor; 3289 this.right = right * pd.scalingFactor; 3290 this.top = top * pd.scalingFactor; 3291 this.bottom = bottom * pd.scalingFactor; 3292 // yValueMovedTo = Double.NaN; 3293 haveSelectedSpectrum = false; 3294 selectedSpectrumIntegrals = null; 3295 selectedSpectrumMeasurements = null; 3296 if (!pd.isPrinting && widgets != null) 3297 for (int j = 0; j < widgets.length; j++) 3298 if (widgets[j] != null) 3299 widgets[j].isVisible = false; 3300 for (int iSplit = 0; iSplit < nSplit; iSplit++) { 3301 // for now, at least, we only allow one 2D image 3302 setPositionForFrame(iSplit); 3303 drawAll(gMain, gFront, gBack, iSplit, isResized || nSplit > 1, taintedAll, pointsOnly); 3304 } 3305 setPositionForFrame(nSplit > 1 ? pd.currentSplitPoint : 0); 3306 if (pd.isPrinting) 3307 return; 3308 } 3309 escapeKeyPressed(boolean isDEL)3310 synchronized void escapeKeyPressed(boolean isDEL) { 3311 if (zoomBox1D != null) 3312 zoomBox1D.xPixel0 = zoomBox1D.xPixel1 = 0; 3313 if (zoomBox2D != null) 3314 zoomBox2D.xPixel0 = zoomBox2D.xPixel1 = 0; 3315 if (!inPlotMove) 3316 return; 3317 if (pendingMeasurement != null) { 3318 pendingMeasurement = null; 3319 return; 3320 } 3321 pd.thisWidget = null; 3322 pendingMeasurement = null; 3323 if (selectedSpectrumMeasurements != null && selectedMeasurement != null) { 3324 if (isDEL) 3325 selectedSpectrumMeasurements.clear(getScale().minXOnScale, 3326 getScale().maxXOnScale); 3327 else 3328 selectedSpectrumMeasurements.removeObj(selectedMeasurement); 3329 selectedMeasurement = null; 3330 updateDialog(AType.Measurements, -1); 3331 } 3332 if (selectedSpectrumIntegrals != null && selectedIntegral != null) { 3333 if (isDEL) 3334 selectedSpectrumIntegrals.clear(getScale().minXOnScale, 3335 getScale().maxXOnScale); 3336 else 3337 selectedSpectrumIntegrals.removeObj(selectedIntegral); 3338 selectedIntegral = null; 3339 updateDialog(AType.Integration, -1); 3340 } 3341 } 3342 findGraphSet(Lst<GraphSet> graphSets, int xPixel, int yPixel)3343 static GraphSet findGraphSet(Lst<GraphSet> graphSets, int xPixel, int yPixel) { 3344 for (int i = graphSets.size(); --i >= 0;) 3345 if (graphSets.get(i).hasPoint(xPixel, yPixel)) 3346 return graphSets.get(i); 3347 return null; 3348 } 3349 findMatchingPeakInfo(PeakInfo pi)3350 PeakInfo findMatchingPeakInfo(PeakInfo pi) { 3351 PeakInfo pi2 = null; 3352 for (int i = 0; i < spectra.size(); i++) 3353 if ((pi2 = (spectra.get(i)).findMatchingPeakInfo(pi)) != null) 3354 break; 3355 return pi2; 3356 } 3357 getCurrentSpectrumIndex()3358 int getCurrentSpectrumIndex() { 3359 return (nSpectra == 1 ? 0 : iSpectrumSelected); 3360 } 3361 getSelectedIntegral()3362 Integral getSelectedIntegral() { 3363 return selectedIntegral; 3364 } 3365 getShowAnnotation(AType type, int i)3366 boolean getShowAnnotation(AType type, int i) { 3367 AnnotationData id = getDialog(type, i); 3368 return (id != null && id.getState()); 3369 } 3370 hasFileLoaded(String filePath)3371 boolean hasFileLoaded(String filePath) { 3372 for (int i = spectra.size(); --i >= 0;) 3373 if (spectra.get(i).getFilePathForwardSlash().equals(filePath)) 3374 return true; 3375 return false; 3376 } 3377 haveSelectedSpectrum()3378 boolean haveSelectedSpectrum() { 3379 return haveSelectedSpectrum; 3380 } 3381 mouseClickedEvent(int xPixel, int yPixel, int clickCount, boolean isControlDown)3382 synchronized void mouseClickedEvent(int xPixel, int yPixel, int clickCount, 3383 boolean isControlDown) { 3384 selectedMeasurement = null; 3385 selectedIntegral = null; 3386 Double isNextClick = nextClickForSetPeak; 3387 nextClickForSetPeak = null; 3388 if (checkArrowUpDownClick(xPixel, yPixel) 3389 || checkArrowLeftRightClick(xPixel, yPixel)) 3390 return; 3391 lastClickX = Double.NaN; 3392 lastPixelX = Integer.MAX_VALUE; 3393 if (isSplitWidget(xPixel, yPixel)) { 3394 splitStack(nSplit == 1); 3395 return; 3396 } 3397 if (isCloserWidget(xPixel, yPixel)) { 3398 pd.closeSpectrum(); 3399 return; 3400 } 3401 PlotWidget pw = getPinSelected(xPixel, yPixel); 3402 if (pw != null) { 3403 setWidgetValueByUser(pw); 3404 return; 3405 } 3406 boolean is2D = is2dClick(xPixel, yPixel); 3407 if (clickCount == 2 && iSpectrumClicked == -1 3408 && iPreviousSpectrumClicked >= 0) { 3409 setSpectrumClicked(iPreviousSpectrumClicked); 3410 } 3411 if (!is2D && isControlDown) { 3412 setSpectrumClicked(iPreviousSpectrumClicked); 3413 if (pendingMeasurement != null) { 3414 processPendingMeasurement(xPixel, yPixel, -3); 3415 } else if (iSpectrumClicked >= 0) { 3416 processPendingMeasurement(xPixel, yPixel, 3); 3417 } 3418 return; 3419 } 3420 lastXMax = Double.NaN; // TODO: was for "is2D || !isControlDown 3421 if (clickCount == 2) { 3422 if (is2D) { 3423 if (sticky2Dcursor) { 3424 addAnnotation( 3425 getAnnotation(imageView.toX(xPixel), 3426 imageView.toSubspectrumIndex(yPixel), pd.coordStr, false, 3427 true, 5, 5), true); 3428 } 3429 3430 sticky2Dcursor = true;//!sticky2Dcursor; 3431 set2DCrossHairs(xPixel, yPixel); 3432 return; 3433 } 3434 3435 // 1D double-click 3436 3437 if (isInTopBar(xPixel, yPixel)) { 3438 // 1D x zoom reset to original 3439 doZoom(toX0(xPixel0), 0, toX0(xPixel1), 0, true, false, false, true, 3440 true); 3441 } else if (isInRightBar(xPixel, yPixel)) { 3442 doZoom(getScale().minXOnScale, viewList.get(0).getScale().minYOnScale, 3443 getScale().maxXOnScale, viewList.get(0).getScale().maxYOnScale, 3444 true, true, false, false, false); 3445 } else if (isInTopBar2D(xPixel, yPixel)) { 3446 reset2D(true); 3447 } else if (isInRightBar2D(xPixel, yPixel)) { 3448 reset2D(false); 3449 } else if (pendingMeasurement != null) { 3450 processPendingMeasurement(xPixel, yPixel, -2); 3451 } else if (iSpectrumClicked >= 0) { 3452 processPendingMeasurement(xPixel, yPixel, 2); 3453 } 3454 return; 3455 } 3456 3457 // single click 3458 3459 if (is2D) { 3460 if (annotations != null) { 3461 Coordinate xy = new Coordinate().set(imageView.toX(xPixel), 3462 imageView.toSubspectrumIndex(yPixel)); 3463 Annotation a = findAnnotation2D(xy); 3464 if (a != null && setAnnotationText(a)) { 3465 return; 3466 } 3467 } 3468 if (clickCount == 1) 3469 sticky2Dcursor = false; 3470 set2DCrossHairs(xPixel, yPixel); 3471 return; 3472 } 3473 3474 // 1D single click 3475 3476 if (isInPlotRegion(xPixel, yPixel)) { 3477 if (selectedSpectrumIntegrals != null 3478 && checkIntegralNormalizationClick(xPixel, yPixel)) 3479 return; 3480 if (pendingMeasurement != null) { 3481 processPendingMeasurement(xPixel, yPixel, 1); 3482 return; 3483 } 3484 3485 setCoordClicked(xPixel, toX(xPixel), toY(yPixel)); 3486 updateDialog(AType.PeakList, -1); 3487 if (isNextClick != null) { 3488 nextClickForSetPeak = isNextClick; 3489 shiftSpectrum(SHIFT_CLICKED, Double.NaN, Double.NaN); 3490 nextClickForSetPeak = null; 3491 return; 3492 } 3493 3494 3495 } else { 3496 setCoordClicked(0, Double.NaN, 0); 3497 } 3498 pd.notifyPeakPickedListeners(null); 3499 } 3500 is2dClick(int xPixel, int yPixel)3501 private boolean is2dClick(int xPixel, int yPixel) { 3502 return (imageView != null && xPixel == imageView.fixX(xPixel) && yPixel == fixY(yPixel)); 3503 } 3504 updateDialog(AType type, int iSpec)3505 private void updateDialog(AType type, int iSpec) { 3506 AnnotationData ad = getDialog(type, iSpec); 3507 if (ad == null || !isVisible(ad)) 3508 return; 3509 double xRange = toX(xPixel1) - toX(xPixel0); 3510 int yOffset = (getSpectrum().isInverted() ? yPixel1 - pd.mouseY : pd.mouseY - yPixel0); 3511 ((JSVDialog) ad).update(pd.coordClicked, xRange, yOffset); 3512 } 3513 isVisible(AnnotationData ad)3514 private boolean isVisible(AnnotationData ad) { 3515 return ad != null && (ad.isDialog() && ad.isVisible()); 3516 } 3517 3518 mousePressedEvent(int xPixel, int yPixel, int clickCount)3519 public void mousePressedEvent(int xPixel, int yPixel, int clickCount) { 3520 checkWidgetEvent(xPixel, yPixel, true); 3521 } 3522 3523 /** 3524 * @param xPixel 3525 * @param yPixel 3526 */ mouseReleasedEvent(int xPixel, int yPixel)3527 synchronized void mouseReleasedEvent(int xPixel, int yPixel) { 3528 if (pendingMeasurement != null) { 3529 if (Math.abs(toPixelX(pendingMeasurement.getXVal()) - xPixel) < 2) 3530 pendingMeasurement = null; 3531 processPendingMeasurement(xPixel, yPixel, -2); 3532 setToolTipForPixels(xPixel, yPixel); 3533 return; 3534 } 3535 if (pd.integralShiftMode != 0) { 3536 pd.integralShiftMode = 0; 3537 zoomBox1D.xPixel1 = zoomBox1D.xPixel0; 3538 return; 3539 } 3540 if (iSpectrumMovedTo >= 0) 3541 setScale(iSpectrumMovedTo); 3542 PlotWidget thisWidget = pd.thisWidget; 3543 if (pd.isIntegralDrag) { 3544 if (isGoodEvent(zoomBox1D, null, true)) { 3545 checkIntegral(toX(zoomBox1D.xPixel0), toX(zoomBox1D.xPixel1), true); 3546 } 3547 zoomBox1D.xPixel1 = zoomBox1D.xPixel0 = 0; 3548 pendingIntegral = null; 3549 pd.isIntegralDrag = false; 3550 } else if (thisWidget == zoomBox2D) { 3551 if (!isGoodEvent(zoomBox2D, null, true)) 3552 return; 3553 imageView.setZoom(zoomBox2D.xPixel0, zoomBox2D.yPixel0, 3554 zoomBox2D.xPixel1, zoomBox2D.yPixel1); 3555 zoomBox2D.xPixel1 = zoomBox2D.xPixel0; 3556 // 2D xy zoom 3557 doZoom(imageView.toX(imageView.xPixel0), getScale().minY, imageView 3558 .toX(imageView.xPixel0 + imageView.xPixels - 1), getScale().maxY, false, 3559 false, false, true, true); 3560 } else if (thisWidget == zoomBox1D) { 3561 if (!isGoodEvent(zoomBox1D, null, true)) 3562 return; 3563 int x1 = zoomBox1D.xPixel1; 3564 // 1D x zoom by zoomBox 3565 boolean doY = (pd.shiftPressed); 3566 doZoom(toX(zoomBox1D.xPixel0), 3567 (doY ? toY(zoomBox1D.yPixel0) : 0), 3568 toX(x1), 3569 (doY ? toY(zoomBox1D.yPixel1) : 0), 3570 true, doY, true, true, true); 3571 zoomBox1D.xPixel1 = zoomBox1D.xPixel0; 3572 } else if (thisWidget == pin1Dx0 || thisWidget == pin1Dx1 3573 || thisWidget == cur2Dx0 || thisWidget == cur2Dx1) { 3574 addCurrentZoom(); 3575 } 3576 } 3577 mouseMovedEvent(int xPixel, int yPixel)3578 synchronized void mouseMovedEvent(int xPixel, int yPixel) { 3579 if (nSpectra > 1) { 3580 3581 int iFrame = getSplitPoint(yPixel); 3582 setPositionForFrame(iFrame); 3583 setSpectrumMovedTo(nSplit > 1 ? iFrame : iSpectrumSelected); 3584 if (iSpectrumMovedTo >= 0) 3585 setScale(iSpectrumMovedTo); 3586 } 3587 inPlotMove = isInPlotRegion(xPixel, yPixel); 3588 setXPixelMovedTo(Double.MAX_VALUE, Double.MAX_VALUE, (inPlotMove ? xPixel : -1), -1); 3589 if (inPlotMove) { 3590 xValueMovedTo = toX(xPixelMovedTo); 3591 yValueMovedTo = getSpectrum().getYValueAt(xValueMovedTo); 3592 } 3593 if (pd.integralShiftMode != 0) { 3594 AnnotationData ad = getDialog(AType.Integration, -1); 3595 Coordinate[] xy = ((IntegralData) ad.getData()).getXYCoords(); 3596 double y = xy[pd.integralShiftMode > 0 ? xy.length - 1 : 0].getYVal(); 3597 3598 ((IntegralData) ad.getData()).shiftY(pd.integralShiftMode, toPixelYint(y) + yPixel 3599 - (pd.integralShiftMode > 0 ? yPixelPlot1 : yPixelPlot0), yPixel0, 3600 yPixels); 3601 } else if (pd.isIntegralDrag) { 3602 } else if (pendingMeasurement != null) { 3603 processPendingMeasurement(xPixel, yPixel, 0); 3604 setToolTipForPixels(xPixel, yPixel); 3605 } else { 3606 selectedMeasurement = (inPlotMove && selectedSpectrumMeasurements != null ? findMeasurement( 3607 selectedSpectrumMeasurements, xPixel, yPixel,Measurement.PT_ON_LINE) 3608 : null); 3609 selectedIntegral = null; 3610 if (inPlotMove && selectedSpectrumIntegrals != null 3611 && selectedMeasurement == null) { 3612 selectedIntegral = (Integral) findMeasurement( 3613 selectedSpectrumIntegrals, xPixel, yPixel, Measurement.PT_ON_LINE); 3614 if (selectedIntegral == null) 3615 selectedIntegral = (Integral) findMeasurement( 3616 selectedSpectrumIntegrals, xPixel, yPixel, Measurement.PT_INT_LABEL); 3617 } 3618 setToolTipForPixels(xPixel, yPixel); 3619 if (imageView == null) { 3620 piMouseOver = null; 3621 int iSpec = (nSplit > 1 ? iSpectrumMovedTo : iSpectrumClicked); 3622 if (!isDrawNoSpectra() && iSpec >= 0) { 3623 Spectrum spec = spectra.get(iSpec); 3624 if (spec.getPeakList() != null) { 3625 coordTemp.setXVal(toX(xPixel)); 3626 coordTemp.setYVal(toY(yPixel)); 3627 piMouseOver = spec.findPeakByCoord(xPixel, coordTemp); 3628 } 3629 } 3630 } else { 3631 if (!pd.display1D && sticky2Dcursor) { 3632 set2DCrossHairs(xPixel, yPixel); 3633 } 3634 } 3635 } 3636 } 3637 3638 /** 3639 * Displays the next view zoomed 3640 */ nextView()3641 void nextView() { 3642 if (currentZoomIndex + 1 < viewList.size()) 3643 setZoomTo(currentZoomIndex + 1); 3644 } 3645 3646 /** 3647 * Displays the previous view zoomed 3648 */ previousView()3649 void previousView() { 3650 if (currentZoomIndex > 0) 3651 setZoomTo(currentZoomIndex - 1); 3652 } 3653 3654 /** 3655 * Resets the spectrum to it's original view 3656 */ resetView()3657 void resetView() { 3658 setZoomTo(0); 3659 } 3660 removeAllHighlights()3661 void removeAllHighlights() { 3662 removeAllHighlights(null); 3663 } 3664 3665 /** 3666 * Remove the highlight at the specified index in the internal list of 3667 * highlights The index depends on the order in which the highlights were 3668 * added 3669 * 3670 * @param index 3671 * the index of the highlight in the list 3672 */ removeHighlight(int index)3673 void removeHighlight(int index) { 3674 highlights.removeItemAt(index); 3675 } 3676 3677 /** 3678 * Remove the highlight specified by the starting and ending x value 3679 * 3680 * @param x1 3681 * the x value of the coordinate where the highlight started 3682 * @param x2 3683 * the x value of the coordinate where the highlight ended 3684 */ removeHighlight(double x1, double x2)3685 void removeHighlight(double x1, double x2) { 3686 for (int i = highlights.size(); --i >= 0;) { 3687 Highlight h = highlights.get(i); 3688 if (h.x1 == x1 && h.x2 == x2) 3689 highlights.removeItemAt(i); 3690 } 3691 } 3692 scaleYBy(double factor)3693 void scaleYBy(double factor) { 3694 if (imageView == null && !zoomEnabled) 3695 return; 3696 // from CTRL +/- 3697 viewData.scaleSpectrum(imageView == null ? iSpectrumSelected : -2, factor); 3698 if (imageView != null) { 3699 update2dImage(false); 3700 resetPinsFromView(); 3701 } 3702 pd.refresh(); 3703 // view.scaleSpectrum(-1, factor); 3704 } 3705 3706 /** 3707 * here we are selecting a spectrum based on a message from Jmol matching type 3708 * and model 3709 * 3710 * @param filePath 3711 * @param type 3712 * @param model 3713 * @return haveFound 3714 */ selectSpectrum(String filePath, String type, String model)3715 boolean selectSpectrum(String filePath, String type, String model) { 3716 boolean haveFound = false; 3717 for (int i = spectra.size(); --i >= 0;) 3718 if ((filePath == null || getSpectrumAt(i).getFilePathForwardSlash() 3719 .equals(filePath)) 3720 && (getSpectrumAt(i).matchesPeakTypeModel(type, model))) { 3721 setSpectrumSelected(i); 3722 if (nSplit > 1) 3723 splitStack(true); 3724 haveFound = true; 3725 } 3726 if (nSpectra > 1 && !haveFound && iSpectrumSelected >= 0 3727 && !pd.isCurrentGraphSet(this)) 3728 setSpectrumSelected(Integer.MIN_VALUE); // no plots in that case 3729 return haveFound; 3730 } 3731 selectPeakByFileIndex(String filePath, String index, String atomKey)3732 PeakInfo selectPeakByFileIndex(String filePath, String index, String atomKey) { 3733 PeakInfo pi; 3734 for (int i = spectra.size(); --i >= 0;) 3735 if ((pi = getSpectrumAt(i).selectPeakByFileIndex(filePath, index, atomKey)) != null) 3736 return pi; 3737 return null; 3738 } 3739 setSelected(int i)3740 void setSelected(int i) { 3741 if (i < 0) { 3742 bsSelected.clearAll(); 3743 setSpectrumClicked(-1); 3744 return; 3745 } 3746 bsSelected.set(i); 3747 setSpectrumClicked((bsSelected.cardinality() == 1 ? i : -1)); 3748 if (nSplit > 1 && i >= 0) 3749 pd.currentSplitPoint = i; 3750 } 3751 setSelectedIntegral(double val)3752 void setSelectedIntegral(double val) { 3753 Spectrum spec = selectedIntegral.getSpectrum(); 3754 getIntegrationGraph(getSpectrumIndex(spec)).setSelectedIntegral( 3755 selectedIntegral, val); 3756 } 3757 3758 /** 3759 * turn on or off a PeakList, Integration, or Measurement dialog 3760 * 3761 * @param type 3762 * @param tfToggle 3763 */ setShowAnnotation(AType type, Boolean tfToggle)3764 void setShowAnnotation(AType type, Boolean tfToggle) { 3765 AnnotationData id = getDialog(type, -1); 3766 if (id == null) { 3767 if (tfToggle != null && tfToggle != Boolean.TRUE) 3768 return; // does not exist and "OFF" -- ignore 3769 // does not exist, and TOGGLE or ON 3770 if (type == AType.PeakList || type == AType.Integration || type == AType.Measurements) 3771 pd.showDialog(type); 3772 return; 3773 } 3774 if (tfToggle == null) { 3775 // exists and "TOGGLE", but id could be an AnnotationData, not a JDialog 3776 if (id.isDialog()) 3777 ((JSVDialog) id).setVisible(!((JSVDialog) id).isVisible()); 3778 // was tfToggle != null && ((AnnotationDialog) id).isVisible()); 3779 else 3780 pd.showDialog(type); // was id.setState(!id.getState()); 3781 return; 3782 } 3783 // exists and "ON" or "OFF" 3784 boolean isON = tfToggle.booleanValue(); 3785 if (isON) 3786 id.setState(isON); 3787 if (isON || id.isDialog()) 3788 pd.showDialog(type); 3789 if (!isON && id.isDialog()) 3790 ((JSVDialog) id).setVisible(false); 3791 3792 // if (type == AType.Integration) 3793 // checkIntegral(parameters, "UPDATE"); 3794 // id.setState(tfToggle == null ? !id.getState() : tfToggle.booleanValue()); 3795 } 3796 checkIntegralParams(Parameters parameters, String value)3797 boolean checkIntegralParams(Parameters parameters, String value) { 3798 Spectrum spec = getSpectrum(); 3799 if (!spec.canIntegrate() || reversePlot) 3800 return false; 3801 int iSpec = getFixedSelectedSpectrumIndex(); 3802 AnnotationData ad = getDialog(AType.Integration, -1); 3803 if (value == null)// && ad != null) 3804 return true; 3805 switch (IntegralData.IntMode.getMode(value.toUpperCase())) { 3806 case NA: 3807 return false; 3808 case CLEAR: 3809 integrate(iSpec, null); 3810 integrate(iSpec, parameters); 3811 break; 3812 case ON: 3813 if (ad == null) 3814 integrate(iSpec, parameters); 3815 else 3816 ad.setState(true); 3817 break; 3818 case OFF: 3819 if (ad != null) 3820 ad.setState(false); 3821 // integrate(iSpec, null); 3822 break; 3823 case TOGGLE: 3824 if (ad == null) 3825 integrate(iSpec, parameters); 3826 else 3827 ad.setState(!ad.getState()); 3828 // integrate(iSpec, ad == null ? parameters : null); 3829 break; 3830 case AUTO: 3831 if (ad == null) { 3832 checkIntegralParams(parameters, "ON"); 3833 ad = getDialog(AType.Integration, -1); 3834 } 3835 if (ad != null) 3836 ((IntegralData) ad.getData()).autoIntegrate(); 3837 break; 3838 case LIST: 3839 pd.showDialog(AType.Integration); 3840 break; 3841 case MARK: 3842 if (ad == null) { 3843 checkIntegralParams(parameters, "ON"); 3844 ad = getDialog(AType.Integration, -1); 3845 } 3846 if (ad != null) 3847 ((IntegralData) ad.getData()).addMarks(value.substring(4).trim()); 3848 break; 3849 case MIN: 3850 if (ad != null) { 3851 try { 3852 double val = Double.parseDouble(ScriptToken.getTokens(value).get(1)); 3853 ((IntegralData) ad.getData()).setMinimumIntegral(val); 3854 } catch (Exception e) { 3855 // ignore 3856 } 3857 } 3858 break; 3859 case UPDATE: 3860 if (ad != null) 3861 ((IntegralData) ad.getData()).update(parameters); 3862 } 3863 updateDialog(AType.Integration, -1); 3864 return true; 3865 } 3866 setSpectrum(int iSpec, boolean fromSplit)3867 void setSpectrum(int iSpec, boolean fromSplit) { 3868 if (fromSplit && nSplit > 1) { 3869 if (nSplit > 1) 3870 setSpectrumClicked(iSpec); 3871 } else { 3872 setSpectrumClicked(iSpec); 3873 stackSelected = false; 3874 showAllStacked = false; 3875 } 3876 if (iSpec >= 0) 3877 dialogsToFront(getSpectrum()); 3878 } 3879 setSpectrumJDX(Spectrum spec)3880 void setSpectrumJDX(Spectrum spec) { 3881 // T/A conversion for IR 3882 int pt = getFixedSelectedSpectrumIndex(); 3883 spectra.removeItemAt(pt); 3884 spectra.add(pt, spec); 3885 pendingMeasurement = null; 3886 clearViews(); 3887 viewData.newSpectrum(spectra); 3888 } 3889 setZoom(double x1, double y1, double x2, double y2)3890 void setZoom(double x1, double y1, double x2, double y2) { 3891 // called by 3892 // 1. double-clicking on a tree node in the application to reset (0,0,0,0) 3893 // 2. the YSCALE command (0,y1,0,y2) 3894 // 3. the ZOOM command (0,0,0,0) or (x1, 0, x2, 0) or (x1, y1, x2, y2) 3895 setZoomTo(0); 3896 if (x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0) { 3897 newPins(); 3898 // reset gray-factors as well 3899 imageView = null; 3900 // in case this is linked, transmit the x-zoom to linked spectra 3901 x1 = getScale().minXOnScale; 3902 x2 = getScale().maxXOnScale; 3903 //} else if (x1 == 0 && x2 == 0) { 3904 // // y zoom only 3905 // x1 = x2 = 0; 3906 // imageView = null; 3907 } else { 3908 doZoom(x1, y1, x2, y2, true, (y1 != y2), false, true, true); 3909 } 3910 } 3911 static final int SHIFT_PEAK = 1; 3912 static final int SHIFT_SETX = 2; 3913 static final int SHIFT_X = 3; 3914 static final int SHIFT_CLICKED = 4; 3915 3916 /** 3917 * apply a shift to the x-axis based on the next click or a specified value 3918 * 3919 * @param mode 3920 * one of PEAK(1), SETX(2), X(3), CLICKED(4) 3921 * @param xOld 3922 * initial position or NaN to ask, or value 3923 * @param xNew 3924 * DOUBLE_MAX_VALUE - reset, NaN - ask, or value 3925 * @return true if accomplished 3926 */ shiftSpectrum(int mode, double xOld, double xNew)3927 boolean shiftSpectrum(int mode, double xOld, double xNew) { 3928 3929 Spectrum spec = getSpectrum(); 3930 if (!spec.isNMR() || !spec.is1D()) 3931 return false; 3932 String ok = null; 3933 double dx = 0; 3934 if (xNew == Double.MAX_VALUE) { 3935 // setPeak NONE or setX NONE 3936 dx = -spec.addSpecShift(0); 3937 } else { 3938 switch (mode) { 3939 case SHIFT_X: 3940 dx = xNew; 3941 break; 3942 case SHIFT_PEAK: 3943 case SHIFT_SETX: 3944 nextClickMode = mode; 3945 if (Double.isNaN(xOld)) { 3946 ok = pd 3947 .getInput( 3948 "Click on " 3949 + (mode == SHIFT_PEAK ? "or beside a peak to set its chemical shift" 3950 : "the spectrum set the chemical shift at that point") 3951 + (xNew == Integer.MIN_VALUE ? "" : " to " + xNew) + ".", 3952 "Set Reference " 3953 + (mode == SHIFT_PEAK ? "for Peak" : "at Point"), "OK"); 3954 nextClickForSetPeak = ("OK".equals(ok) ? Double.valueOf(xNew) : null); 3955 return false; 3956 } 3957 nextClickForSetPeak = null; 3958 //$FALL-THROUGH$ 3959 case SHIFT_CLICKED: 3960 if (nextClickForSetPeak != null) { 3961 xNew = nextClickForSetPeak.doubleValue(); 3962 nextClickForSetPeak = null; 3963 } 3964 if (Double.isNaN(xOld)) 3965 xOld = lastClickX; 3966 if (nextClickMode == SHIFT_PEAK) 3967 xOld = getNearestPeak(spec, xOld, toY(pd.mouseY)); 3968 if (Double.isNaN(xNew)) 3969 try { 3970 String s = pd.getInput("New chemical shift (set blank to reset)", 3971 "Set Reference", 3972 DF.formatDecimalDbl(xOld, getScale().precision[0])).trim(); 3973 if (s.length() == 0) 3974 xNew = xOld - spec.addSpecShift(0); 3975 else 3976 xNew = Double.parseDouble(s); 3977 } catch (Exception e) { 3978 return false; 3979 } 3980 dx = xNew - xOld; 3981 break; 3982 } 3983 } 3984 if (dx == 0) 3985 return false; 3986 spec.addSpecShift(dx); 3987 if (annotations != null) 3988 for (int i = annotations.size(); --i >= 0;) 3989 if (annotations.get(i).spec == spec) 3990 annotations.get(i).addSpecShift(dx); 3991 if (dialogs != null) 3992 for (Map.Entry<String, AnnotationData> e : dialogs.entrySet()) 3993 if (e.getValue().getSpectrum() == spec) 3994 e.getValue().setSpecShift(dx); 3995 // double dx0 = getScale().specShift; 3996 // for (int i = viewList.size(); --i >= 0;) 3997 // viewList.get(i).addSpecShift(dx); 3998 // if (getScale().specShift == dx0) 3999 getScale().addSpecShift(dx); 4000 if (!Double.isNaN(lastClickX)) 4001 lastClickX += dx; 4002 updateDialogs(); 4003 doZoom(0, getScale().minYOnScale, 0, getScale().maxYOnScale, true, true, 4004 false, true, false); 4005 pd.setTaintedAll(); 4006 pd.repaint(); 4007 return true; 4008 } 4009 toPeak(int istep)4010 void toPeak(int istep) { 4011 istep *= (drawXAxisLeftToRight ? 1 : -1); 4012 if (Double.isNaN(lastClickX)) 4013 lastClickX = lastPixelX = 0; 4014 Spectrum spec = getSpectrum(); 4015 Coordinate coord = setCoordClicked(lastPixelX, lastClickX, 0); 4016 int iPeak = spec.setNextPeak(coord, istep); 4017 if (iPeak < 0) 4018 return; 4019 PeakInfo peak = spec.getPeakList().get(iPeak); 4020 spec.setSelectedPeak(peak); 4021 setCoordClicked(peak.getXPixel(), peak.getX(), 0); 4022 pd.notifyPeakPickedListeners(new PeakPickEvent(jsvp, pd.coordClicked, 4023 peak)); 4024 } 4025 4026 // methods that only act on SELECTED spectra 4027 scaleSelectedBy(double f)4028 void scaleSelectedBy(double f) { 4029 for (int i = bsSelected.nextSetBit(0); i >= 0; i = bsSelected 4030 .nextSetBit(i + 1)) 4031 viewData.scaleSpectrum(i, f); 4032 } 4033 4034 // overridden methods 4035 4036 4037 @Override toString()4038 public String toString() { 4039 return "gs: " + nSpectra + " " + spectra + " " 4040 + spectra.get(0).getFilePath(); 4041 } 4042 setXPointer(Spectrum spec, double x)4043 void setXPointer(Spectrum spec, double x) { 4044 if (spec != null) 4045 setSpectrumClicked(getSpectrumIndex(spec)); 4046 xValueMovedTo = lastClickX = x; 4047 lastPixelX = toPixelX(x); 4048 setXPixelMovedTo(x, Double.MAX_VALUE, 0, 0); 4049 yValueMovedTo = Double.NaN; 4050 } 4051 setXPointer2(Spectrum spec, double x)4052 void setXPointer2(Spectrum spec, double x) { 4053 if (spec != null) 4054 setSpectrumClicked(getSpectrumIndex(spec)); 4055 setXPixelMovedTo(Double.MAX_VALUE, x, 0, 0); 4056 } 4057 hasCurrentMeasurement(AType type)4058 boolean hasCurrentMeasurement(AType type) { 4059 return ((type == AType.Integration ? selectedSpectrumIntegrals 4060 : selectedSpectrumMeasurements) != null); 4061 } 4062 4063 private Map<String, AnnotationData> dialogs; 4064 private Object[] aIntegrationRatios; 4065 getDialog(AType type, int iSpec)4066 AnnotationData getDialog(AType type, int iSpec) { 4067 if (iSpec == -1) 4068 iSpec = getCurrentSpectrumIndex(); 4069 return (dialogs == null || iSpec < 0 ? null : dialogs.get(type + "_" + iSpec)); 4070 } 4071 removeDialog(int iSpec, AType type)4072 void removeDialog(int iSpec, AType type) { 4073 if (dialogs != null && iSpec >= 0) 4074 dialogs.remove(type + "_" + iSpec); 4075 } 4076 addDialog(int iSpec, AType type, AnnotationData dialog)4077 AnnotationData addDialog(int iSpec, AType type, AnnotationData dialog) { 4078 // if (iSpec < 0) { 4079 // iSpec = getSpectrumIndex(dialog.getSpectrum()); 4080 // dialog = null; 4081 // } 4082 if (dialogs == null) 4083 dialogs = new Hashtable<String, AnnotationData>(); 4084 String key = type + "_" + iSpec; 4085 dialog.setGraphSetKey(key); 4086 dialogs.put(key, dialog); 4087 return dialog; 4088 } 4089 removeDialog(JSVDialog dialog)4090 void removeDialog(JSVDialog dialog) { 4091 String key = dialog.getGraphSetKey(); 4092 dialogs.remove(key); 4093 AnnotationData data = dialog.getData(); 4094 if (data != null) 4095 dialogs.put(key, data); 4096 } 4097 getPeakListing(int iSpec, Parameters p, boolean forceNew)4098 MeasurementData getPeakListing(int iSpec, Parameters p, boolean forceNew) { 4099 if (iSpec < 0) 4100 iSpec = getCurrentSpectrumIndex(); 4101 if (iSpec < 0) 4102 return null; 4103 AnnotationData dialog = getDialog(AType.PeakList, -1); 4104 if (dialog == null) { 4105 if (!forceNew) 4106 return null; 4107 addDialog(iSpec, AType.PeakList, dialog = new PeakData(AType.PeakList, 4108 getSpectrum())); 4109 } 4110 ((PeakData) dialog.getData()).setPeakList(p, Integer.MIN_VALUE, viewData.getScale()); 4111 if (dialog.isDialog()) 4112 ((JSVDialog) dialog).setFields(); 4113 return dialog.getData(); 4114 } 4115 setPeakListing(Boolean tfToggle)4116 void setPeakListing(Boolean tfToggle) { 4117 AnnotationData dialog = getDialog(AType.PeakList, -1); 4118 JSVDialog ad = (dialog != null && dialog.isDialog() ? (JSVDialog) dialog : null); 4119 boolean isON = (tfToggle == null ? ad == null || !ad.isVisible() : tfToggle.booleanValue()); 4120 if (isON) { 4121 pd.showDialog(AType.PeakList); 4122 } else { 4123 if (dialog.isDialog()) 4124 ((JSVDialog) dialog).setVisible(false); 4125 } 4126 } 4127 haveIntegralDisplayed(int i)4128 boolean haveIntegralDisplayed(int i) { 4129 AnnotationData ad = getDialog(AType.Integration, i); 4130 return (ad != null && ad.getState()); 4131 } 4132 getIntegrationGraph(int i)4133 IntegralData getIntegrationGraph(int i) { 4134 AnnotationData ad = getDialog(AType.Integration, i); 4135 return (ad == null ? null : (IntegralData) ad.getData()); 4136 } 4137 setIntegrationRatios(String value)4138 void setIntegrationRatios(String value) { 4139 int iSpec = getFixedSelectedSpectrumIndex(); 4140 if (aIntegrationRatios == null) 4141 aIntegrationRatios = new Object[nSpectra]; 4142 aIntegrationRatios[iSpec] = IntegralData.getIntegrationRatiosFromString( 4143 getSpectrum(), value); 4144 } 4145 4146 /** 4147 * deprecated -- or at least not compatible with multiple spectra 4148 * 4149 * @param i 4150 * @return list 4151 */ 4152 @SuppressWarnings("unchecked") getIntegrationRatios(int i)4153 Lst<Annotation> getIntegrationRatios(int i) { 4154 return (Lst<Annotation>) (aIntegrationRatios == null ? null 4155 : aIntegrationRatios[i]); 4156 } 4157 integrate(int iSpec, Parameters parameters)4158 boolean integrate(int iSpec, Parameters parameters) { 4159 Spectrum spec = getSpectrumAt(iSpec); 4160 if (parameters == null || !spec.canIntegrate()) { 4161 removeDialog(iSpec, AType.Integration); 4162 return false; 4163 } 4164 addDialog(iSpec, AType.Integration, new IntegralData(spec, parameters)); 4165 return true; 4166 } 4167 getIntegration(int iSpec, Parameters p, boolean forceNew)4168 IntegralData getIntegration(int iSpec, Parameters p, boolean forceNew) { 4169 if (iSpec < 0) 4170 iSpec = getCurrentSpectrumIndex(); 4171 if (iSpec < 0) 4172 return null; 4173 AnnotationData dialog = getDialog(AType.Integration, -1); 4174 if (dialog == null) { 4175 if (!forceNew) 4176 return null; 4177 dialog = addDialog(iSpec, AType.Integration, new IntegralData(getSpectrum(), p)); 4178 } 4179 return (IntegralData) dialog.getData(); 4180 } 4181 getMeasurementInfo(AType type, int iSpec)4182 Map<String, Object> getMeasurementInfo(AType type, int iSpec) { 4183 MeasurementData md; 4184 switch (type) { 4185 case PeakList: 4186 md = getPeakListing(iSpec, null, false); 4187 break; 4188 case Integration: 4189 md = getIntegration(iSpec, null, false); 4190 break; 4191 default: 4192 return null; 4193 } 4194 if (md == null) 4195 return null; 4196 Map<String, Object> info = new Hashtable<String, Object>(); 4197 md.getInfo(info); 4198 return info; 4199 } 4200 getInfo(String key, int iSpec)4201 Map<String, Object> getInfo(String key, int iSpec) { 4202 Map<String, Object> spectraInfo = new Hashtable<String, Object>(); 4203 if ("".equals(key)) { 4204 spectraInfo.put("KEYS", "viewInfo spectra"); 4205 } else if ("viewInfo".equalsIgnoreCase(key)) 4206 return getScale().getInfo(spectraInfo); 4207 Lst<Map<String, Object>> specInfo = new Lst<Map<String, Object>>(); 4208 spectraInfo.put("spectra", specInfo); 4209 for (int i = 0; i < nSpectra; i++) { 4210 if (iSpec >= 0 && i != iSpec) 4211 continue; 4212 Spectrum spec = spectra.get(i); 4213 Map<String, Object> info = spec.getInfo(key); 4214 if (iSpec >= 0 && key != null 4215 && (info.size() == 2 || key.equalsIgnoreCase("id"))) { 4216 if (info.size() == 2) 4217 info.remove("id"); 4218 return info; 4219 } 4220 Parameters.putInfo(key, info, "type", spec.getDataType()); 4221 Parameters.putInfo(key, info, "titleLabel", spec.getTitleLabel()); 4222 Parameters.putInfo(key, info, "filePath", spec.getFilePath().replace('\\', '/')); 4223 Parameters.putInfo(key, info, "PeakList", (Parameters.isMatch(key, 4224 "PeakList") ? getMeasurementInfo(AType.PeakList, i) : null)); 4225 Parameters.putInfo(key, info, "Integration", (Parameters.isMatch(key, 4226 "Integration") ? getMeasurementInfo(AType.Integration, i) : null)); 4227 if (iSpec >= 0) 4228 return info; 4229 specInfo.addLast(info); 4230 } 4231 return spectraInfo; 4232 } 4233 4234 /** 4235 * 4236 * @param forPrinting (could be preparing to print) 4237 * @return null if ambiguous, otherwise JDXSpectrum.getTitle() 4238 * 4239 */ getTitle(boolean forPrinting)4240 String getTitle(boolean forPrinting) { 4241 return (nSpectra == 1 || iSpectrumSelected >= 0 && (!forPrinting || nSplit == 1) ? 4242 getSpectrum().getTitle() : null); 4243 } 4244 getCurrentView()4245 ScaleData getCurrentView() { 4246 setScale(getFixedSelectedSpectrumIndex()); 4247 return viewData.getScale(); 4248 } 4249 set2DXY(double x, double y, boolean isLocked)4250 void set2DXY(double x, double y, boolean isLocked) { 4251 int p; 4252 if (gs2dLinkedX != null) { 4253 p = toPixelX(x); 4254 if(p != fixX(p)) { 4255 p = Integer.MIN_VALUE; 4256 x = Double.MAX_VALUE; 4257 } 4258 cur1D2x1.setX(x, p); 4259 } 4260 if (gs2dLinkedY != null) { 4261 p = toPixelX(y); 4262 if(p != fixX(p)) { 4263 p = Integer.MIN_VALUE; 4264 y = Double.MAX_VALUE; 4265 } 4266 cur1D2x2.setX(y, p); 4267 } 4268 cur1D2Locked = isLocked; 4269 } 4270 dialogsToFront(Spectrum spec)4271 void dialogsToFront(Spectrum spec) { 4272 if (dialogs == null) 4273 return; 4274 if (spec == null) 4275 spec = getSpectrum(); 4276 for (Map.Entry<String, AnnotationData> e : dialogs.entrySet()) { 4277 AnnotationData ad = e.getValue(); 4278 if (isVisible(ad)) { 4279 if (spec == null) 4280 ((JSVDialog) ad).setVisible(true); 4281 else 4282 ((JSVDialog) ad).setFocus(ad.getSpectrum() == spec); 4283 } 4284 } 4285 } 4286 4287 4288 //////////////////////////// WAS AWTGRAPHSET ////////////// 4289 4290 setPlotColors(Object oColors)4291 void setPlotColors(Object oColors) { 4292 GenericColor[] colors = (GenericColor[]) oColors; 4293 if (colors.length > nSpectra) { 4294 GenericColor[] tmpPlotColors = new GenericColor[nSpectra]; 4295 System.arraycopy(colors, 0, tmpPlotColors, 0, nSpectra); 4296 colors = tmpPlotColors; 4297 } else if (nSpectra > colors.length) { 4298 GenericColor[] tmpPlotColors = new GenericColor[nSpectra]; 4299 int numAdditionColors = nSpectra - colors.length; 4300 System.arraycopy(colors, 0, tmpPlotColors, 0, colors.length); 4301 for (int i = 0, j = colors.length; i < numAdditionColors; i++, j++) 4302 tmpPlotColors[j] = generateRandomColor(); 4303 colors = tmpPlotColors; 4304 } 4305 plotColors = colors; 4306 } 4307 4308 private JSVPanel jsvp; 4309 private Object image2D; 4310 private GenericColor[] plotColors; 4311 private GenericGraphics g2d; 4312 private Object gMain; 4313 4314 disposeImage()4315 private void disposeImage() { 4316 /** 4317 * @j2sNative 4318 * 4319 * if (this.image2D != null) 4320 * this.image2D.parentNode.removeChild(this.image2D); 4321 * 4322 */ 4323 {} 4324 image2D = null; 4325 jsvp = null; 4326 pd = null; 4327 highlights = null; 4328 plotColors = null; 4329 } 4330 4331 generateRandomColor()4332 private GenericColor generateRandomColor() { 4333 while (true) { 4334 int red = (int) (Math.random() * 255); 4335 int green = (int) (Math.random() * 255); 4336 int blue = (int) (Math.random() * 255); 4337 GenericColor randomColor = g2d.getColor3(red, green, blue); 4338 if (randomColor.getRGB() != 0) 4339 return randomColor; 4340 } 4341 } 4342 setPlotColor0(Object oColor)4343 void setPlotColor0(Object oColor) { 4344 plotColors[0] = (GenericColor) oColor; 4345 } 4346 4347 /** 4348 * Returns the color of the plot at a certain index 4349 * 4350 * @param index 4351 * the index 4352 * @return the color of the plot 4353 */ getPlotColor(int index)4354 GenericColor getPlotColor(int index) { 4355 if (index >= plotColors.length) 4356 return null; 4357 return plotColors[index]; 4358 } 4359 4360 setColorFromToken(Object og, ScriptToken whatColor)4361 private void setColorFromToken(Object og, ScriptToken whatColor) { 4362 if (whatColor != null) 4363 g2d.setGraphicsColor(og, 4364 whatColor == ScriptToken.PLOTCOLOR ? plotColors[0] : pd 4365 .getColor(whatColor)); 4366 } 4367 4368 private final int COLOR_GREY = -3; 4369 private final int COLOR_BLACK = -2; 4370 private final int COLOR_INTEGRAL = -1; 4371 setPlotColor(Object og, int i)4372 private void setPlotColor(Object og, int i) { 4373 GenericColor c; 4374 switch (i) { 4375 case COLOR_GREY: 4376 c = veryLightGrey; 4377 break; 4378 case COLOR_BLACK: 4379 c = pd.BLACK; 4380 break; 4381 case COLOR_INTEGRAL: 4382 c = pd.getColor(ScriptToken.INTEGRALPLOTCOLOR); 4383 break; 4384 default: 4385 c = plotColors[i]; 4386 break; 4387 } 4388 g2d.setGraphicsColor(og, c); 4389 } 4390 4391 /////////////// 2D image ///////////////// 4392 4393 draw2DImage()4394 private void draw2DImage() { 4395 if (imageView != null) 4396 g2d.drawGrayScaleImage(gMain, image2D, imageView.xPixel0, imageView.yPixel0, // destination 4397 imageView.xPixel0 + imageView.xPixels - 1, // destination 4398 imageView.yPixel0 + imageView.yPixels - 1, // destination 4399 imageView.xView1, imageView.yView1, imageView.xView2, imageView.yView2); // source 4400 } 4401 4402 get2DImage(Spectrum spec0)4403 private boolean get2DImage(Spectrum spec0) { 4404 imageView = new ImageView(); 4405 imageView.set(viewList.get(0).getScale()); 4406 if (!update2dImage(true)) 4407 return false; 4408 imageView.resetZoom(); 4409 sticky2Dcursor = true;// I don't know why 4410 return true; 4411 } 4412 4413 update2dImage(boolean isCreation)4414 private boolean update2dImage(boolean isCreation) { 4415 imageView.set(viewData.getScale()); 4416 Spectrum spec = getSpectrumAt(0); 4417 int[] buffer = imageView.get2dBuffer(spec, !isCreation); 4418 if (buffer == null) { 4419 image2D = null; 4420 imageView = null; 4421 return false; 4422 } 4423 if (isCreation) { 4424 buffer = imageView.adjustView(spec, viewData); 4425 imageView.resetView(); 4426 } 4427 image2D = g2d.newGrayScaleImage(gMain, image2D, imageView.imageWidth, imageView.imageHeight, buffer); 4428 setImageWindow(); 4429 return true; 4430 } 4431 getAnnotation(double x, double y, String text, boolean isPixels, boolean is2d, int offsetX, int offsetY)4432 private Annotation getAnnotation(double x, double y, String text, 4433 boolean isPixels, boolean is2d, int offsetX, int offsetY) { 4434 return new ColoredAnnotation().setCA(x, y, getSpectrum(), text, pd.BLACK, 4435 isPixels, is2d, offsetX, offsetY); 4436 } 4437 getAnnotation(Lst<String> args, Annotation lastAnnotation)4438 private Annotation getAnnotation(Lst<String> args, Annotation lastAnnotation) { 4439 return Annotation.getColoredAnnotation(g2d, getSpectrum(), args, lastAnnotation); 4440 } 4441 fillBox(Object g, int x0, int y0, int x1, int y1, ScriptToken whatColor)4442 private void fillBox(Object g, int x0, int y0, int x1, int y1, 4443 ScriptToken whatColor) { 4444 setColorFromToken(g, whatColor); 4445 g2d.fillRect(g, Math.min(x0, x1), Math.min(y0, y1), Math.abs(x0 4446 - x1), Math.abs(y0 - y1)); 4447 } 4448 drawBox(Object g, int x0, int y0, int x1, int y1, ScriptToken whatColor)4449 private void drawBox(Object g, int x0, int y0, int x1, int y1, 4450 ScriptToken whatColor) { 4451 setColorFromToken(g, whatColor); 4452 g2d.drawRect(g, Math.min(x0, x1), Math.min(y0, y1), Math.abs(x0 - x1) - 1, 4453 Math.abs(y0 - y1) - 1); 4454 } 4455 drawHandle(Object g, int x, int y, int size, boolean outlineOnly)4456 private void drawHandle(Object g, int x, int y, int size, boolean outlineOnly) { 4457 if (outlineOnly) 4458 g2d.drawRect(g, x - size, y - size, size*2, size*2); 4459 else 4460 g2d.fillRect(g, x - size, y - size, size*2 + 1, size*2+1); 4461 } 4462 setCurrentBoxColor(Object g)4463 private void setCurrentBoxColor(Object g) { 4464 g2d.setGraphicsColor(g, pd.BLACK); 4465 } 4466 fillArrow(Object g, int type, int x, int y, boolean doFill)4467 private void fillArrow(Object g, int type, int x, int y, boolean doFill) { 4468 int f = 1; 4469 switch (type) { 4470 case ARROW_LEFT: 4471 case ARROW_UP: 4472 f = -1; 4473 break; 4474 } 4475 int[] axPoints = new int[] { x - 5, x - 5, x + 5, x + 5, x + 8, x, x - 8 }; 4476 int[] ayPoints = new int[] { y + 5*f, y - f, y - f, y + 5*f, y + 5*f, y + 10*f, y + 5*f }; 4477 switch (type) { 4478 case ARROW_LEFT: 4479 case ARROW_RIGHT: 4480 if (doFill) 4481 g2d.fillPolygon(g, ayPoints, axPoints, 7); 4482 else 4483 g2d.drawPolygon(g, ayPoints, axPoints, 7); 4484 break; 4485 case ARROW_UP: 4486 case ARROW_DOWN: 4487 if (doFill) 4488 g2d.fillPolygon(g, axPoints, ayPoints, 7); 4489 else 4490 g2d.drawPolygon(g, axPoints, ayPoints, 7); 4491 4492 } 4493 } 4494 fillCircle(Object g, int x, int y, boolean doFill)4495 private void fillCircle(Object g, int x, int y, boolean doFill) { 4496 if (doFill) 4497 g2d.fillCircle(g, x-4, y-4, 8); 4498 else 4499 g2d.drawCircle(g, x-4, y-4, 8); 4500 } 4501 setAnnotationColor(Object g, Annotation note, ScriptToken whatColor)4502 void setAnnotationColor(Object g, Annotation note, 4503 ScriptToken whatColor) { 4504 if (whatColor != null) { 4505 setColorFromToken(g, whatColor); 4506 return; 4507 } 4508 GenericColor color = null; 4509 if (note instanceof ColoredAnnotation) 4510 color = ((ColoredAnnotation) note).getColor(); 4511 if (color == null) 4512 color = pd.BLACK; 4513 g2d.setGraphicsColor(g, color); 4514 } 4515 setSolutionColor(VisibleInterface vi, boolean isNone, boolean asFitted)4516 public void setSolutionColor(VisibleInterface vi, boolean isNone, boolean asFitted) { 4517 for (int i = 0; i < nSpectra; i++) { 4518 Spectrum spec = spectra.get(i); 4519 int color = (isNone || !spec.canShowSolutionColor() ? -1 : vi.getColour(spec, asFitted)); 4520 spec.setFillColor(color == -1 ? null : pd.vwr.parameters.getColor1(color)); 4521 } 4522 } 4523 setIRMode(IRMode mode, String type)4524 public void setIRMode(IRMode mode, String type) { 4525 for (int i = 0; i < nSpectra; i++) { 4526 Spectrum spec = spectra.get(i); 4527 if (!spec.dataType.equals(type)) 4528 continue; 4529 Spectrum spec2 = Spectrum.taConvert(spec, mode); 4530 if (spec2 != spec) 4531 pd.setSpecForIRMode(spec2); 4532 } 4533 } 4534 getSpectrumCount()4535 public int getSpectrumCount() { 4536 // TODO Auto-generated method stub 4537 return 0; 4538 } 4539 invertYAxis()4540 public void invertYAxis() { 4541 viewList.get(0).init(null, 0, 0, getSpectrum().invertYAxis().isContinuous()); 4542 resetViewCompletely(); 4543 } 4544 4545 } 4546