原始 MediaWiki 页面

我知道编辑这个网站吗?
the ImageJ2 platform本页介绍与 the ImageJ2 platform 相关的内容。点击徽标查看详情。

BeanShell 脚本

自迁移出 MediaWiki 以来,本页内容尚未经过审查。如果您愿意帮忙,请查看帮助指南

BeanShell是与ImageJ macro language和Java类似的脚本语言。事实上,您甚至可以几乎逐字执行Java代码,但常见的情况是编写脚本,即省略所有语法糖以使您的代码成为类的一部分。

BeanShell 也不需要严格的类型(读:你不需要带有类型的变量的声明),使得在代码中有效地将代码转换为正确的 Java 构建很容易。

快速入门

如果你已经熟悉Java或者宏语言,那么BeanShell的语法你也很熟悉。

存在的 Hello, World! 示例:

// This prints 'Hello, World!' to the output area
print("Hello, World!");

变量可以被赋值:

someName = 1;
someName = "Hello";

默认情况下,BeanShell中的变量不是强类型的;如果您使用变量名但没有指定其类型,则可以指定指定任何内容。或者,您可以声明具有数据类型的变量,在这种情况下强制执行该类型:

String s;
s = 1; // this fails

注意:ImageJ 宏语言的内置函数在 BeanShell 中不可用。

语法

变量

  • 戒指是变化生物的占位符
  • 每个指标都有一个名称
  • 每个指标都有一个值
  • 值可以是任何数据类型(数字、文本等)
  • 变量可以被赋予新值

设置变量的值

变量通过以分号结尾的 name = value 形式的语句来赋值。该值可以是一个表达式。

intensity = 255;
value = 2 * 8 + 1;
title = "Hello, World!";
text = "title";

使用变量

您可以将一个变量的值设置为第二个变量的值:

text = title;

请注意,等号右侧的指标名称指的是设备本身(不是其值),但等号右侧的指标名称指的是设备中存储的当前值。

一旦变量被分配了新值,它们就会忘记旧值:

x = y;
y = x;

在第一个语句之后,x 采用y 的值,随后第二个语句不会更改y 的值。

赋值右边可以包含复杂的表达式:

x = y * y  2 * y + 3;

请注意,在将数值分配给变量之前,需要先计算右侧:

intensity = intensity * 2;

这意味着只是将强度的值增加一倍。

评论

在来源代码中使用注释非常重要,不仅可以让其他人理解代码的含义,还可以让您在 6 个月后再次查看代码时了解自己的含义。评论看起来像这样:

// This is a comment trying to help you to
// remember what you meant to do here:
a = Math.exp(x * Math.sin(y))
    + Math.atan(x * y  a);

您应该而不是用英语重复代码,但描述代码未传输的重要方面。例如,可能需要解决方法的错误,您可能需要在注释中对此进行解释(迄今为止您尝试“修复”解决方法)。

注释经常被窃取代码,例如调试语句

// x = 10; // hard-code x to 10 for now, just for debugging

如果您在评论中要说的内容很多,您可以使用多行评论:

/*
 Multi-line comments can be started by a slash
 followed by a star, and their end is marked
 by a star followed by a slash:
*/

进一步阅读

有关更多信息,请参阅 BeanShell 的 Quickstart 页面。

提示

您可以使用以下行脚本(即继续解释当前脚本之前解释其他脚本):

this.interpreter.source("the-other-script.bsh");

例子

将 CIEL*a*b 数字添加到状态栏

如果您的显示器已安排为sRGB,则有一种简单的方法可以在状态栏显示Lab值:

import color.CIELAB;

import java.awt.Label;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

// IJ1's API does not offer all I want
setAccessibility(true);

// press Escape on the ImageJ window to stop it
class Add_CIELab_to_Status extends Thread implements KeyListener {
    protected ImageJ ij;
    protected Label status;
    protected Pattern pattern = Pattern.compile("^.* value=([0-9]*),([0-9]*),([0-9]*)$");
    protected float[] lab, rgb;

    public Add_CIELab_to_Status() {
        ij = IJ.getInstance();
        status = ij.statusLine;
        ij.addKeyListener(this);
        lab = new float[3];
        rgb = new float[3];
    }

    public void run() {
        try {
            for (;;) {
                String text = status.getText();
                Matcher matcher = pattern.matcher(text);
                if (matcher.matches()) {
                    for (int i = 0; i < 3; i++)
                        rgb[i] = Float.parseFloat(matcher.group(i + 1)) / 255;
                    CIELAB.sRGB2CIELAB(rgb, lab);
                    status.setText(text + ", L=" + IJ.d2s(lab[0], 2)
                        + ",a*=" + IJ.d2s(lab[1], 3) + ",b*=" + IJ.d2s(lab[2], 3));
                }
                Thread.sleep(5);
            }
        } catch (InterruptedException e) {}
    }
     
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            ij.removeKeyListener(this);
            interrupt();
        }
    }

    public void keyReleased(KeyEvent e) {}
    public void keyTyped(KeyEvent e) {}
}

new Add_CIELab_to_Status().start();

此示例启动一个新线程(确保实现 run() 方法,但实际上调用 start() 方法!),该线程轮询状态栏。

它还将自身注册为按钮侦听器,以便当用户在主窗口出现焦点状态时按下 Escape 键时,它可以停止该进程。