预言了两天,终于决定在我们的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下的所有对象!