本页通过代码示例提供了各种scripting languages的比较。
每个示例脚本都提供类似的功能:一个命令启动器,它打开一个小对话框窗口,让您输入 ImageJ 执行的命令。
当键入命令名称时,如果该命令存在,文本的颜色颜色变为黑色。
每个由剧本四个部分组成:
1.从ij.Menus类中获取所有命令的列表。
- 设置带有文本框的对话框。
- 向文本框添加文本侦听器,侦听器在完成与命令匹配单词的键入时更改字体颜色。 4.点击“确定”按钮或按回车键时执行命令。
使用 Java 编写的命令启动器是迄今为止代码行的,更糟糕的是,也是最冗长的。
虽然在 Clojure 中可以根据需要声明类型,但并不是简单的;该脚本的低文件计算要求不会产生不必要的冗长。但 Java 需要类型声明,以便可以编译脚本并生成二进制 .class。
虽然 Java 和 Clojure 版本都将指纹封装在本地名称空间中(在 Clojure 中,通过使用 let 语句来声明本地变量),但 Jython 版本则不然,因此在类外部定义时,它们都是全局的。不过,可以通过在类或函数中定义整个脚本来实现指纹封装,但它不像 Java 中那样“简单”,也不像 Clojure 中那样自然和简单。
其优点是,每个 Jython 脚本都在其自己的命名空间和解释器实例中执行,而 Clojure 脚本全部在唯一的静态解释器中运行,共享因此的命名空间。
JavaScript 版本(下面粘贴的简单代码)非常类似于 Java。每个脚本都在其至少单独的线程和命名空间上运行,就像 Jython 脚本一样。
请注意,Clojure 不是脚本语言:Clojure 直接编译为 JVM 字节码,因此以本机运行。
在 Java 中
另请参阅Introduction into Developing Plugins文档页面。
import ij.IJ;
import ij.plugin.PlugIn;
import ij.gui.GenericDialog;
import java.util.Hashtable;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.TextField;
import java.awt.event.TextListener;
import java.awt.event.TextEvent;
import java.awt.Color;
public class Command_Launcher implements PlugIn {
public void run(String arg) {
// obtain a list of all commands, sorted
Hashtable commands = ij.Menus.getCommands();
final ArrayList keys = new ArrayList();
keys.addAll(commands.keySet());
Collections.sort(keys);
// gui
GenericDialog gd = new GenericDialog("Launcher");
gd.addStringField("Command: ", "");
final TextField prompt = (TextField)gd.getStringFields().get(0);
prompt.setForeground(Color.red);
prompt.addTextListener(new TextListener() {
public void textValueChanged(TextEvent e) {
String text = prompt.getText();
// if a command matches, redo color to black
for (Iterator it = keys.iterator(); it.hasNext(); ) {
String command = (String)it.next();
if (command.equals(text)) {
prompt.setForeground(Color.black);
return;
}
}
// no command found, set to red:
prompt.setForeground(Color.red);
}
});
gd.showDialog();
if (gd.wasCanceled()) return;
String command = gd.getNextString();
// execute!
IJ.doCommand(command);
}
}
请注意,上面的循环仅作为示例设置。简单地查询 keys 列表来查找我们正在寻找的特定 text 键会更容易:
...
// if a command matches, redo color to black
if (keys.contains(text)) {
prompt.setForeground(Color.black);
return;
}
...
在 Jython 中
另请参阅 Jython Scripting 文档页面。
from java.awt import Color
from java.awt.event import TextListener
import ij
commands = ij.Menus.getCommands().keySet().toArray()
gd = ij.gui.GenericDialog('Command Launcher')
gd.addStringField('Command: ', '');
prompt = gd.getStringFields().get(0)
prompt.setForeground(Color.red)
class TypeListener(TextListener):
def textValueChanged(self, tvc):
if prompt.getText() in commands:
prompt.setForeground(Color.black)
return prompt.setForeground(Color.red)
prompt.addTextListener(TypeListener())
gd.showDialog()
if not gd.wasCanceled():
ij.IJ.doCommand(gd.getNextString())
在上面,请注意,我们不是循环命令列表,而是使用“列表中的 if 元素”结构来查询它。要实际循环,请执行以下操作:
text = prompt.getText()
for c in commands:
if c == text:
prompt.setForeground(Color.black)
return
prompt.setForeground(Color.red)
在 Clojure 中
另请参阅 Clojure Scripting 文档页面。
(import '(java.awt Color)
'(java.awt.event TextListener)
'(ij.gui GenericDialog)
'(ij IJ)
'(ij Menus))
(let [commands (keys (. Menus getCommands))
gd (GenericDialog. "Command Launcher")]
(.addStringField gd "Command: " "")
(let [prompt (. (. gd getStringFields) get 0)]
(doto prompt
(.setForeground (. Color red))
(.addTextListener (proxy [TextListener] []
(textValueChanged [tvc]
(let [text (.getText prompt)]
(.setForeground prompt
(if (some #{text} commands)
(. Color black)
(. Color red)))))))))
(.showDialog gd)
(when-not (.wasCanceled gd)
(IJ/doCommand (.getNextString gd))))
第二个版本是 lispier,由 Clojure 的 Rich Hickey 重写了上述版本。请注意使用 §§§0作者§§§函数来检查列表中的任何给定键(text 是此处唯一的键)是否包含在一组键 (commands) 中:
(import '(java.awt Color)
'(java.awt.event TextListener))
(let [commands (keys (.getCommands ij.Menus))
gd (ij.gui.GenericDialog. "Command Launcher")]
(.addStringField gd "Command: " "")
(let [prompt (.. gd getStringFields (get 0))]
(doto prompt
(setForeground (. Color red))
(addTextListener (proxy [TextListener] []
(textValueChanged [tvc]
(let [text (.getText prompt)]
(.setForeground prompt
(if (some #{text} commands)
(. Color black)
(. Color red)))))))))
(.showDialog gd)
(when-not (.wasCanceled gd)
(.doCommand ij.IJ (.getNextString gd))))
在 JavaScript 中
另请参阅 JavaScript Scripting 文档页面。
// All ImageJ and java.lang.* classes have been automatically imported
// using importPackage(Package.ij) etc. directives.
importClass(Packages.java.awt.event.TextListener);
importClass(Packages.java.awt.Color)
var commands = Menus.getCommands();
var keys = commands.keySet();
var gd = new GenericDialog("Command Launcher");
gd.addStringField("Command: ", "");
var prom = gd.getStringFields().get(0);
prom.setForeground(Color.red);
prom.addTextListener(new TextListener( {
textValueChanged: function(evt) {
if (keys.contains(prom.getText()))
prom.setForeground(Color.black);
else
prom.setForeground(Color.red);
}
}));
gd.showDialog();
if (!gd.wasCanceled())
IJ.doCommand(gd.getNextString());
在 JRuby 中
有关使用 JRuby 编写的 ImageJ 脚本的一些教程材料,请参阅JRuby Scripting。
include_class 'java.awt.Color'
include_class 'java.awt.event.TextListener'
class TypeListener
# This is the (slightly surprising) JRuby way of implementing
# a Java interface:
include TextListener
def initialize(commands,prompt)
@commands = commands
@prompt = prompt
end
def textValueChanged(tvc)
text = @prompt.getText
if @commands.include? text
@prompt.setForeground Color.black
else
@prompt.setForeground Color.red
end
end
end
commands = ij.Menus.getCommands.keySet.toArray
gd = ij.gui.GenericDialog.new 'CommandLauncher'
gd.addStringField 'Command: ', ''
prompt = gd.getStringFields[0]
prompt.setForeground Color.red
prompt.addTextListener TypeListener.new( commands, prompt )
gd.showDialog
unless gd.wasCanceled
ij.IJ.doCommand gd.getNextString
end
在 BeanShell 中
另请参阅 Beanshell Scripting 文档页面。
有关使用 BeanShell 的一些教程材料,请参阅BeanShell’s Quickstart。
如果这对您来说非常像 Java 示例,那么您是绝对正确的:BeanShell 具有与 Java 相同的语法,尽管它不是强类型的(如果您不一样,则占用声明变量),并且它是解释性的。
import ij.IJ;
import ij.Menus;
import ij.plugin.PlugIn;
import ij.gui.GenericDialog;
import java.util.Hashtable;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.TextField;
import java.awt.event.TextListener;
import java.awt.event.TextEvent;
import java.awt.Color;
keys = new ArrayList();
keys.addAll(Menus.getCommands().keySet());
Collections.sort(keys);
// gui
GenericDialog gd = new GenericDialog("Launcher");
gd.addStringField("Command: ", "");
final TextField prompt = (TextField)gd.getStringFields().get(0);
prompt.setForeground(Color.red);
prompt.addTextListener(new TextListener() {
public void textValueChanged(TextEvent e) {
String text = prompt.getText();
// if a command matches, redo color to black
for (Iterator it = keys.iterator(); it.hasNext(); ) {
String command = (String)it.next();
if (command.equals(text)) {
prompt.setForeground(Color.black);
return;
}
}
// no command found, set to red:
prompt.setForeground(Color.red);
}
});
gd.showDialog();
if (gd.wasCanceled()) return;
String command = gd.getNextString();
// execute!
IJ.doCommand(command);