大梦想家

5年开发工程师,2年实施经理,X年售前顾问,......
数据加载中……
使用JRuby为你的客户端助力

    预言了两天,终于决定在我们的RCP客户端中增加执行JRuby的功能。说是预言其实也没有什么好预言的,JRuby早有耳闻,Ruby也一直在学习。其实要解决的问题只有一个---解决Java实例如何给JRuby,然后有JRuby操作,其实不难,JRbuy官方的WIKI上有一个例子,但是那个例子有太多硬编码的问题,稍稍改造,将硬编码的内容抽取到JRuby中,就好了~

    我想说的其实是在RCP中加入JRuby的作用是:

    实施人员只需要写脚本就可以随意操作界面上的任意东西;

    使产品更进一步达到零二次开发的阶段;

    使用JRuby来开发SWT的界面,还是有比较复杂,在熟悉SWT开发和JRuby的情况下画一个比较复杂的界面时候就会非常复杂!这里还是建议使用类似于XSWT等XML界面描述语言,然后配合脚本完成功能。

下面给出一个可以在运行JRuby的SWTShell:

package com.glnpu.jruby;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.jruby.Ruby;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.builtin.IRubyObject;

public class RunJRUBY extends Shell {

    private RunJRUBY run;
    private Text text;
    /**
     * Launch the application
     * @param args
     */
    public static void main(String args[]) {
        try {
            Display display = Display.getDefault();
            RunJRUBY shell = new RunJRUBY(display, SWT.SHELL_TRIM);
            shell.open();
            shell.layout();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                    display.sleep();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Create the shell
     * @param display
     * @param style
     */
    public RunJRUBY(Display display, int style) {
        super(display, style);
        run = this;
        createContents();
    }

    /**
     * Create contents of the window
     */
    protected void createContents() {
        setText("SWT Application");
        setSize(500, 375);

        text = new Text(this, SWT.V_SCROLL | SWT.BORDER | SWT.WRAP | SWT.H_SCROLL);
        text.setBounds(0, 0, 492, 312);

        final Button button = new Button(this, SWT.NONE);
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent e) {
                Ruby runtime = Ruby.getDefaultInstance();
                try {
                    //允许传对象,作为参数给JRuby
                    IRubyObject rootRubyObject = JavaEmbedUtils.newRuntimeAdapter().eval( runtime, text.getText() );
                    JavaEmbedUtils.invokeMethod( runtime, rootRubyObject, "run", new Object[] {run}, null );
                    //不传对象,直接运行JRbuy
                    //runtime.evalScriptlet(text.getText());
                } catch (Exception e1) {
                    System.err.println(e1.toString());
                    e1.printStackTrace();
                }
            }
        });
        button.setText("button");
        button.setBounds(335, 326, 48, 22);
        //
    }

    @Override
    protected void checkSubclass() {
        // Disable the check that prevents subclassing of SWT components
    }

}

下面是可以执行的JRuby代码:

require 'java'
module SWTTest
  include_package 'org.eclipse.swt'
  include_package 'org.eclipse.swt.layout'
  include_package 'org.eclipse.swt.widgets'
  include_package 'org.eclipse.swt.events'
end
    class TestDialog < SWTTest::Dialog
      @shell
      @parentShell
      def initialize shell
          super(shell, SWTTest::SWT::NONE)
          @parentShell = shell
          open
      end
      def open
          createContents()
          @shell.open();
          @shell.layout();       
      end
      def createContents
          @shell = SWTTest::Shell.new(@parentShell, SWTTest::SWT::DIALOG_TRIM | SWTTest::SWT::APPLICATION_MODAL)
          @shell.setSize(500, 375);
          @shell.setText("SWT Dialog");
          button = SWTTest::Button.new(@shell, SWTTest::SWT::PUSH)
          button.setText("Test Button 1")    
          button.setBounds(147, 116, 48, 22);
      end
    end
  class TestMain
      def run shell
          TestDialog.new shell
      end
  end
  TestMain.new

在JRuby代码的最下面有一个TestMain的类,主要是用于调用的~这一点是和其他的写法不同的!

至于它有多强大,就看大家怎么用了~而且java和JRuby是运行在同一个JVM之上的,它可以使用此JVM下的所有对象!



客户虐我千百遍,我待客户如初恋!

posted on 2008-03-07 09:20 阿南 阅读(1279) 评论(4)  编辑  收藏 所属分类: 个人原创

评论

# re: 使用JRuby为你的客户端助力 2008-03-07 11:00 dennis

hi,Jruby已经有GUI方面的DSL,封装了swing,可以“描述”界面咯。看看这个 http://www.alef1.org/jean/swiby/ 和这个 http://cheri.rubyforge.org/
  回复  更多评论    

# re: 使用JRuby为你的客户端助力 2008-03-07 12:55 魔域私服

  回复  更多评论    

# re: 使用JRuby为你的客户端助力 2008-03-07 14:17 阿南

JRuby对Swing的封装,不过我用的是SWT,而且主要是用它在于我的程序交互,更类似于Office的VBA的功能!
  回复  更多评论    

# re: 使用JRuby为你的客户端助力 2008-03-07 18:57 dennis

自己定义个DSL不是更爽?ruby搞这个是小case
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航: