Changeset 2428


Ignore:
Timestamp:
03/13/07 16:19:52 (13 years ago)
Author:
sorber
Message:

Basic export overlays to .xls format.

Location:
trunk/loci/visbio/overlays
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/overlays/OverlayIO.java

    r2372 r2428  
    3333import loci.visbio.VisBio; 
    3434import loci.visbio.util.*; 
     35import org.apache.poi.hssf.usermodel.*; 
     36import org.apache.poi.hssf.util.Region; 
    3537 
    3638/** Utility methods for saving and loading overlays to and from disk. */ 
     
    172174              loadedNodedObjects.elementAt(numNodedObjectsRestored++); 
    173175            float[][] temp = new float[2][numNodes]; 
    174             for (int i=0; i<2; i++) System.arraycopy(nodes[i], 0, temp[i], 0, numNodes); 
     176            for (int i=0; i<2; i++) System.arraycopy(nodes[i], 0, temp[i], 0, 
     177                numNodes); 
    175178            ono.setNodes(temp); 
    176179            nodes = new float[2][50]; 
     
    188191          int tok = 0; 
    189192 
    190           if (count != lengths.length + 10) { // 10 == number of non-dim. fields in the overlay description 
    191             String s = "line in data table has an insufficient number of fields (" + count + " instead of " 
    192               + (lengths.length + 10) + ")"; 
     193          if (count != lengths.length + 10) {  
     194            // 10 == number of non-dim. fields in the overlay description 
     195            String s = "line in data table has an insufficient number of " + 
     196              "fields (" + count + " instead of " + (lengths.length + 10) + ")"; 
    193197            displayErrorMsg(owner, lineNum, s); 
    194198            return null; 
     
    218222 
    219223          if (pos == null) { 
    220             displayErrorMsg(owner, lineNum, "line has an invalid dimensional position"); 
     224            displayErrorMsg(owner, lineNum,  
     225                "line has an invalid dimensional position"); 
    221226            return null; 
    222227          } 
     
    239244 
    240245          catch (NumberFormatException exc) { 
    241             displayErrorMsg(owner, lineNum, "line has invalid coordinate values"); 
     246            displayErrorMsg(owner, lineNum,  
     247                "line has invalid coordinate values"); 
    242248            return null; 
    243249          } 
     
    273279          //System.out.println("]"); // TEMP 
    274280          //System.out.println("r = " + r); // TEMP 
    275           // this error should never fire--will be caught above ("is coordinate w/in range?") 
     281          // this error should never fire--will be caught above ("is coordinate 
     282          // w/in range?") 
    276283          /* 
    277284          if (r < 0 || r >= loadedOverlays.length) { 
    278             displayErrorMsg(owner, lineNum, "could not reconstruct overlay: invalid dimensional position"); 
     285            displayErrorMsg(owner, lineNum, "could not reconstruct overlay: 
     286            invalid dimensional position"); 
    279287            return null; 
    280288          } 
     
    308316          } 
    309317          catch (NumberFormatException exc) { 
    310             // this error message won't fire: covered by regular expressions in getEventAndState 
     318            // this error message won't fire: covered by regular expressions in 
     319            // getEventAndState 
    311320            displayErrorMsg(owner, lineNum, "error parsing node coordinates"); 
    312321            return null; 
     
    334343    else if (loadedNodedObjects.size() > 0) { 
    335344      if (numNodedObjectsRestored + 1 < loadedNodedObjects.size()) { 
    336         displayErrorMsg(owner, lineNum, "missing node lists for one or more Freeforms"); 
     345        displayErrorMsg(owner, lineNum,  
     346            "missing node lists for one or more Freeforms"); 
    337347        return null; 
    338348      }  
     
    342352          loadedNodedObjects.elementAt(numNodedObjectsRestored++); 
    343353        float[][] temp = new float[2][numNodes]; 
    344         for (int i=0; i<2; i++) System.arraycopy(nodes[i], 0, temp[i], 0, numNodes); 
     354        for (int i=0; i<2; i++) System.arraycopy(nodes[i], 0, temp[i], 0, 
     355            numNodes); 
    345356        ono.setNodes(temp); 
    346357      } 
     
    420431      else if (ono instanceof OverlayPolyline) k = ++polylineCount; 
    421432 
    422       out.println("# " + ono + " " + k + " (" + xx1 + "," + yy1 + ")(" + xx2 + "," + yy2 + ")"); 
     433      out.println("# " + ono + " " + k + " (" + xx1 + "," + yy1 + ")(" + xx2 + 
     434          "," + yy2 + ")"); 
    423435 
    424436      out.println("X\tY"); 
     
    429441      } 
    430442    } 
     443  } 
     444 
     445  /** Saves overlays to a .xls workbook */ 
     446  public static HSSFWorkbook exportOverlays (OverlayTransform overlay) { 
     447    String[] dims = overlay.getDimTypes(); 
     448    int[] lengths = overlay.getLengths(); 
     449    Vector[] overlays = overlay.overlays; 
     450    Vector savedNodedObjects = new Vector(); 
     451 
     452    // initialize worksheet 
     453    HSSFWorkbook wb = new HSSFWorkbook(); 
     454    HSSFSheet s = wb.createSheet(); 
     455    HSSFRow r = null; 
     456    HSSFCell c = null; 
     457 
     458    // create cell styles  
     459    HSSFCellStyle text = wb.createCellStyle(); 
     460    text.setDataFormat(HSSFDataFormat.getBuiltinFormat("text"));  
     461 
     462    HSSFCellStyle integer = wb.createCellStyle(); 
     463    integer.setDataFormat((short) 1); 
     464 
     465    HSSFCellStyle flt = wb.createCellStyle(); 
     466    flt.setDataFormat((short) 0); // "general" format 
     467     
     468    HSSFCellStyle hex = wb.createCellStyle(); 
     469    hex.setDataFormat((short) 0); // "general" format 
     470 
     471    // write file header 
     472    int rownum = 0; 
     473 
     474    String header = "# " + VisBio.TITLE + " " + VisBio.VERSION + 
     475      " overlay file written " + new Date(); 
     476 
     477    // try to estimate number of cells to merge 
     478    // short width = s.getDefaultColumnWidth(); 
     479    // int numChars = header.length(); 
     480    // short numColsToMerge = (short) Math.ceil((float) numChars/(float) 
     481    // (width)); 
     482     
     483    short numColsToMerge = 12; // number of columns in overlay table header 
     484 
     485    Region mergedCells = new Region (0, (short) 0, 0, numColsToMerge); 
     486    s.addMergedRegion(mergedCells); 
     487 
     488    r = s.createRow(rownum); 
     489    c = r.createCell((short) 0); 
     490 
     491    c.setCellStyle(text); 
     492    c.setCellValue(header); 
     493 
     494    // write table header 
     495   
     496    short cellnum = 0; 
     497    r = s.createRow(++rownum); 
     498    c = r.createCell(cellnum); 
     499 
     500    c.setCellStyle(text); 
     501    c.setCellValue("Overlay"); 
     502 
     503    cellnum = 1; 
     504    for (int i = 0; i<lengths.length; i++) { 
     505      c = r.createCell(cellnum++); 
     506      c.setCellStyle(text); 
     507      c.setCellValue(dims[i] + " (" + lengths[i] + ")"); 
     508    } 
     509 
     510    String[] colHeaders = {"x1", "y1", "x2", "y2", "text", "color", "filled", 
     511      "group", "notes"}; 
     512    for (int i=0; i<colHeaders.length; i++) { 
     513      c = r.createCell(cellnum++); 
     514      c.setCellStyle(text); 
     515      c.setCellValue(colHeaders[i]); 
     516    } 
     517 
     518    // overlays table 
     519    for (int i=0; i<overlays.length; i++) { 
     520      int[] pos = MathUtil.rasterToPosition(lengths, i); 
     521       
     522      for (int j=0; j<overlays[i].size(); j++) { 
     523        cellnum = 0; 
     524        // make new row 
     525        r = s.createRow(++rownum); 
     526         
     527        OverlayObject obj = (OverlayObject) overlays[i].elementAt(j); 
     528 
     529        // a 'rider' to this loop: keep track of noded objects 
     530        if (obj instanceof OverlayNodedObject) savedNodedObjects.add(obj); 
     531 
     532        // overlay object type 
     533        c = r.createCell(cellnum++); 
     534        c.setCellStyle(text); 
     535        c.setCellValue(obj.toString()); 
     536 
     537        // object dimensional position 
     538        for (int p=0; p<pos.length; p++) { 
     539          c = r.createCell(cellnum++); 
     540          c.setCellStyle(integer); 
     541          c.setCellValue(pos[p] + 1); // add 1 to shift indices for humans 
     542        } 
     543 
     544        // x1 
     545        c = r.createCell(cellnum++); 
     546        if (obj.hasEndpoint()) {  
     547          c.setCellStyle(flt); 
     548          c.setCellValue(obj.x1); 
     549        } 
     550        else { 
     551          c.setCellStyle(text); 
     552          c.setCellValue(NOT_APPLICABLE); 
     553        } 
     554         
     555        // y1  
     556        c = r.createCell(cellnum++); 
     557        if (obj.hasEndpoint()) {  
     558          c.setCellStyle(flt); 
     559          c.setCellValue(obj.y1); 
     560        } 
     561        else { 
     562          c.setCellStyle(text); 
     563          c.setCellValue(NOT_APPLICABLE); 
     564        } 
     565 
     566        // x2 
     567        c = r.createCell(cellnum++); 
     568        if (obj.hasEndpoint()) {  
     569          c.setCellStyle(flt); 
     570          c.setCellValue(obj.x2); 
     571        } 
     572        else { 
     573          c.setCellStyle(text); 
     574          c.setCellValue(NOT_APPLICABLE); 
     575        } 
     576 
     577        // y2  
     578        c = r.createCell(cellnum++); 
     579        if (obj.hasEndpoint()) {  
     580          c.setCellStyle(flt); 
     581          c.setCellValue(obj.y2); 
     582        } 
     583        else { 
     584          c.setCellStyle(text); 
     585          c.setCellValue(NOT_APPLICABLE); 
     586        } 
     587 
     588        // object text 
     589        c = r.createCell(cellnum++); 
     590        c.setCellStyle(text); 
     591        c.setCellValue(obj.hasText() ? obj.text : NOT_APPLICABLE); 
     592 
     593        // object color 
     594        c = r.createCell(cellnum++); 
     595        c.setCellStyle(hex); 
     596        c.setCellValue(ColorUtil.colorToHex(obj.color)); 
     597 
     598        // object filled 
     599        c = r.createCell(cellnum++); 
     600        c.setCellStyle(text); 
     601        c.setCellValue(obj.canBeFilled() ? "" + (obj.filled ? "true" : 
     602              "false") : NOT_APPLICABLE); 
     603         
     604        // object group 
     605        c = r.createCell(cellnum++); 
     606        c.setCellStyle(text); 
     607        c.setCellValue(obj.group.replaceAll("\t", " ")); 
     608 
     609        // object notes 
     610        c = r.createCell(cellnum++); 
     611        c.setCellStyle(text); 
     612        c.setCellValue(obj.notes.replaceAll("\t", " ")); 
     613      } 
     614    } 
     615 
     616    // write nodes of noded objects 
     617    int freeformCount = 0; 
     618    int polylineCount = 0; 
     619     
     620    rownum += 2; // skip a row 
     621    for (int i = 0; i<savedNodedObjects.size(); i++) { 
     622      OverlayNodedObject ono = (OverlayNodedObject)  
     623        savedNodedObjects.elementAt(i); 
     624 
     625      // write nodes header 
     626      int numNodes = ono.getNumNodes(); 
     627      r = s.createRow(rownum++); 
     628      c = r.createCell((short) 0); 
     629      c.setCellStyle(text); 
     630 
     631      float xx1, xx2, yy1, yy2; 
     632      xx1 = ono.getX(); 
     633      yy1 = ono.getY(); 
     634      xx2 = ono.getX2(); 
     635      yy2 = ono.getY2(); 
     636       
     637      int k = 0; 
     638      if (ono instanceof OverlayFreeform) k = ++freeformCount; 
     639      else if (ono instanceof OverlayPolyline) k = ++polylineCount; 
     640 
     641      String hdr = ono + " " + k + " (" + xx1 + "," + yy1 + ")(" + xx2 + "," + 
     642        yy2 + ")"; 
     643      c.setCellValue(hdr); 
     644 
     645      // write nodes themselves 
     646      for (int j = 0; j<numNodes; j++) { 
     647        float[] node = ono.getNodeCoords(j); 
     648        r = s.createRow(rownum++); 
     649        c = r.createCell((short) 0); 
     650        c.setCellStyle(flt); 
     651        c.setCellValue(node[0]); 
     652 
     653        c = r.createCell((short) 1); 
     654        c.setCellStyle(flt); 
     655        c.setCellValue(node[1]); 
     656      } 
     657      rownum++; // skip a row 
     658    } 
     659 
     660    return wb; 
    431661  } 
    432662 
     
    491721    // 
    492722    // I visualized the process of parsing an overlay file as a 'state machine': 
    493     // at each input (a line of text), the machine changes state and spits out an event 
    494     // telling the method loadOverlays to parse the line, display an error message, etc. 
    495     // This method getEventTypeAndNewState describes the state machine's behavior: each 
    496     // top-level if/elseif clause corresponds to a different state, and the interior 
    497     // if/elseif/else clauses describe possible transitions from that state. 
     723    // at each input (a line of text), the machine changes state and spits out 
     724    // an event telling the method loadOverlays to parse the line, display an 
     725    // error message, etc. 
     726    // This method getEventTypeAndNewState describes the state machine's 
     727    // behavior: each top-level if/elseif clause corresponds to a different 
     728    // state, and the interior if/elseif/else clauses describe possible 
     729    // transitions from that state. 
    498730    // 
    499     // As a result of using the state machine approach, I've managed to put most the error messages for 
    500     // unexpected lines in one place (if (event == BARF) under loadOverlays); however 
    501     // there are still many cases which generate errors elsewhere in loadOverlays. 
    502     // Adding more states to the machine and/or more rigorous checking for acceptable line formats 
    503     // in this machine would help reduce the number of exceptional cases not handled here. 
    504  
     731    // As a result of using the state machine approach, I've managed to put 
     732    // most the error messages for unexpected lines in one place (if (event == 
     733    // BARF) under loadOverlays); however there are still many cases which 
     734    // generate errors elsewhere in loadOverlays. 
     735    // Adding more states to the machine and/or more rigorous checking for 
     736    // acceptable line formats in this machine would help reduce the number of 
     737    // exceptional cases not handled here.   
     738     
    505739    int state = WAIT, event = BARF; 
    506740    if (current == WAIT) { 
     
    528762        state = TABLE; event = PARSE; 
    529763      } 
    530       else if (input.startsWith("#")) {state = TABLE; event = IGNORE;} // must check for freeform header first 
     764      else if (input.startsWith("#")) {state = TABLE; event = IGNORE;}  
     765      // must check for freeform header first 
    531766      else { 
    532767        event = BARF; state = TABLE; 
  • trunk/loci/visbio/overlays/OverlayTransform.java

    r2393 r2428  
    3636import loci.visbio.util.*; 
    3737import loci.visbio.view.DisplayWindow; 
     38import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
    3839import visad.*; 
    3940 
     
    417418  public void saveOverlays(PrintWriter out) { 
    418419    OverlayIO.saveOverlays(out, this); 
     420  } 
     421 
     422  /** Exports the overlays as .xls to the given output file.*/ 
     423  public HSSFWorkbook exportOverlays() { 
     424    return OverlayIO.exportOverlays (this); 
    419425  } 
    420426 
  • trunk/loci/visbio/overlays/OverlayWidget.java

    r2332 r2428  
    4040import loci.visbio.data.*; 
    4141import loci.visbio.util.*; 
     42import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
    4243import visad.util.Util; 
    4344 
     
    110111  /** Button for saving overlays to disk. */ 
    111112  protected JButton save; 
     113 
     114  /** Button for exporting overlays to .xls on disk. */ 
     115  protected JButton export; 
    112116 
    113117  // -- GUI components - overlay-specific -- 
     
    296300    save.setToolTipText("Saves overlays to a text file on disk"); 
    297301 
     302    // overlay export button 
     303    export = new JButton("Export overlays..."); 
     304    export.addActionListener(this); 
     305    if (!LAFUtil.isMacLookAndFeel()) save.setMnemonic('e'); 
     306    export.setToolTipText("Exports overlays to a .xls file on disk"); 
     307 
    298308    // lay out components 
    299309    setLayout(new BorderLayout()); 
     
    341351    row += 2; 
    342352    builder.add(ButtonBarFactory.buildCenteredBar(new JButton[] { 
    343       remove, copy, paste, dist, load, save}), 
     353      remove, copy, paste, dist, load, save, export}), 
    344354      cc.xyw(1, row, 9, "center, center")); 
    345355    row += 2; 
     
    666676      } 
    667677    } 
     678    else if (src == export) { 
     679      try { 
     680        FileOutputStream fout = new FileOutputStream("workbook.xls"); 
     681        HSSFWorkbook wb = overlay.exportOverlays(); 
     682        wb.write(fout); 
     683        fout.close(); 
     684      } 
     685      catch (IOException exc) { 
     686        //update this TODO ACS 
     687        exc.printStackTrace(); 
     688      } 
     689    } 
    668690  } 
    669691 
Note: See TracChangeset for help on using the changeset viewer.