package ij; import ij.util.Tools; import ij.text.TextWindow; import ij.plugin.MacroInstaller; import ij.plugin.frame.Recorder; import ij.io.OpenDialog; import java.io.*; import java.util.*; import java.awt.event.KeyEvent; import java.awt.Menu; /** Runs ImageJ menu commands in a separate thread.*/ public class Executer implements Runnable { private static String previousCommand; private static CommandListener listener; private static Vector listeners = new Vector(); private String command; private Thread thread; /** Create an Executer to run the specified menu command in this thread using the active image. */ public Executer(String cmd) { command = cmd; } /** Create an Executer that runs the specified menu command in a separate thread using the specified image, or using the active image if 'imp' is null. */ public Executer(String cmd, ImagePlus imp) { if (cmd.startsWith("Repeat")) { command = previousCommand; IJ.setKeyUp(KeyEvent.VK_SHIFT); } else { command = cmd; if (!(cmd.equals("Undo")||cmd.equals("Close"))) previousCommand = cmd; } IJ.resetEscape(); thread = new Thread(this, cmd); thread.setPriority(Math.max(thread.getPriority()-2, Thread.MIN_PRIORITY)); if (imp!=null) WindowManager.setTempCurrentImage(thread, imp); thread.start(); } public void run() { if (command==null) return; if (listeners.size()>0) synchronized (listeners) { for (int i=0; i<listeners.size(); i++) { CommandListener listener = (CommandListener)listeners.elementAt(i); command = listener.commandExecuting(command); if (command==null) return; } } try { if (Recorder.record) { Recorder.setCommand(command); runCommand(command); Recorder.saveCommand(); } else runCommand(command); int len = command.length(); if (command.charAt(len-1)!=']') IJ.setKeyUp(IJ.ALL_KEYS); // set keys up except for "<", ">", "+" and "-" shortcuts } catch(Throwable e) { IJ.showStatus(""); IJ.showProgress(1, 1); ImagePlus imp = WindowManager.getCurrentImage(); if (imp!=null) imp.unlock(); String msg = e.getMessage(); if (e instanceof OutOfMemoryError) IJ.outOfMemory(command); else if (e instanceof RuntimeException && msg!=null && msg.equals(Macro.MACRO_CANCELED)) ; //do nothing else { CharArrayWriter caw = new CharArrayWriter(); PrintWriter pw = new PrintWriter(caw); e.printStackTrace(pw); String s = caw.toString(); if (IJ.isMacintosh()) { if (s.indexOf("ThreadDeath")>0) return; s = Tools.fixNewLines(s); } int w=500, h=300; if (s.indexOf("UnsupportedClassVersionError")!=-1) { if (s.indexOf("version 49.0")!=-1) { s = e + "\n \nThis plugin requires Java 1.5 or later."; w=700; h=150; } if (s.indexOf("version 50.0")!=-1) { s = e + "\n \nThis plugin requires Java 1.6 or later."; w=700; h=150; } if (s.indexOf("version 51.0")!=-1) { s = e + "\n \nThis plugin requires Java 1.7 or later."; w=700; h=150; } } if (IJ.getInstance()!=null) new TextWindow("Exception", s, w, h); else IJ.log(s); } } } void runCommand(String cmd) { Hashtable table = Menus.getCommands(); String className = (String)table.get(cmd); if (className!=null) { String arg = ""; if (className.endsWith("\")")) { // extract string argument (e.g. className("arg")) int argStart = className.lastIndexOf("(\""); if (argStart>0) { arg = className.substring(argStart+2, className.length()-2); className = className.substring(0, argStart); } } if (IJ.shiftKeyDown() && className.startsWith("ij.plugin.Macro_Runner") && !Menus.getShortcuts().contains("*"+cmd)) IJ.open(IJ.getDirectory("plugins")+arg); else IJ.runPlugIn(cmd, className, arg); } else { // Is this command in Plugins>Macros? if (MacroInstaller.runMacroCommand(cmd)) return; // Is this command a LUT name? String path = IJ.getDirectory("luts")+cmd+".lut"; File f = new File(path); if (f.exists()) { String dir = OpenDialog.getLastDirectory(); IJ.open(path); OpenDialog.setLastDirectory(dir); } else if (!openRecent(cmd)) IJ.error("Unrecognized command: " + cmd); } } /** Opens a file from the File/Open Recent menu and returns 'true' if successful. */ boolean openRecent(String cmd) { Menu menu = Menus.openRecentMenu; if (menu==null) return false; for (int i=0; i<menu.getItemCount(); i++) { if (menu.getItem(i).getLabel().equals(cmd)) { IJ.open(cmd); return true; } } return false; } /** Returns the last command executed. Returns null if no command has been executed. */ public static String getCommand() { return previousCommand; } /** Adds the specified command listener. */ public static void addCommandListener(CommandListener listener) { listeners.addElement(listener); } /** Removes the specified command listener. */ public static void removeCommandListener(CommandListener listener) { listeners.removeElement(listener); } }