1 package jspecview.dialog; 2 3 import java.util.Map; 4 5 import javajs.util.DF; 6 7 import javajs.util.PT; 8 9 import jspecview.api.AnnotationData; 10 import jspecview.api.JSVPanel; 11 import jspecview.api.PlatformDialog; 12 import jspecview.common.Annotation; 13 import jspecview.common.Coordinate; 14 import jspecview.common.IntegralData; 15 import jspecview.common.Spectrum; 16 import jspecview.common.JSViewer; 17 import jspecview.common.MeasurementData; 18 import jspecview.common.PanelData; 19 import jspecview.common.Parameters; 20 import jspecview.common.PeakData; 21 22 abstract public class JSVDialog extends Annotation implements AnnotationData { 23 getPosXY()24 abstract public int[] getPosXY(); 25 26 @Override isDialog()27 public boolean isDialog() { 28 return true; 29 } 30 31 public String optionKey; 32 public Map<String, Object> options; 33 34 protected AType type; 35 protected String title; 36 protected JSViewer vwr; 37 protected Spectrum spec; 38 protected DialogManager manager; 39 protected PlatformDialog dialog; 40 protected JSVPanel jsvp; 41 protected Object txt1, txt2, txt3; 42 protected Object combo1; // measurement listing, peaks 43 protected MeasurementData xyData; 44 protected Parameters myParams; 45 protected int precision = 1; 46 47 private int[] loc; 48 private Object showHideButton; // text changeable 49 private boolean addClearBtn, addCombo1; 50 protected boolean addApplyBtn; 51 private boolean isNumeric; // not Views or OverlayLegend 52 private boolean defaultVisible; // not OverlayLegend 53 private String subType; 54 private String graphSetKey; 55 private Object[][] tableData; 56 private boolean addUnits; 57 private String[] unitOptions; 58 private int[] formatOptions; 59 private Integer unitPtr; 60 private boolean isON = true; 61 addUniqueControls()62 abstract protected void addUniqueControls(); 63 callback(String id, String msg)64 abstract public boolean callback(String id, String msg); 65 66 /** 67 * 68 * required initializer; from JSViewer 69 * 70 * @param title 71 * @param viewer 72 * @param spec 73 * @return this 74 */ setParams(String title, JSViewer viewer, Spectrum spec)75 public JSVDialog setParams(String title, JSViewer viewer, Spectrum spec) { 76 title = DialogManager.fixTitle(title); 77 this.title = title; 78 this.vwr = viewer; 79 this.spec = spec; 80 manager = viewer.getDialogManager(); 81 jsvp = viewer.selectedPanel; 82 myParams = ((Parameters) viewer.getPlatformInterface("Parameters")) 83 .setName("dialogParams"); 84 subType = (spec == null ? "!" : spec.getTypeLabel()); 85 optionKey = type + "_" + subType; 86 options = manager.getDialogOptions(); 87 if (spec != null) { 88 Object[] specOptions = spec.getDefaultAnnotationInfo(type); 89 options.put(optionKey, specOptions); 90 unitOptions = (String[]) specOptions[0]; 91 formatOptions = (int[]) specOptions[1]; 92 unitPtr = (Integer) options.get(optionKey + "_unitPtr"); 93 if (unitPtr == null) 94 unitPtr = (Integer) specOptions[2]; 95 } 96 switch (type) { 97 case Integration: 98 isNumeric = true; 99 addClearBtn = true; 100 defaultVisible = true; 101 addApplyBtn = true; 102 break; 103 case Measurements: 104 isNumeric = true; 105 addClearBtn = true; 106 // no apply button 107 addCombo1 = true; 108 defaultVisible = true; 109 break; 110 case OverlayLegend: 111 break; 112 case PeakList: 113 isNumeric = true; 114 addApplyBtn = true; 115 defaultVisible = true; 116 break; 117 case Views: 118 defaultVisible = true; 119 break; 120 case NONE: 121 break; 122 } 123 initDialog(); 124 return this; 125 } 126 127 128 // //// frame construction //////// 129 initDialog()130 private void initDialog() { 131 dialog = manager.getDialog(this); 132 restoreDialogPosition(jsvp, getPosXY()); 133 dialog.setTitle(title); 134 layoutDialog(); 135 } 136 layoutDialog()137 protected void layoutDialog() { 138 dialog.startLayout(); 139 addUniqueControls(); 140 if (isNumeric) { 141 getUnitOptions(); 142 if (addCombo1) 143 combo1 = dialog.addSelectOption("cmbUnits", "Units", unitOptions, 144 unitPtr.intValue(), addUnits); 145 // txtFontSize = ((DialogHelper dialogHelper)).addInputOption("FontSize", 146 // "Font Size", null, null, "10"); 147 if (addApplyBtn) 148 dialog.addButton("btnApply", "Apply"); 149 showHideButton = dialog.addButton("btnShow", "Show"); 150 if (addClearBtn) 151 dialog.addButton("btnClear", "Clear"); 152 } 153 dialog.endLayout(); 154 checkEnables(); 155 dialog.setVisible(defaultVisible); 156 } 157 158 /** 159 * @param id 160 * @param msg 161 * @return true if consumed 162 */ callbackAD(String id, String msg)163 protected boolean callbackAD(String id, String msg) { 164 if (id.equals("FOCUS")) { 165 eventFocus(); 166 } else if (id.equals("tableSelect")) { 167 tableSelect(msg); 168 } else if (id.equals("btnClear")) { 169 clear(); 170 } else if (id.equals("btnApply")) { 171 eventApply(); 172 } else if (id.equals("btnShow")) { 173 String label = dialog.getText(showHideButton); 174 eventShowHide(label.equals("Show")); 175 } else if (id.equals("cmbUnits")) { 176 setPrecision(dialog.getSelectedIndex(combo1)); 177 } else if (id.startsWith("txt")) { 178 eventApply(); 179 } else if (id.equals("windowClosing")) { 180 done(); 181 return true; 182 } 183 if (jsvp != null) 184 jsvp.doRepaint(true); 185 return true; 186 } 187 188 /** 189 * @param dialogHelper 190 */ addUniqueControls(DialogManager dialogHelper)191 protected void addUniqueControls(DialogManager dialogHelper) { 192 // int and peak only 193 } 194 195 // /////// general interface to the outside world //////// 196 197 @Override getAType()198 public AType getAType() { 199 return type; 200 } 201 202 @Override getGraphSetKey()203 public String getGraphSetKey() { 204 return graphSetKey; 205 } 206 207 @Override setGraphSetKey(String key)208 public void setGraphSetKey(String key) { 209 this.graphSetKey = key; 210 } 211 212 @Override getSpectrum()213 public Spectrum getSpectrum() { 214 return spec; 215 } 216 217 @Override getState()218 public boolean getState() { 219 return isON; 220 } 221 222 @Override setState(boolean b)223 public void setState(boolean b) { 224 isON = b; 225 } 226 227 // ////// interface to DialogParams//////// 228 checkEnables()229 public void checkEnables() { 230 boolean isShow = checkVisible(); 231 dialog.setText(showHideButton, isShow ? "Hide" : "Show"); 232 } 233 createTable(Object[][] data, String[] header, int[] widths)234 public void createTable(Object[][] data, String[] header, int[] widths) { 235 tableData = data; 236 dialog.createTable(data, header, widths); 237 } 238 setTableSelectionEnabled(boolean enabled)239 public void setTableSelectionEnabled(boolean enabled) { 240 dialog.setCellSelectionEnabled(enabled); 241 } 242 243 @Override getParameters()244 public Parameters getParameters() { 245 return myParams; 246 } 247 showMessage(String msg, String title, int msgType)248 public void showMessage(String msg, String title, int msgType) { 249 manager.showMessageDialog(dialog, msg, title, msgType); 250 } 251 setThreshold(double y)252 protected void setThreshold(double y) { 253 dialog.setText(txt1, getThreasholdText(y)); 254 } 255 setComboSelected(int i)256 public void setComboSelected(int i) { 257 dialog.setSelectedIndex(combo1, i); 258 } 259 applyFromFields()260 public void applyFromFields() { 261 apply(null); 262 } 263 reEnable()264 public JSVDialog reEnable() { 265 paramsReEnable(); 266 return this; 267 } 268 dispose()269 public void dispose() { 270 dialog.dispose(); 271 } 272 setVisible(boolean visible)273 public void setVisible(boolean visible) { 274 dialog.setVisible(visible); 275 } 276 277 @Override isVisible()278 public boolean isVisible() { 279 return dialog.isVisible(); 280 } 281 selectTableRow(int i)282 public void selectTableRow(int i) { 283 dialog.selectTableRow(i); 284 } 285 repaint()286 public void repaint() { 287 dialog.repaint(); 288 } 289 setFields()290 public void setFields() { 291 switch (type) { 292 case Integration: 293 break; 294 case Measurements: 295 break; 296 case NONE: 297 break; 298 case PeakList: 299 myParams = xyData.getParameters(); 300 setThreshold(myParams.peakListThreshold); 301 setComboSelected(myParams.peakListInterpolation.equals("none") ? 1 302 : 0); 303 createData(); 304 break; 305 case OverlayLegend: 306 break; 307 case Views: 308 break; 309 } 310 } 311 setFocus(boolean tf)312 public void setFocus(boolean tf) { 313 dialog.setFocus(tf); 314 } 315 update(Coordinate clicked, double xRange, int yOffset)316 public void update(Coordinate clicked, double xRange, int yOffset) { 317 selectTableRow(-1); 318 switch (type) { 319 case Integration: 320 loadData(); 321 checkEnables(); 322 break; 323 case Measurements: 324 loadData(); 325 checkEnables(); 326 break; 327 case NONE: 328 break; 329 case PeakList: 330 if (yOffset > 20) 331 applyFromFields(); 332 if (xyData == null || clicked == null || yOffset > 20) 333 return; 334 int ipt = 0; 335 double dx0 = 1e100; 336 double xval = clicked.getXVal(); 337 PeakData md = (PeakData) xyData; 338 double min = Math.abs(xRange / 20); 339 for (int i = md.size(); --i >= 0;) { 340 double dx = Math.abs(xval - md.get(i).getXVal()); 341 if (dx < dx0) { 342 dx0 = dx; 343 ipt = i; 344 } 345 } 346 if (dx0 < min) { 347 selectTableRow(md.size() - 2 - ipt); 348 repaint(); 349 } 350 break; 351 case OverlayLegend: 352 break; 353 case Views: 354 break; 355 } 356 } 357 358 protected double lastNorm = 1; 359 getPeakData()360 public MeasurementData getPeakData() { 361 // could be called by outside, but isn't. 362 PeakData md = new PeakData(AType.PeakList, spec); 363 md.setPeakList(myParams, precision, jsvp.getPanelData().getView()); 364 xyData = md; 365 return null; 366 } 367 368 @Override getData()369 public MeasurementData getData() { 370 if (xyData == null) 371 createData(); 372 return xyData; 373 } 374 setData(AnnotationData data)375 public void setData(AnnotationData data) { 376 myParams = data.getParameters(); 377 xyData = (MeasurementData) data; 378 } 379 380 @Override setSpecShift(double dx)381 public void setSpecShift(double dx) { 382 if (xyData != null) 383 xyData.setSpecShift(dx); 384 } 385 setType(AType type)386 public void setType(AType type) { 387 this.type = type; 388 switch (type) { 389 case Measurements: 390 addUnits = true; 391 break; 392 case Integration: 393 break; 394 case PeakList: 395 break; 396 case OverlayLegend: 397 break; 398 case Views: 399 break; 400 case NONE: 401 break; 402 403 } 404 } 405 406 ////////////// protected methods 407 408 protected int iRowColSelected = -1; 409 protected int iSelected = -1; 410 apply(Object[] objects)411 protected void apply(Object[] objects) { 412 try { 413 switch (type) { 414 case Integration: 415 double offset = Double.parseDouble((String) objects[0]); 416 double scale = Double.parseDouble((String) objects[1]); 417 //double minval = Double.parseDouble((String) objects[2]); 418 myParams.integralOffset = offset; 419 myParams.integralRange = scale; 420 //myParams.integralMinY = minval; 421 myParams.integralDrawAll = false; 422 ((IntegralData) getData()).update(myParams); 423 break; 424 case Measurements: 425 // n/a 426 break; 427 case NONE: 428 return; 429 case PeakList: 430 if (!skipCreate) { 431 setThreshold(Double.NaN); 432 createData(); 433 } 434 skipCreate = false; 435 break; 436 case OverlayLegend: 437 break; 438 case Views: 439 vwr.parameters.viewOffset = Double.parseDouble((String) objects[0]); 440 break; 441 } 442 loadData(); 443 checkEnables(); 444 jsvp.doRepaint(true); 445 } catch (Exception e) { 446 // ignore 447 } 448 } 449 done()450 protected void done() { 451 if (jsvp != null && spec != null) 452 jsvp.getPanelData().removeDialog(this); 453 // setState(false); 454 if (xyData != null) 455 xyData.setState(isON); 456 saveDialogPosition(getPosXY()); 457 dispose(); 458 jsvp.doRepaint(true); 459 } 460 461 462 // /////////// private methods 463 464 /** 465 * 466 * @param panel 467 * a PPanel (Applet) or a JScrollPane (MainFrame) 468 * 469 * @param posXY 470 * static for a given dialog 471 */ restoreDialogPosition(JSVPanel panel, int[] posXY)472 private void restoreDialogPosition(JSVPanel panel, int[] posXY) { 473 if (panel != null) { 474 if (posXY[0] == Integer.MIN_VALUE) { 475 posXY[0] = 0; 476 posXY[1] = -20; 477 } 478 int[] pt = manager.getLocationOnScreen(panel); 479 int height = panel.getHeight(); 480 loc = new int[] { Math.max(0, pt[0] + posXY[0]), 481 Math.max(0, pt[1] + height + posXY[1]) }; 482 dialog.setIntLocation(loc); 483 } 484 } 485 saveDialogPosition(int[] posXY)486 private void saveDialogPosition(int[] posXY) { 487 try { 488 int[] pt = manager.getLocationOnScreen(dialog); 489 posXY[0] += pt[0] - loc[0]; 490 posXY[1] += pt[1] - loc[1]; 491 } catch (Exception e) { 492 // ignore 493 } 494 } 495 getThreasholdText(double y)496 private String getThreasholdText(double y) { 497 if (Double.isNaN(y)) { 498 PanelData pd = jsvp.getPanelData(); 499 double f = (pd.getSpectrum().isInverted() ? 0.1 : 0.9); 500 Coordinate c = pd.getClickedCoordinate(); 501 y = (c == null ? (pd.getView().minYOnScale * f + pd.getView().maxYOnScale) 502 * (1 - f) 503 : c.getYVal()); 504 } 505 String sy = DF.formatDecimalDbl(y, y < 1000 ? 2 : -2); // "#0.00" : 506 // "0.00E0" 507 return " " + sy; 508 } 509 checkVisible()510 private boolean checkVisible() { 511 return vwr.pd().getShowAnnotation(type); 512 } 513 getUnitOptions()514 private void getUnitOptions() { 515 String key = optionKey + "_format"; 516 Integer format = (Integer) options.get(key); 517 if (format == null) 518 options.put(key, format = Integer 519 .valueOf(formatOptions[unitPtr == null ? 0 : unitPtr.intValue()])); 520 // txtFormat = dialogHelper.addInputOption("numberFormat", "Number Format", 521 // format, null, null, false); 522 } 523 524 private boolean skipCreate; 525 eventFocus()526 protected void eventFocus() { 527 if (spec != null) 528 jsvp.getPanelData().jumpToSpectrum(spec); 529 switch (type) { 530 case Integration: 531 if (iRowSelected >= 0) { 532 iRowSelected++; 533 tableCellSelect(-1, -1); 534 } 535 break; 536 case Measurements: 537 break; 538 case NONE: 539 break; 540 case PeakList: 541 createData(); 542 skipCreate = true; 543 break; 544 case OverlayLegend: 545 break; 546 case Views: 547 break; 548 } 549 } 550 eventApply()551 protected void eventApply() { 552 switch (type) { 553 case Integration: 554 break; 555 case Measurements: 556 break; 557 case NONE: 558 break; 559 case PeakList: 560 createData(); 561 skipCreate = true; 562 break; 563 case OverlayLegend: 564 break; 565 case Views: 566 break; 567 } 568 applyFromFields(); 569 } 570 eventShowHide(boolean isShow)571 private void eventShowHide(boolean isShow) { 572 isON = isShow; 573 if (isShow) 574 eventApply(); 575 jsvp.doRepaint(true); 576 checkEnables(); 577 } 578 clear()579 private void clear() { 580 setState(true); 581 if (xyData != null) { 582 xyData.clear(); 583 applyFromFields(); 584 } 585 } 586 paramsReEnable()587 private void paramsReEnable() { 588 switch (type) { 589 case Integration: 590 break; 591 case Measurements: 592 break; 593 case NONE: 594 break; 595 case PeakList: 596 skipCreate = true; 597 break; 598 case OverlayLegend: 599 break; 600 case Views: 601 break; 602 } 603 setVisible(true); 604 isON = true; 605 applyFromFields(); 606 } 607 608 private int iRowSelected = -1; 609 private int iColSelected = -1; 610 tableCellSelect(int iRow, int iCol)611 private void tableCellSelect(int iRow, int iCol) { 612 System.out.println(iRow + " jSVDial " + iCol); 613 if (iRow < 0) { 614 iRow = iRowColSelected / 1000; 615 iCol = iRowColSelected % 1000; 616 iRowColSelected = -1; 617 } 618 Object value = tableData[iRow][1]; 619 int icolrow = iRow * 1000 + iCol; 620 if (icolrow == iRowColSelected) 621 return; 622 iRowColSelected = icolrow; 623 System.out.println("Setting rc = " + iRowColSelected + " " + spec); 624 selectTableRow(iRowSelected); 625 try { 626 switch (type) { 627 case Integration: 628 callback("SHOWSELECTION", value.toString()); 629 checkEnables(); 630 break; 631 case Measurements: 632 break; 633 case NONE: 634 break; 635 case PeakList: 636 try { 637 switch (iCol) { 638 case 6: 639 case 5: 640 case 4: 641 double x1 = Double.parseDouble((String) value); 642 double x2 = Double 643 .parseDouble((String) tableData[iRow + 3 - iCol][1]); 644 jsvp.getPanelData().setXPointers(spec, x1, spec, x2); 645 break; 646 default: 647 jsvp.getPanelData().findX(spec, Double.parseDouble((String) value)); 648 } 649 } catch (Exception e) { 650 jsvp.getPanelData().findX(spec, 1E100); 651 } 652 jsvp.doRepaint(false); 653 break; 654 case OverlayLegend: 655 jsvp.getPanelData().setSpectrum(iRow, false); 656 break; 657 case Views: 658 break; 659 } 660 } catch (Exception e) { 661 // for parseDouble 662 } 663 } 664 loadData()665 protected void loadData() { 666 Object[][] data; 667 String[] header; 668 int[] widths; 669 switch (type) { 670 case Integration: 671 if (xyData == null) 672 createData(); 673 iSelected = -1; 674 data = ((IntegralData) xyData).getMeasurementListArray(null); 675 header = xyData.getDataHeader(); 676 widths = new int[] { 40, 65, 65, 50 }; 677 createTable(data, header, widths); 678 break; 679 case Measurements: 680 if (xyData == null) 681 return; 682 data = xyData.getMeasurementListArray(dialog.getSelectedItem(combo1).toString()); 683 header = xyData.getDataHeader(); 684 widths = new int[] { 40, 65, 65, 50 }; 685 createTable(data, header, widths); 686 break; 687 case NONE: 688 break; 689 case PeakList: 690 if (xyData == null) 691 createData(); 692 data = ((PeakData) xyData).getMeasurementListArray(null); 693 header = ((PeakData) xyData).getDataHeader(); 694 widths = new int[] { 40, 65, 50, 50, 50, 50, 50 }; 695 createTable(data, header, widths); 696 setTableSelectionEnabled(true); 697 break; 698 case OverlayLegend: 699 header = new String[] { "No.", "Plot Color", "Title" }; 700 data = vwr.selectedPanel.getPanelData().getOverlayLegendData(); 701 widths = new int[] { 30, 60, 250 }; 702 createTable(data, header, widths); 703 setTableSelectionEnabled(true); 704 break; 705 case Views: 706 break; 707 } 708 } 709 createData()710 private void createData() { 711 switch (type) { 712 case Integration: 713 xyData = new IntegralData(spec, myParams); 714 iSelected = -1; 715 break; 716 case Measurements: 717 // n/a 718 break; 719 case NONE: 720 break; 721 case PeakList: 722 try { 723 double thresh = Double.parseDouble(dialog.getText(txt1)); 724 myParams.peakListThreshold = thresh; 725 myParams.peakListInterpolation = dialog.getSelectedItem(combo1) 726 .toString(); 727 myParams.precision = precision; 728 PeakData md = new PeakData(AType.PeakList, spec); 729 md.setPeakList(myParams, precision, jsvp.getPanelData().getView()); 730 xyData = md; 731 loadData(); 732 } catch (Exception e) { 733 // for parseDouble 734 } 735 break; 736 case OverlayLegend: 737 break; 738 case Views: 739 break; 740 } 741 } 742 setPrecision(int i)743 private void setPrecision(int i) { 744 precision = formatOptions[i]; 745 } 746 tableSelect(String url)747 private void tableSelect(String url) { 748 boolean isAdjusting = "true".equals(getField(url, "adjusting")); 749 if (isAdjusting) { 750 iColSelected = iRowSelected = -1; 751 System.out.println("adjusting" + url); 752 return; 753 } 754 int index = PT.parseInt(getField(url, "index")); 755 switch ("ROW COL ROWCOL".indexOf(getField(url, "selector"))) { 756 case 8: 757 iColSelected = PT.parseInt(getField(url, "index2")); 758 //$FALL-THROUGH$ 759 case 0: 760 iRowSelected = index; 761 System.out.println("r set to " + index); 762 break; 763 case 4: 764 iColSelected = index; 765 System.out.println("c set to " + index); 766 break; 767 } 768 if (iColSelected >= 0 && iRowSelected >= 0) { 769 tableCellSelect(iRowSelected, iColSelected); 770 } 771 } 772 getField(String url, String name)773 private String getField(String url, String name) { 774 url += "&"; 775 String key = "&" + name + "="; 776 int pt = url.indexOf(key); 777 return (pt < 0 ? null : url.substring(pt + key.length(), url.indexOf("&", 778 pt + 1))); 779 } 780 781 782 } 783