打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
为Java应用程序加入脚本引擎

什么是BeanShell?

BeanShell是一个小型的,免费的,可嵌入式的,具有面向对象脚本语言特性的Java代码解释器。它是用Java语言写的。它能执行标准的Java语句和表达式,还自带简单的脚本命令和语法。它把编程对象当成一个简单的方法,这很像Perl和JavaScript.

你可以在写Java测试或调试时使用BeanShell,也可以用它作为你的应用程序的脚本引挚。简而言之,BeanShell可以动态的解释JAVA语言。也就是说BeanShell在许多方面对于Java的用处就像Tcl/Tk对于C的用处一样:BeanShell是可嵌入式的---你可以在运行时从你的应用程序调用BeanShell去动态的执行Java代码或是为你的应用程序提供脚本扩展。相反,你也可以从BeanShell调用你的应用程序及其对象,它可以让JAVA对象和API动态运行。正因为BeanShell是用JAVA写的,所以它可以和你的应用程序运行在同一个JVM空间内,你也可以自由的传递实时对象的引用(References)到脚本代码中并且作为结果返回。





回页首


BeanShell脚本语言简介

BeanShell能理解标准的JAVA语句,表达式,和方法宣告。语句和表达式的内容可以是:变量,宣告,赋值,方法调用,循环,条件等。

在Java程序中你必须严格的使用它们,但在BeanShell中,你可以用"宽松类型"(loosely typed)的方式来使用它们。也就是说,你可以在写脚本时偷懒,不进行变量类型的宣告(在原始数据类型和对象都可以)。如果你试着用错变量类型,BeanShell将会给出一个错误。总之BeanShell的脚本是很容易上手的。

这里有一个简单的例子:

foo = "Foo";            four = (2 + 2)*2/2;            print( foo + " = " + four );  // print() 是BeanShell的一个脚本命令。            // 循环            for (i=0; i<5; i++)            print(i);            //显示一个有包含一个按钮的窗口            button = new JButton( "My Button" );            frame = new JFrame( "My Frame" );            frame.getContentPane().add( button, "Center" );            frame.pack();            frame.setVisible(true);            

你也可以在Beanshell脚本中宣告和定义自己的方法:

int multiply(int a, int b)            {            return a*b;            }            print(multiply(12,14));//打印出168            

BeanShell的变量或参数的类型可以不用显示的指定,如下:

int multiply(a, b)            {            return a*b;            }            result = multiply(12,14);            print(result);//打印出168            

在BeanShell中也可以写对象。它与JavaScript很相似,它用一个方法,再内嵌一些内部方法,并且在未尾返回一个this来实现对象的编程:

Employee()            {            age = 26;            sex = "M";            name = "Turbo";            int getAge()            {            return age;            }            String getSex()            {            return sex;            }            String getName()            {            return name;            }            return this;            }            turbo = Employee(); // 构造一个Employee对象。            print("Name:"+turbo.getName); //打印出employee的名字。            

上面的程序片断,相信大家已经对BeanShell的语法有了一个印象,你可以通过参考资料中的链接,找到更详细的BeanShell的脚本语法教程。





回页首


在应用程序中嵌入脚本引擎

其实在Java中调用bsh的脚本非常简单,你需要先创建一个Interpreter类的实例.然后就可以用它运行你的脚本代码或者脚本文件。请看下面的一个例子,这个例子来自于BeanShell的文档:

Import bsh.*;            //创建一个bsh解释器实例            Interpeter bsh = new Interpreter();            // 表达式求值            bsh.eval("foo=Math.sin(0.5)");            bsh.eval("bar=foo*5; bar=Math.cos(bar);");            bsh.eval("for(i=0; i<10; i) { print(\"hello\"); }");            // 运行语句。            bsh.eval("for(int i=0; i<10; i) { System.out.println(\"hello\"); }");            // 载入脚本文件            bsh.source("myscript.bsh");  // or bsh.eval("source(\"myscript.bsh\")");            // 使用set()和get()方法存取变量值。            bsh.set( "date", new Date() );            Date date = (Date)bsh.get( "date" );            // This would also work:            Date date = (Date)bsh.eval( "date" );            bsh.eval("year = date.getYear()");            Integer year = (Integer)bsh.get("year");  // primitives use wrappers            // 也可以实现任意的Java Interface..            // 或处理AWT事件。            bsh.eval( "actionPerformed( e ) { print( e ); }");            ActionListener scriptedHandler =            (ActionListener)bsh.eval("return (ActionListener)this");            Use the scripted event handler normally...            new JButton.addActionListener( script );            





回页首


示例程序

为了让读者更好的理解,我们在这里以jdk1.4中的一个演示程序,Notepad程序作为基础,向读者讲解BeanShell是如何嵌入到Notepad程序中的。如果你安装了JDK1.4的话,Notepad源程序可以在<JAVA_HOME>\demo\jfc\Notepad目录中找到.

笔者写的一个BeanShell类,用来运行用户的脚本,下面的该程序的完整清单:

import javax.swing.text.*;            import javax.swing.*;            import java.io.*;            import bsh.*;            public class BeanShell            {            private static NameSpace namespace;            private static boolean running;            private static Notepad notepad;            //初始化引擎            public static void initBeanShell(Notepad pad)            {            notepad = pad;            namespace = new NameSpace("Notepad embedded scripting engine.");            }            //运行一段脚本代码            public static void runScript(String script)            {            try            {            StringReader reader = new StringReader(script);            runScript( "New script", reader);            }            catch(Exception ex)            {            ex.printStackTrace();            System.out.println(ex);            return;            }            }            public static void runScript(String scriptInfo, Reader reader)            {            Interpreter interpreter = new Interpreter(reader,System.out,System.out,true,namespace);            try            {            if(notepad != null)            {            JTextComponent editor = notepad.getEditor();            interpreter.set("application",notepad); //将应用程序的变量传入解释器,            interpreter.set("editor", editor);	    //这样就可在脚本中使用这个变量参照            running = true;            interpreter.eval(reader, namespace, scriptInfo);            }            }            catch(Throwable throwable)            {            throwable.printStackTrace();            JOptionPane.showMessageDialog(notepad,            new Object[]            {"Script 错误!",            throwable.getMessage()},            "错误",JOptionPane.ERROR_MESSAGE);            }            finally            {            running = false;            }            }            public static boolean isMacroRunning()            {            return running;            }            }            

这个BeanShell提供了三个方法,
void initBeanShell(Notepad),这个方法进行初始化。
void runScript(String script),这个方法可直接运行脚本代码。
void runScript(String scriptInfo, Reader reader),这个方法可从一个Reader流中运行脚本。
而真正核心的执行脚本的代码在void runScript(String scriptInfo, Reader reader)方法中,大家注意,代码中先创建了一个BeanShell的解释器实例,

Interpreter interpreter = new  Interpreter(reader,System.out,System.out,true,namespace);            

然后将Notepad程序的实例变量传入解释器,这样就可直接在脚本中引用Notedpad的实例了,

JTextComponent editor = notepad.getEditor();            interpreter.set("application",notepad); //将应用程序的变量传入解释器,            interpreter.set("editor", editor);	    //这样就可在脚本中使用这个变量参照            

接下来看看如何把BeanShell嵌入到Notepad程序中,笔者写了几个类, Main,用来初始化,并在Notepad程序中加入一个"Script Editor"的菜单 ScriptEditor,简单的脚本编辑器,用来编辑或载入脚本,运行脚本程序。 ScriptEditorAction,启动Script Editor的Action.

下面是Main.class的主要代码,

		Notepad notepad = new Notepad();            JMenu editMenu = new JMenu("Script Editor");            JMenuItem editItem = new JMenuItem();            editMenu.add(editItem);            editItem.setAction(new ScriptEditorAction(notepad));            notepad.getMenubar().add(editMenu);            

以上程序取得Notepad程序的Menu Bar,并添加一个Script Editor菜单到其中,这样,就可不用修改Notepad程序,并在其中加入启动Script Editor的菜单。

下图是程序运行中的画面:




这个程序的完整代码,请在文章未尾的参考资料中去下载。





回页首


写一个简单的脚本

现在我们写一个简单的脚本代码,用来统计某个单词在Notepad文章中的出现次数,下面列出这个脚本的代码:

/**            * 字串统计程序。            * @author: turbo chen            */            //字串统计函数            counter(s)            {            str = editor.getText();            str = str.toLowerCase();            slen = s.length();            s = s.toLowerCase();            count = 0;            from = 0;            while ( (from=str.indexOf(s,from))>-1 )            {            count = count + 1;            from = from + slen;            }            return count;            }            // application 是经由BeanShell传入的应用程序对象。            target = JOptionPane.showInputDialog(application,"Please input the count target:");            if ( target != null )            {            count = counter(target);            JOptionPane.showMessageDialog(application,"Found "+count+" targets.");            }            

将上面的脚本输入到"Script Editor"视窗中,运行它。看看程序运行的画面:




(查找"of"这个单词在文章中出现的次数,)




(找到13个目标。)





回页首


总结

本文讲解了BeanShell脚本引擎如何在现有的应用程序中应用,也让读者了解到BeanShell脚本的基本特性与脚本语法,让大家看到嵌入脚本引擎到Java应用程序中是多么的容易。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
BeanShell快速入门---Java应用程序脚本引擎 | 中华学习网--IT科技频道
Java中运行动态脚本 如Groovy
Java SE 6 新特性: 对脚本语言的支持
给 Java SE 注入脚本语言的活力
在Java中使用脚本语言 javax.script探秘
java调用jruby获取网页内容(JDK1.5) - coldtest的专栏 - CSD...
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服