|
RoiManager |
|
package ij.plugin.frame; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import java.awt.List; import java.util.zip.*; import ij.*; import ij.process.*; import ij.gui.*; import ij.io.*; import ij.plugin.filter.*; import ij.util.*; import ij.macro.*; import ij.measure.*; /** This plugin implements the Analyze/Tools/ROI Manager command. */ public class RoiManager extends PlugInFrame implements ActionListener, ItemListener, MouseListener, MouseWheelListener { static final int BUTTONS = 10; static final int DRAW=0, FILL=1, LABEL=2; static final int MENU=0, COMMAND=1, MULTI=2; Panel panel; static Frame instance; java.awt.List list; Hashtable rois = new Hashtable(); Roi roiCopy; boolean canceled; boolean macro; boolean ignoreInterrupts; PopupMenu pm; Button moreButton; static boolean measureAll = true; static boolean onePerSlice = true; public RoiManager() { super("ROI Manager"); if (instance!=null) { instance.toFront(); return; } instance = this; ImageJ ij = IJ.getInstance(); addKeyListener(ij); addMouseListener(this); addMouseWheelListener(this); WindowManager.addWindow(this); setLayout(new FlowLayout(FlowLayout.CENTER,5,5)); int rows = 15; boolean allowMultipleSelections = true; //IJ.isMacintosh(); list = new List(rows, allowMultipleSelections); list.add("012345678901234"); list.addItemListener(this); list.addKeyListener(ij); list.addMouseListener(this); list.addMouseWheelListener(this); if (IJ.isLinux()) list.setBackground(Color.white); add(list); panel = new Panel(); int nButtons = IJ.isJava2()?BUTTONS:BUTTONS-1; panel.setLayout(new GridLayout(nButtons, 1, 5, 0)); addButton("Add [t]"); addButton("Update"); addButton("Delete"); addButton("Rename"); addButton("Open"); addButton("Save"); addButton("Measure"); addButton("Deselect"); addButton("Show All"); addButton("More >>"); add(panel); addPopupMenu(); pack(); list.remove(0); GUI.center(this); show(); } void addButton(String label) { Button b = new Button(label); b.addActionListener(this); b.addKeyListener(IJ.getInstance()); b.addMouseListener(this); if (label.equals("More >>")) moreButton = b; panel.add(b); } void addPopupMenu() { pm=new PopupMenu(); //addPopupItem("Select All"); addPopupItem("Draw"); addPopupItem("Fill"); addPopupItem("Label"); pm.addSeparator(); addPopupItem("Combine"); addPopupItem("Split"); addPopupItem("Add Particles"); addPopupItem("Multi Measure"); addPopupItem("Sort"); addPopupItem("Specify..."); addPopupItem("Remove Slice Info"); addPopupItem("Help"); add(pm); } void addPopupItem(String s) { MenuItem mi=new MenuItem(s); mi.addActionListener(this); pm.add(mi); } public void actionPerformed(ActionEvent e) { int modifiers = e.getModifiers(); boolean altKeyDown = (modifiers&ActionEvent.ALT_MASK)!=0 || IJ.altKeyDown(); boolean shiftKeyDown = (modifiers&ActionEvent.SHIFT_MASK)!=0 || IJ.shiftKeyDown(); IJ.setKeyUp(KeyEvent.VK_ALT); IJ.setKeyUp(KeyEvent.VK_SHIFT); String label = e.getActionCommand(); if (label==null) return; String command = label; if (command.equals("Add [t]")) add(shiftKeyDown, altKeyDown); else if (command.equals("Update")) update(); else if (command.equals("Delete")) delete(false); else if (command.equals("Rename")) rename(null); else if (command.equals("Open")) open(null); else if (command.equals("Save")) save(); else if (command.equals("Measure")) measure(MENU); else if (command.equals("Show All")) showAll(); else if (command.equals("Draw")) drawOrFill(DRAW); else if (command.equals("Fill")) drawOrFill(FILL); else if (command.equals("Label")) drawOrFill(LABEL); else if (command.equals("Deselect")) select(-1); else if (command.equals("More >>")) { Point ploc = panel.getLocation(); Point bloc = moreButton.getLocation(); pm.show(this, ploc.x, bloc.y); } else if (command.equals("Select All")) selectAll(); else if (command.equals("Combine")) combine(); else if (command.equals("Split")) split(); else if (command.equals("Add Particles")) addParticles(); else if (command.equals("Multi Measure")) multiMeasure(); else if (command.equals("Sort")) sort(); else if (command.equals("Specify...")) specify(); else if (command.equals("Remove Slice Info")) removeSliceInfo(); else if (command.equals("Help")) help(); } public void itemStateChanged(ItemEvent e) { //IJ.log("itemStateChanged: "+e.getItem().toString()+" "+e+" "+ignoreInterrupts); if (e.getStateChange()==ItemEvent.SELECTED && !ignoreInterrupts) { int index = 0; try {index = Integer.parseInt(e.getItem().toString());} catch (NumberFormatException ex) {} if (index<0) index = 0; if (!IJ.shiftKeyDown() && !IJ.isMacintosh()) { int[] indexes = list.getSelectedIndexes(); for (int i=0; i<indexes.length; i++) { if (indexes[i]!=index) list.deselect(indexes[i]); } } if (WindowManager.getCurrentImage()!=null) { restore(index, true); if (Recorder.record) Recorder.record("roiManager", "Select", index); } } } void add(boolean shiftKeyDown, boolean altKeyDown) { if (shiftKeyDown) addAndDraw(altKeyDown); else if (altKeyDown) add(true); else add(false); } boolean add(boolean promptForName) { ImagePlus imp = getImage(); if (imp==null) return false; Roi roi = imp.getRoi(); if (roi==null) { error("The active image does not have a selection."); return false; } int n = list.getItemCount(); if (n>0) { // check for duplicate String label = list.getItem(n-1); Roi roi2 = (Roi)rois.get(label); if (roi2!=null) { int slice2 = getSliceNumber(label); if (roi.equals(roi2) && (slice2==-1||slice2==imp.getCurrentSlice())) return false; } } String name = roi.getName(); if (isStandardName(name)) name = null; String label = name!=null?name:getLabel(imp, roi, -1); if (promptForName) label = promptForName(label); else label = getUniqueName(label); if (label==null) return false; list.add(label); roi.setName(label); roiCopy = (Roi)roi.clone(); Calibration cal = imp.getCalibration(); if (cal.xOrigin!=0.0 || cal.yOrigin!=0.0) { Rectangle r = roiCopy.getBounds(); roiCopy.setLocation(r.x-(int)cal.xOrigin, r.y-(int)cal.yOrigin); } rois.put(label, roiCopy); updateShowAll(); if (Recorder.record) Recorder.record("roiManager", "Add"); return true; } /** Adds the specified ROI to the list. The third argument ('n') will be used form the first part of the ROI lable if it is >= 0. */ public void add(ImagePlus imp, Roi roi, int n) { if (roi==null) return; String label = getLabel(imp, roi, n); if (label==null) return; list.add(label); roi.setName(label); roiCopy = (Roi)roi.clone(); Calibration cal = imp.getCalibration(); if (cal.xOrigin!=0.0 || cal.yOrigin!=0.0) { Rectangle r = roiCopy.getBounds(); roiCopy.setLocation(r.x-(int)cal.xOrigin, r.y-(int)cal.yOrigin); } rois.put(label, roiCopy); } boolean isStandardName(String name) { if (name==null) return false; boolean isStandard = false; int len = name.length(); if (len>=14 && name.charAt(4)=='-' && name.charAt(9)=='-' ) isStandard = true; else if (len>=9 && name.charAt(4)=='-') isStandard = true; return isStandard; } String getLabel(ImagePlus imp, Roi roi, int n) { Rectangle r = roi.getBounds(); int xc = r.x + r.width/2; int yc = r.y + r.height/2; if (n>=0) {xc = yc; yc=n;} if (xc<0) xc = 0; if (yc<0) yc = 0; int digits = 4; String xs = "" + xc; if (xs.length()>digits) digits = xs.length(); String ys = "" + yc; if (ys.length()>digits) digits = ys.length(); xs = "000000" + xc; ys = "000000" + yc; String label = ys.substring(ys.length()-digits) + "-" + xs.substring(xs.length()-digits); if (imp.getStackSize()>1) { String zs = "000000" + imp.getCurrentSlice(); label = zs.substring(zs.length()-digits) + "-" + label; } return label; } void addAndDraw(boolean altKeyDown) { if (altKeyDown) { if (!add(true)) return; } else if (!add(false)) return; ImagePlus imp = WindowManager.getCurrentImage(); Undo.setup(Undo.COMPOUND_FILTER, imp); IJ.run("Draw"); Undo.setup(Undo.COMPOUND_FILTER_DONE, imp); if (Recorder.record) Recorder.record("roiManager", "Add & Draw"); } boolean delete(boolean replacing) { int count = list.getItemCount(); if (count==0) return error("The list is empty."); int index[] = list.getSelectedIndexes(); if (index.length==0 || (replacing&&count>1)) { String msg = "Delete all items on the list?"; if (replacing) msg = "Replace items on the list?"; canceled = false; if (!IJ.macroRunning() && !macro) { YesNoCancelDialog d = new YesNoCancelDialog(this, "ROI Manager", msg); if (d.cancelPressed()) {canceled = true; return false;} if (!d.yesPressed()) return false; } index = getAllIndexes(); } for (int i=count-1; i>=0; i--) { boolean delete = false; for (int j=0; j<index.length; j++) { if (index[j]==i) delete = true; } if (delete) { rois.remove(list.getItem(i)); list.remove(i); } } updateShowAll(); if (Recorder.record) Recorder.record("roiManager", "Delete"); return true; } boolean update() { ImagePlus imp = getImage(); if (imp==null) return false; ImageCanvas ic = imp.getCanvas(); boolean showingAll = ic!=null && ic.getShowAllROIs(); Roi roi = imp.getRoi(); if (roi==null) { error("The active image does not have a selection."); return false; } int index = list.getSelectedIndex(); if (index<0 && !showingAll) return error("Exactly one item in the list must be selected."); if (index>=0) { String name = list.getItem(index); rois.remove(name); rois.put(name, roi); } if (Recorder.record) Recorder.record("roiManager", "Update"); if (showingAll) imp.draw(); return true; } boolean rename(String name2) { int index = list.getSelectedIndex(); if (index<0) return error("Exactly one item in the list must be selected."); String name = list.getItem(index); if (name2==null) name2 = promptForName(name); if (name2==null) return false; Roi roi = (Roi)rois.get(name); rois.remove(name); roi.setName(name2); rois.put(name2, roi); list.replaceItem(name2, index); list.select(index); if (Recorder.record) Recorder.record("roiManager", "Rename", name2); return true; } String promptForName(String name) { GenericDialog gd = new GenericDialog("ROI Manager"); gd.addStringField("Rename As:", name, 20); gd.showDialog(); if (gd.wasCanceled()) return null; String name2 = gd.getNextString(); name2 = getUniqueName(name2); return name2; } boolean restore(int index, boolean setSlice) { String label = list.getItem(index); Roi roi = (Roi)rois.get(label); ImagePlus imp = getImage(); if (imp==null || roi==null) return false; if (setSlice) { int slice = getSliceNumber(label); if (slice>=1 && slice<=imp.getStackSize()) imp.setSlice(slice); } Roi roi2 = (Roi)roi.clone(); Calibration cal = imp.getCalibration(); Rectangle r = roi2.getBounds(); if (cal.xOrigin!=0.0 || cal.yOrigin!=0.0) roi2.setLocation(r.x+(int)cal.xOrigin, r.y+(int)cal.yOrigin); int width= imp.getWidth(), height=imp.getHeight(); if (r.x>=width || r.y>=height || (r.x+r.width)<=0 || (r.y+r.height)<=0) roi2.setLocation((width-r.width)/2, (height-r.height)/2); imp.setRoi(roi2); return true; } int getSliceNumber(String label) { int slice = -1; if (label.length()>4 && label.charAt(4)=='-' && label.length()>=14) slice = (int)Tools.parseDouble(label.substring(0,4),-1); return slice; } void open(String path) { Macro.setOptions(null); String name = null; if (path==null || path.equals("")) { OpenDialog od = new OpenDialog("Open Selection(s)...", ""); String directory = od.getDirectory(); name = od.getFileName(); if (name==null) return; path = directory + name; } if (Recorder.record) Recorder.record("roiManager", "Open", path); if (path.endsWith(".zip")) { openZip(path); return; } Opener o = new Opener(); if (name==null) name = o.getName(path); Roi roi = o.openRoi(path); if (roi!=null) { if (name.endsWith(".roi")) name = name.substring(0, name.length()-4); name = getUniqueName(name); list.add(name); rois.put(name, roi); } updateShowAll(); } // Modified on 2005/11/15 by Ulrik Stervbo to only read .roi files and to not empty the current list void openZip(String path) { ZipInputStream in = null; ByteArrayOutputStream out; int nRois = 0; try { in = new ZipInputStream(new FileInputStream(path)); byte[] buf = new byte[1024]; int len; ZipEntry entry = in.getNextEntry(); while (entry!=null) { String name = entry.getName(); if (name.endsWith(".roi")) { out = new ByteArrayOutputStream(); while ((len = in.read(buf)) > 0) out.write(buf, 0, len); out.close(); byte[] bytes = out.toByteArray(); RoiDecoder rd = new RoiDecoder(bytes, name); Roi roi = rd.getRoi(); if (roi!=null) { name = name.substring(0, name.length()-4); name = getUniqueName(name); list.add(name); rois.put(name, roi); nRois++; } } entry = in.getNextEntry(); } in.close(); } catch (IOException e) {error(e.toString());} if(nRois==0) error("This ZIP archive does not appear to contain \".roi\" files"); updateShowAll(); } String getUniqueName(String name) { String name2 = name; int n = 1; Roi roi2 = (Roi)rois.get(name2); while (roi2!=null) { roi2 = (Roi)rois.get(name2); if (roi2!=null) { int lastDash = name2.lastIndexOf("-"); if (lastDash!=-1 && name2.length()-lastDash<5) name2 = name2.substring(0, lastDash); name2 = name2+"-"+n; n++; } roi2 = (Roi)rois.get(name2); } return name2; } boolean save() { if (list.getItemCount()==0) return error("The selection list is empty."); int[] indexes = list.getSelectedIndexes(); if (indexes.length==0) indexes = getAllIndexes(); if (indexes.length>1) return saveMultiple(indexes, null); String name = list.getItem(indexes[0]); Macro.setOptions(null); SaveDialog sd = new SaveDialog("Save Selection...", name, ".roi"); String name2 = sd.getFileName(); if (name2 == null) return false; String dir = sd.getDirectory(); Roi roi = (Roi)rois.get(name); rois.remove(name); if (!name2.endsWith(".roi")) name2 = name2+".roi"; String newName = name2.substring(0, name2.length()-4); rois.put(newName, roi); roi.setName(newName); list.replaceItem(newName, indexes[0]); RoiEncoder re = new RoiEncoder(dir+name2); try { re.write(roi); } catch (IOException e) { IJ.error("ROI Manager", e.getMessage()); } return true; } boolean saveMultiple(int[] indexes, String path) { Macro.setOptions(null); if (path==null) { SaveDialog sd = new SaveDialog("Save ROIs...", "RoiSet", ".zip"); String name = sd.getFileName(); if (name == null) return false; if (!(name.endsWith(".zip") || name.endsWith(".ZIP"))) name = name + ".zip"; String dir = sd.getDirectory(); path = dir+name; } try { ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(path)); DataOutputStream out = new DataOutputStream(new BufferedOutputStream(zos)); RoiEncoder re = new RoiEncoder(out); for (int i=0; i<indexes.length; i++) { String label = list.getItem(indexes[i]); Roi roi = (Roi)rois.get(label); if (!label.endsWith(".roi")) label += ".roi"; zos.putNextEntry(new ZipEntry(label)); re.write(roi); out.flush(); } out.close(); } catch (IOException e) { error(""+e); return false; } if (Recorder.record) Recorder.record("roiManager", "Save", path); return true; } boolean measure(int mode) { ImagePlus imp = getImage(); if (imp==null) return false; int[] indexes = list.getSelectedIndexes(); if (indexes.length==0) indexes = getAllIndexes(); if (indexes.length==0) return false; int nLines = 0; boolean allSliceOne = true; for (int i=0; i<indexes.length; i++) { String label = list.getItem(indexes[i]); if (getSliceNumber(label)>1) allSliceOne = false; Roi roi = (Roi)rois.get(label); if (roi.isLine()) nLines++; } if (nLines>0 && nLines!=indexes.length) { error("All items must be areas or all must be lines."); return false; } int nSlices = 1; if (mode==MULTI) nSlices = imp.getStackSize(); int measurements = Analyzer.getMeasurements(); if (imp.getStackSize()>1) Analyzer.setMeasurements(measurements|Measurements.SLICE); int currentSlice = imp.getCurrentSlice(); for (int slice=1; slice<=nSlices; slice++) { if (nSlices>1) imp.setSlice(slice); for (int i=0; i<indexes.length; i++) { if (restore(indexes[i], nSlices==1&&!allSliceOne)) IJ.run("Measure"); else break; } } imp.setSlice(currentSlice); Analyzer.setMeasurements(measurements); if (indexes.length>1) IJ.run("Select None"); if (Recorder.record) Recorder.record("roiManager", "Measure"); return true; } /* This method performs measurements for several ROI's in a stack and arranges the results with one line per slice. By constast, the measure() method produces several lines per slice. The results from multiMeasure() may be easier to import into a spreadsheet program for plotting or additional analysis. Based on the multi() method in Bob Dougherty's Multi_Measure plugin (http://www.optinav.com/Multi-Measure.htm). */ boolean multiMeasure() { ImagePlus imp = getImage(); if (imp==null) return false; int[] indexes = list.getSelectedIndexes(); if (indexes.length==0) indexes = getAllIndexes(); if (indexes.length==0) return false; int measurements = Analyzer.getMeasurements(); int nSlices = imp.getStackSize(); GenericDialog gd = new GenericDialog("Multi Measure"); if (nSlices>1) gd.addCheckbox("Measure All "+nSlices+" Slices", measureAll); gd.addCheckbox("One Row Per Slice", onePerSlice); int columns = getColumnCount(imp, measurements)*indexes.length; String str = nSlices==1?"this option":"both options"; gd.setInsets(10, 25, 0); gd.addMessage( "Enabling "+str+" will result\n"+ "in a table with "+columns+" columns." ); gd.showDialog(); if (gd.wasCanceled()) return false; if (nSlices>1) measureAll = gd.getNextBoolean(); onePerSlice = gd.getNextBoolean(); if (!measureAll) nSlices = 1; int currentSlice = imp.getCurrentSlice(); if (!onePerSlice) return measure(MULTI); Analyzer aSys = new Analyzer(); //System Analyzer ResultsTable rtSys = Analyzer.getResultsTable(); ResultsTable rtMulti = new ResultsTable(); Analyzer aMulti = new Analyzer(imp, measurements, rtMulti); //Private Analyzer for (int slice=1; slice<=nSlices; slice++) { int sliceUse = slice; if(nSlices == 1)sliceUse = currentSlice; imp.setSlice(sliceUse); rtMulti.incrementCounter(); int roiIndex = 0; for (int i=0; i<indexes.length; i++) { if (restore(indexes[i], false)) { roiIndex++; Roi roi = imp.getRoi(); ImageStatistics stats = imp.getStatistics(measurements); aSys.saveResults(stats, roi); //Save measurements in system results table; for (int j=0; j<=rtSys.getLastColumn(); j++){ float[] col = rtSys.getColumn(j); String head = rtSys.getColumnHeading(j); if (head!=null && col!=null && !head.equals("Slice")) rtMulti.addValue(head+roiIndex,rtSys.getValue(j,rtSys.getCounter()-1)); } } else break; } aMulti.displayResults(); aMulti.updateHeadings(); } imp.setSlice(currentSlice); if (indexes.length>1) IJ.run("Select None"); return true; } int getColumnCount(ImagePlus imp, int measurements) { ImageStatistics stats = imp.getStatistics(measurements); ResultsTable rt = new ResultsTable(); Analyzer analyzer = new Analyzer(imp, measurements, rt); analyzer.saveResults(stats, null); int count = 0; for (int i=0; i<=rt.getLastColumn(); i++) { float[] col = rt.getColumn(i); String head = rt.getColumnHeading(i); if (head!=null && col!=null) count++; } return count; } boolean drawOrFill(int mode) { int[] indexes = list.getSelectedIndexes(); if (indexes.length==0) indexes = getAllIndexes(); ImagePlus imp = WindowManager.getCurrentImage(); imp.killRoi(); ImageProcessor ip = imp.getProcessor(); ip.setColor(Toolbar.getForegroundColor()); ip.snapshot(); Undo.setup(Undo.FILTER, imp); Filler filler = mode==LABEL?new Filler():null; int slice = imp.getCurrentSlice(); for (int i=0; i<indexes.length; i++) { String name = list.getItem(i); Roi roi = (Roi)rois.get(name); int type = roi.getType(); if (roi==null) continue; if (mode==FILL&&(type==Roi.POLYLINE||type==Roi.FREELINE||type==Roi.ANGLE)) mode = DRAW; int slice2 = getSliceNumber(name); if (slice2>=1 && slice2<=imp.getStackSize()) { imp.setSlice(slice2); ip = imp.getProcessor(); ip.setColor(Toolbar.getForegroundColor()); if (slice2!=slice) Undo.reset(); } switch (mode) { case DRAW: roi.drawPixels(ip); break; case FILL: ip.fillPolygon(roi.getPolygon()); break; case LABEL: roi.drawPixels(ip); filler.drawLabel(imp, ip, i+1, roi.getBounds()); break; } } ImageCanvas ic = imp.getCanvas(); if (ic!=null) ic.setShowAllROIs(false); imp.updateAndDraw(); String str=null; switch (mode) { case DRAW: str="Draw"; break; case FILL: str="Fill"; break; case LABEL: str="Label"; imp.updateAndDraw(); break; } if (Recorder.record) Recorder.record("roiManager", str); return true; } void combine() { ImagePlus imp = getImage(); if (imp==null) return; int[] indexes = list.getSelectedIndexes(); if (indexes.length==1) { error("More than one item must be selected, or none"); return; } if (indexes.length==0) indexes = getAllIndexes(); ShapeRoi s1=null, s2=null; for (int i=0; i<indexes.length; i++) { Roi roi = (Roi)rois.get(list.getItem(indexes[i])); if (roi.isLine() || roi.getType()==Roi.POINT) continue; Calibration cal = imp.getCalibration(); if (cal.xOrigin!=0.0 || cal.yOrigin!=0.0) { roi = (Roi)roi.clone(); Rectangle r = roi.getBounds(); roi.setLocation(r.x+(int)cal.xOrigin, r.y+(int)cal.yOrigin); } if (s1==null) { if (roi instanceof ShapeRoi) s1 = (ShapeRoi)roi; else s1 = new ShapeRoi(roi); if (s1==null) return; } else { if (roi instanceof ShapeRoi) s2 = (ShapeRoi)roi; else s2 = new ShapeRoi(roi); if (s2==null) continue; if (roi.isArea()) s1.or(s2); } } if (s1!=null) imp.setRoi(s1); if (Recorder.record) Recorder.record("roiManager", "Combine"); } void addParticles() { String err = IJ.runMacroFile("ij.jar:AddParticles", null); if (err!=null && err.length()>0) error(err); } void sort() { int n = rois.size(); if (n==0) return; String[] labels = new String[n]; int index = 0; for (Enumeration en=rois.keys(); en.hasMoreElements();) labels[index++] = (String)en.nextElement(); list.removeAll(); StringSorter.sort(labels); for (int i=0; i<labels.length; i++) list.add(labels[i]); if (Recorder.record) Recorder.record("roiManager", "Sort"); } void specify() { try {IJ.run("Specify...");} catch (Exception e) {return;} runCommand("add"); } void removeSliceInfo() { int[] indexes = list.getSelectedIndexes(); if (indexes.length==0) indexes = getAllIndexes(); for (int i=0; i<indexes.length; i++) { int index = indexes[i]; String name = list.getItem(index); int n = getSliceNumber(name); if (n==-1) continue; String name2 = name.substring(5, name.length()); name2 = getUniqueName(name2); Roi roi = (Roi)rois.get(name); rois.remove(name); roi.setName(name2); rois.put(name2, roi); list.replaceItem(name2, index); } } void help() { String macro = "run('URL...', 'url=http://rsb.info.nih.gov/ij/docs/menus/analyze.html#manager');"; new MacroRunner(macro); } void split() { ImagePlus imp = getImage(); if (imp==null) return; Roi roi = imp.getRoi(); if (roi==null || roi.getType()!=Roi.COMPOSITE) { error("Image with composite selection required"); return; } Roi[] rois = ((ShapeRoi)roi).getRois(); for (int i=0; i<rois.length; i++) { imp.setRoi(rois[i]); add(false); } //if (Recorder.record) Recorder.record("roiManager", "Split"); } void showAll() { ImagePlus imp = WindowManager.getCurrentImage(); if (imp==null) {error("There are no images open."); return;} ImageCanvas ic = imp.getCanvas(); if (ic==null) return; boolean showingROIs = ic.getShowAllROIs(); ic.setShowAllROIs(!showingROIs); if (Recorder.record) Recorder.recordString("setOption(\"Show All\","+(showingROIs?"false":"true")+");\n"); imp.draw(); } void updateShowAll() { ImagePlus imp = WindowManager.getCurrentImage(); if (imp==null) return; ImageCanvas ic = imp.getCanvas(); if (ic!=null && ic.getShowAllROIs()) imp.draw(); } int[] getAllIndexes() { int count = list.getItemCount(); int[] indexes = new int[count]; for (int i=0; i<count; i++) indexes[i] = i; return indexes; } ImagePlus getImage() { ImagePlus imp = WindowManager.getCurrentImage(); if (imp==null) { error("There are no images open."); return null; } else return imp; } boolean error(String msg) { new MessageDialog(this, "ROI Manager", msg); Macro.abort(); return false; } public void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID()==WindowEvent.WINDOW_CLOSING) { instance = null; } ignoreInterrupts = false; } /** Returns a reference to the ROI Manager or null if it is not open. */ public static RoiManager getInstance() { return (RoiManager)instance; } /** Returns the ROI Hashtable. @see getCount @see getRoisAsArray */ public Hashtable getROIs() { return rois; } /** Returns the selection list. @see getCount @see getRoisAsArray */ public List getList() { return list; } /** Returns the ROI count. */ public int getCount() { return list.getItemCount(); } /** Returns the ROIs as an array. */ public Roi[] getRoisAsArray() { int n = list.getItemCount(); Roi[] array = new Roi[n]; for (int i=0; i<n; i++) { String label = list.getItem(i); array[i] = (Roi)rois.get(label); } return array; } /** Returns the name of the selection with the specified index. Can be called from a macro using <pre>call("ij.plugin.frame.RoiManager.getName", index)</pre> Returns "null" if the Roi Manager is not open or index is out of range. */ public static String getName(String index) { int i = (int)Tools.parseDouble(index, -1); RoiManager instance = getInstance(); if (instance!=null && i>=0 && i<instance.list.getItemCount()) return instance.list.getItem(i); else return "null"; } /** Executes the ROI Manager "Add", "Add & Draw", "Update", "Delete", "Measure", "Draw", "Fill", "Deselect", "Select All", "Combine", "Split" or "Sort" command. Returns false if <code>cmd</code> is not one of these strings. */ public boolean runCommand(String cmd) { cmd = cmd.toLowerCase(); macro = true; boolean ok = true; if (cmd.equals("add")) add(IJ.shiftKeyDown(), IJ.altKeyDown()); else if (cmd.equals("add & draw")) addAndDraw(false); else if (cmd.equals("update")) update(); else if (cmd.equals("delete")) delete(false); else if (cmd.equals("measure")) measure(COMMAND); else if (cmd.equals("draw")) drawOrFill(DRAW); else if (cmd.equals("fill")) drawOrFill(FILL); else if (cmd.equals("label")) drawOrFill(LABEL); else if (cmd.equals("combine")) combine(); else if (cmd.equals("split")) split(); else if (cmd.equals("sort")) sort(); else if (cmd.equals("deselect")||cmd.indexOf("all")!=-1) { if (IJ.isMacOSX()) ignoreInterrupts = true; select(-1); } else if (cmd.equals("reset")) { list.removeAll(); rois.clear(); } else ok = false; macro = false; return ok; } /** Executes the ROI Manager "Open", "Save" or "Rename" command. Returns false if <code>cmd</code> is not "Open", "Save" or "Rename", or if an error occurs. */ public boolean runCommand(String cmd, String name) { cmd = cmd.toLowerCase(); macro = true; if (cmd.equals("open")) { open(name); macro = false; return true; } else if (cmd.equals("save")) { if (!name.endsWith(".zip") && !name.equals("")) return error("Name must end with '.zip'"); if (list.getItemCount()==0) return error("The selection list is empty."); int[] indexes = getAllIndexes(); boolean ok = false; if (name.equals("")) ok = saveMultiple(indexes, null); else ok = saveMultiple(indexes, name); macro = false; return ok; } else if (cmd.equals("rename")) { rename(name); macro = false; return true; } return false; } public void select(int index) { int n = list.getItemCount(); if (index<0) { for (int i=0; i<n; i++) if (list.isSelected(i)) list.deselect(i); return; } boolean mm = list.isMultipleMode(); if (mm) list.setMultipleMode(false); if (index<n) { list.select(index); restore(index, true); if (!Interpreter.isBatchMode()) IJ.wait(10); } if (mm) list.setMultipleMode(true); } public void select(int index, boolean shiftKeyDown, boolean altKeyDown) { if (!(shiftKeyDown||altKeyDown)) select(index); ImagePlus imp = IJ.getImage(); if (imp==null) return; Roi previousRoi = imp.getRoi(); if (previousRoi==null) {select(index); return;} Roi.previousRoi = (Roi)previousRoi.clone(); String label = list.getItem(index); Roi roi = (Roi)rois.get(label); if (roi!=null) { roi.setImage(imp); roi.update(shiftKeyDown, altKeyDown); } } void selectAll() { boolean allSelected = true; int count = list.getItemCount(); for (int i=0; i<count; i++) { if (!list.isIndexSelected(i)) allSelected = false; } if (allSelected) select(-1); else { for (int i=0; i<count; i++) if (!list.isSelected(i)) list.select(i); } } /** Overrides PlugInFrame.close(). */ public void close() { super.close(); instance = null; } public void mousePressed (MouseEvent e) { int x=e.getX(), y=e.getY(); if (e.isPopupTrigger() || e.isMetaDown()) pm.show(e.getComponent(),x,y); } public void mouseWheelMoved(MouseWheelEvent event) { synchronized(this) { int index = list.getSelectedIndex(); int rot = event.getWheelRotation(); if (rot<-1) rot = -1; if (rot>1) rot = 1; index += rot; if (index<0) index = 0; if (index>=list.getItemCount()) index = list.getItemCount(); //IJ.log(index+" "+rot); select(index); if (IJ.isWindows()) list.requestFocusInWindow(); } } public void mouseReleased (MouseEvent e) {} public void mouseClicked (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} }
|
RoiManager |
|