我知道编辑这个网站吗?

脚本比较

本页通过代码示例提供了各种scripting languages的比较。

每个示例脚本都提供类似的功能:一个命令启动器,它打开一个小对话框窗口,让您输入 ImageJ 执行的命令。

当键入命令名称时,如果该命令存在,文本的颜色颜色变为黑色。

每个由剧本四个部分组成:

1.从ij.Menus类中获取所有命令的列表。

  1. 设置带有文本框的对话框。
  2. 向文本框添加文本侦听器,侦听器在完成与命令匹配单词的键入时更改字体颜色。 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);