Changeset 2508


Ignore:
Timestamp:
03/23/07 11:32:23 (13 years ago)
Author:
curtis
Message:

Add LUT buttons for color widget, add color range override, fix color bugs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/apps/slim/SlimPlotter.java

    r2502 r2508  
    2323import javax.swing.border.TitledBorder; 
    2424import javax.swing.event.*; 
     25import javax.swing.text.Document; 
    2526import loci.formats.in.SDTInfo; 
    2627import loci.formats.in.SDTReader; 
     
    2829import loci.formats.ExtensionFileFilter; 
    2930import loci.visbio.util.BreakawayPanel; 
     31import loci.visbio.util.ColorUtil; 
    3032import loci.visbio.util.OutputConsole; 
    3133import visad.*; 
     
    3335import visad.java3d.*; 
    3436import visad.util.ColorMapWidget; 
     37import visad.util.Util; 
    3538 
    3639/** A tool for visualization of spectral lifetime data. */ 
     
    4043 
    4144  // -- Constants -- 
     45 
     46  /** Names for preset color look-up table. */ 
     47  public static final String[] LUT_NAMES = { 
     48    "Grayscale", "HSV", "RGB", null, 
     49    "Red", "Green", "Blue", null, 
     50    "Cyan", "Magenta", "Yellow", null, 
     51    "Fire", "Ice" 
     52  }; 
     53 
     54  /** Preset color look-up tables. */ 
     55  public static final float[][][] LUTS = { 
     56    ColorUtil.LUT_GRAY, ColorUtil.LUT_HSV, ColorUtil.LUT_RGB, null, 
     57    ColorUtil.LUT_RED, ColorUtil.LUT_GREEN, ColorUtil.LUT_BLUE, null, 
     58    ColorUtil.LUT_CYAN, ColorUtil.LUT_MAGENTA, ColorUtil.LUT_YELLOW, null, 
     59    ColorUtil.LUT_FIRE, ColorUtil.LUT_ICE 
     60  }; 
    4261 
    4362  /** Default orientation for 3D decay curves display. */ 
     
    91110  private double roiPercent; 
    92111  private float maxVal; 
     112  private float tauMin, tauMax; 
    93113 
    94114  // fit parameters 
     
    108128  // GUI components for decay pane 
    109129  private JLabel decayLabel; 
     130  private ColorMapWidget colorWidget; 
     131  private JCheckBox cOverride; 
     132  private JTextField cMinValue, cMaxValue; 
     133  private JButton lutLoad, lutSave, lutPresets; 
     134  private JPopupMenu lutsMenu; 
     135  private JFileChooser lutBox; 
    110136  private JRadioButton linear, log; 
    111137  private JRadioButton perspective, parallel; 
     
    123149 
    124150  // other GUI components 
     151  private JFrame masterWindow; 
    125152  private OutputConsole console; 
    126153 
     
    321348        minWave, maxWave, channels, null, new Unit[] {nm}, null); 
    322349      bc = new RealTupleType(bType, cType); 
    323       RealType vType2 = RealType.getRealType("tau"); 
     350      RealType vType2 = RealType.getRealType("value"); 
    324351      RealTupleType vv = new RealTupleType(vType, vType2); 
    325352      bcvFunc = new FunctionType(bc, vv); 
     
    574601      // construct 2D pane 
    575602      progress.setNote("Creating plots"); 
    576       JFrame masterWindow = new JFrame("Slim Plotter - " + file.getName()); 
     603      masterWindow = new JFrame("Slim Plotter - " + file.getName()); 
    577604      masterWindow.addWindowListener(this); 
    578605      JPanel masterPane = new JPanel(); 
     
    681708      decayPane.add(decayLabel, BorderLayout.NORTH); 
    682709 
    683       ColorMapWidget colorWidget = new ColorMapWidget(vMap); 
     710      colorWidget = new ColorMapWidget(vMap); 
    684711      Dimension prefSize = colorWidget.getPreferredSize(); 
    685712      colorWidget.setPreferredSize(new Dimension(prefSize.width, 0)); 
     713 
     714      cOverride = new JCheckBox("", false); 
     715      cOverride.setToolTipText( 
     716        "Toggles manual override of color range"); 
     717      cOverride.addActionListener(this); 
     718      cMinValue = new JTextField(); 
     719      Util.adjustTextField(cMinValue); 
     720      cMinValue.setToolTipText("Overridden color minimum"); 
     721      cMinValue.setEnabled(false); 
     722      cMinValue.getDocument().addDocumentListener(this); 
     723      cMaxValue = new JTextField(); 
     724      Util.adjustTextField(cMaxValue); 
     725      cMaxValue.setToolTipText("Overridden color maximum"); 
     726      cMaxValue.setEnabled(false); 
     727      cMaxValue.getDocument().addDocumentListener(this); 
     728 
     729      lutLoad = new JButton("Load LUT..."); 
     730      lutLoad.setToolTipText("Loads a color table from disk"); 
     731      lutLoad.addActionListener(this); 
     732 
     733      lutSave = new JButton("Save LUT..."); 
     734      lutSave.setToolTipText("Saves this color table to disk"); 
     735      lutSave.addActionListener(this); 
     736 
     737      lutsMenu = new JPopupMenu(); 
     738      for (int i=0; i<LUT_NAMES.length; i++) { 
     739        if (LUT_NAMES[i] == null) lutsMenu.addSeparator(); 
     740        else { 
     741          JMenuItem item = new JMenuItem(LUT_NAMES[i]); 
     742          item.setActionCommand("lut" + i); 
     743          item.addActionListener(this); 
     744          lutsMenu.add(item); 
     745        } 
     746      } 
     747 
     748      lutPresets = new JButton("LUTs >"); 
     749      lutPresets.setToolTipText("Selects a LUT from the list of presets"); 
     750      lutPresets.addActionListener(this); 
     751 
     752      lutBox = new JFileChooser(System.getProperty("user.dir")); 
     753      lutBox.addChoosableFileFilter( 
     754        new ExtensionFileFilter("lut", "Binary color table files")); 
    686755 
    687756      showData = new JCheckBox("Data", true); 
     
    772841      if (progress.isCanceled()) System.exit(0); 
    773842 
     843      JPanel colorPanel = new JPanel(); 
     844      colorPanel.setBorder(new TitledBorder("Color Mapping")); 
     845      colorPanel.setLayout(new BoxLayout(colorPanel, BoxLayout.Y_AXIS)); 
     846      colorPanel.add(colorWidget); 
     847 
     848      JPanel colorRange = new JPanel(); 
     849      colorRange.setLayout(new BoxLayout(colorRange, BoxLayout.X_AXIS)); 
     850      colorRange.add(cOverride); 
     851      colorRange.add(cMinValue); 
     852      colorRange.add(cMaxValue); 
     853      colorPanel.add(colorRange); 
     854 
     855      JPanel colorButtons = new JPanel(); 
     856      colorButtons.setLayout(new BoxLayout(colorButtons, BoxLayout.X_AXIS)); 
     857      colorButtons.add(lutLoad); 
     858      colorButtons.add(lutSave); 
     859      colorButtons.add(lutPresets); 
     860      colorPanel.add(colorButtons); 
     861 
    774862      JPanel showPanel = new JPanel(); 
    775863      showPanel.setBorder(new TitledBorder("Show")); 
     
    787875      scalePanel.add(zOverride); 
    788876      scalePanel.add(zScaleValue); 
    789  
    790       JPanel colorPanel = new JPanel(); 
    791       colorPanel.setBorder(new TitledBorder("Color Mapping")); 
    792       colorPanel.setLayout(new BorderLayout()); 
    793       colorPanel.add(colorWidget); 
    794877 
    795878      JPanel miscRow1 = new JPanel(); 
     
    9211004  } 
    9221005 
     1006  /** Sets the currently selected range component's color widget table. */ 
     1007  public void setWidgetTable(float[][] table) { 
     1008//    float[][] oldTable = colorWidget.getTableView(); 
     1009//    float[] alpha = oldTable.length > 3 ? oldTable[3] : null; 
     1010//    table = ColorUtil.adjustColorTable(table, alpha, true); 
     1011    colorWidget.setTableView(table); 
     1012  } 
     1013 
    9231014  /** Logs the given output to the appropriate location. */ 
    9241015  public void log(String msg) { 
     
    9391030      cVisible[c] = !cVisible[c]; 
    9401031      plotData(true, true, false); 
     1032    } 
     1033    else if (src == cOverride) { 
     1034      boolean manual = cOverride.isSelected(); 
     1035      cMinValue.setEnabled(manual); 
     1036      cMaxValue.setEnabled(manual); 
     1037      updateColorScale(); 
     1038    } 
     1039    else if (src == lutLoad) { 
     1040      // ask user to specify the file 
     1041      int returnVal = lutBox.showOpenDialog(masterWindow); 
     1042      if (returnVal != JFileChooser.APPROVE_OPTION) return; 
     1043      File file = lutBox.getSelectedFile(); 
     1044 
     1045      float[][] table = ColorUtil.loadColorTable(file); 
     1046      if (table == null) { 
     1047        JOptionPane.showMessageDialog(masterWindow, "Error reading LUT file.", 
     1048          "Cannot load color table", JOptionPane.ERROR_MESSAGE); 
     1049      } 
     1050      else setWidgetTable(table); 
     1051    } 
     1052    else if (src == lutSave) { 
     1053      // ask user to specify the file 
     1054      int returnVal = lutBox.showSaveDialog(masterWindow); 
     1055      if (returnVal != JFileChooser.APPROVE_OPTION) return; 
     1056      File file = lutBox.getSelectedFile(); 
     1057      String s = file.getAbsolutePath(); 
     1058      if (!s.toLowerCase().endsWith(".lut")) file = new File(s + ".lut"); 
     1059 
     1060      boolean success = 
     1061        ColorUtil.saveColorTable(colorWidget.getTableView(), file); 
     1062      if (!success) { 
     1063        JOptionPane.showMessageDialog(masterWindow, "Error writing LUT file.", 
     1064          "Cannot save color table", JOptionPane.ERROR_MESSAGE); 
     1065      } 
     1066    } 
     1067    else if (src == lutPresets) { 
     1068      lutsMenu.show(lutPresets, lutPresets.getWidth(), 0); 
    9411069    } 
    9421070    else if (src == linear || src == log) plotData(true, true, true); 
     
    10161144      } 
    10171145    } 
    1018     else { // OK button 
    1019       width = parse(wField.getText(), width); 
    1020       height = parse(hField.getText(), height); 
    1021       timeBins = parse(tField.getText(), timeBins); 
    1022       channels = parse(cField.getText(), channels); 
    1023       timeRange = parse(trField.getText(), timeRange); 
    1024       minWave = parse(wlField.getText(), minWave); 
    1025       waveStep = parse(sField.getText(), waveStep); 
    1026       adjustPeaks = peaksBox.isSelected(); 
    1027       cutEnd = cutBox.isSelected(); 
    1028       cVisible = new boolean[channels]; 
    1029       Arrays.fill(cVisible, true); 
    1030       paramDialog.setVisible(false); 
     1146    else { 
     1147      String cmd = e.getActionCommand(); 
     1148      if (cmd != null && cmd.startsWith("lut")) { 
     1149        // apply the chosen LUT preset 
     1150        setWidgetTable(LUTS[Integer.parseInt(cmd.substring(3))]); 
     1151      } 
     1152      else { // OK button 
     1153        width = parse(wField.getText(), width); 
     1154        height = parse(hField.getText(), height); 
     1155        timeBins = parse(tField.getText(), timeBins); 
     1156        channels = parse(cField.getText(), channels); 
     1157        timeRange = parse(trField.getText(), timeRange); 
     1158        minWave = parse(wlField.getText(), minWave); 
     1159        waveStep = parse(sField.getText(), waveStep); 
     1160        adjustPeaks = peaksBox.isSelected(); 
     1161        cutEnd = cutBox.isSelected(); 
     1162        cVisible = new boolean[channels]; 
     1163        Arrays.fill(cVisible, true); 
     1164        paramDialog.setVisible(false); 
     1165      } 
    10311166    } 
    10321167  } 
     
    11321267  // -- DocumentListener methods -- 
    11331268 
    1134   public void changedUpdate(DocumentEvent e) { updateZAxis(); } 
    1135   public void insertUpdate(DocumentEvent e) { updateZAxis(); } 
    1136   public void removeUpdate(DocumentEvent e) { updateZAxis(); } 
     1269  public void changedUpdate(DocumentEvent e) { documentUpdate(e); } 
     1270  public void insertUpdate(DocumentEvent e) { documentUpdate(e); } 
     1271  public void removeUpdate(DocumentEvent e) { documentUpdate(e); } 
    11371272 
    11381273  // -- Runnable methods -- 
     
    12831418      } 
    12841419 
    1285       float tauMin = Float.NaN, tauMax = Float.NaN; 
     1420      tauMin = tauMax = Float.NaN; 
    12861421      if (tau != null) { 
    12871422        tauMin = tauMax = tau[0][0]; 
     
    14261561        zScale.createStandardLabels(maxVal, 0, 0, maxVal); 
    14271562      } 
     1563 
     1564      updateColorScale(); 
    14281565    } 
    14291566 
     
    14401577        zScaleValue.getDocument().addDocumentListener(this); 
    14411578      } 
     1579      float minZ = 0; 
    14421580      float maxZ = d == d ? d : maxVal; 
    14431581      if (doLog) maxZ = linearToLog(maxZ); 
    14441582      if (maxZ != maxZ || maxZ == 0) maxZ = 1; 
    14451583      try { 
    1446         zMap.setRange(0, maxZ); 
    1447         zMapFit.setRange(0, maxZ); 
    1448         zMapRes.setRange(0, maxZ); 
    1449         //vMap.setRange(0, max); 
    1450         //vMapFit.setRange(0, max); 
    1451         //vMapRes.setRange(0, max); 
     1584        zMap.setRange(minZ, maxZ); 
     1585        zMapFit.setRange(minZ, maxZ); 
     1586        zMapRes.setRange(minZ, maxZ); 
    14521587        decayPlot.reAutoScale(); 
    14531588      } 
     
    14821617  /** Converts linear value to logarithm value. */ 
    14831618  private float linearToLog(float v) { 
    1484     return (float) v >= 1 ? (float) Math.log(v) / BASE_LOG : Float.NaN; 
     1619    return (float) v >= 1 ? (float) Math.log(v) / BASE_LOG : 0; 
    14851620  } 
    14861621 
     
    15331668  } 
    15341669 
     1670  private void documentUpdate(DocumentEvent e) { 
     1671    Document doc = e.getDocument(); 
     1672    if (doc == zScaleValue.getDocument()) updateZAxis(); 
     1673    else updateColorScale(); // cMinValue or cMaxValue 
     1674  } 
     1675 
    15351676  private void updateZAxis() { 
    15361677    float f = Float.NaN; 
     
    15381679    catch (NumberFormatException exc) { } 
    15391680    if (f == f) plotData(false, true, false); 
     1681  } 
     1682 
     1683  private void updateColorScale() { 
     1684    boolean manual = cOverride.isSelected(); 
     1685    float min = Float.NaN, max = Float.NaN; 
     1686    if (manual) { 
     1687      try { min = Float.parseFloat(cMinValue.getText()); } 
     1688      catch (NumberFormatException exc) { } 
     1689      try { max = Float.parseFloat(cMaxValue.getText()); } 
     1690      catch (NumberFormatException exc) { } 
     1691    } 
     1692    else { 
     1693      if (colorHeight.isSelected()) { 
     1694        min = 0; 
     1695        max = maxVal; 
     1696      } 
     1697      else { // colorTau.isSelected() 
     1698        min = tauMin; 
     1699        max = tauMax; 
     1700      } 
     1701      cMinValue.getDocument().removeDocumentListener(this); 
     1702      cMinValue.setText("" + min); 
     1703      cMinValue.getDocument().addDocumentListener(this); 
     1704      cMaxValue.getDocument().removeDocumentListener(this); 
     1705      cMaxValue.setText("" + max); 
     1706      cMaxValue.getDocument().addDocumentListener(this); 
     1707    } 
     1708    if (min == min && max == max && min < max) { 
     1709      try { vMap.setRange(min, max); } 
     1710      catch (VisADException exc) { exc.printStackTrace(); } 
     1711      catch (RemoteException exc) { exc.printStackTrace(); } 
     1712    } 
    15401713  } 
    15411714 
Note: See TracChangeset for help on using the changeset viewer.