2

我正在尝试在 JRuby 中重新创建 SwiXML 示例。但是在 JRuby 中创建的对象似乎对 SwiXML 是不可见的。这是一个例子。

<frame size="200,200" title="Action Test">
  <menubar>
    <menu text="File">
      <menuitem action="quit" accelerator="meta X" />
    </menu>
  </menubar>
  <button action="quit" text="A Quit Button"
  ToolTipText="This is a quit button." />
</frame>

SwiXML 示例中的 Java 代码如下:

public class ActionTest {
  // Create an Action as a member variable
  public Action quit = new AbstractAction() {
    public void actionPerformed(ActionEvent evt) {
      System.exit(0);
    }
  };
  public ActionTest() throws Exception {
    // set the Action's name
    quit.putValue(Action.NAME, "Quit");
    // build the GUI
    new SwingEngine(this).render("ActionTest.xml")
    .setVisible(true);
  }
  public static void main(String[] args) throws Exception {
    new ActionTest();
  }
}

我创建了一些与此相对应的 JRuby 代码,但似乎从未见过 @quit 成员。还尝试引用其他命名元素(不在此示例中):

require 'java'
require 'java/swixml.jar'
require 'java/jdom.jar'

include_class 'javax.swing.AbstractAction'
include_class 'javax.swing.Action'
include_class 'javax.swing.JButton'

class MyAction < AbstractAction
  def actionPerformed(ae)
    exit # puts "Clicked"
  end
end

class Main < Object # Java::JavaLang::Object
  def initialize
    @quit = MyAction.new
    @quit.putValue(Action.NAME, "Quit")
    @f = java.io.File.new("sample.xml")
    @se = org.swixml.SwingEngine.new(self).render(@f).setVisible(true)
  end
end

Main.new
4

2 回答 2

0

我在这里没有你的答案(我的 Ruby 不够好)——但我在这里尝试使用 Jython 时遇到了类似的问题;这个例子部分有效(它选择了“退出”动作)。

from org.swixml.jsr296 import SwingApplication
from org.jdesktop.application import Application
from javax.swing import JButton, JFrame

class MyFrame(JFrame):
    def __init__(self):
        pass

class Tester(SwingApplication):
    def __init__(self):
        self.frame=MyFrame()
        #self.frame=JFrame()

    def startup(self):
        print "Application Started"
        self.render(self.frame,"frame.xml").show()

    def shutdown(self):
        print "Application Shutdown"


    #def quit(self,evt):
    #   print "Over-ridden quit"

    def action1(self,evt):
        print "action1"

if __name__=='__main__':
     Application.launch(Tester,None)

我在 XML 中添加了第二个按钮,如下所示:

<button action="action1" text="action1" ToolTipText="action1" />

但是 swixml 似乎从未见过额外的“action1”方法,当我启动(然后退出)应用程序时,我得到以下输出:

Application Started
SwixML 2.5
11-Nov-2011 12:10:38 org.swixml.XAction <init>
WARNING: error on Action initialization [org.python.proxies.__main__$MyFrame$1.action1()]
Application Shutdown

有趣的是,如果您取消注释 'def quit(self,evt)' 方法;这个方法被 SXIWML 看到了;并且“退出”按钮的行为从关闭应用程序变为打印出消息。

因此,当操作完全在 Jython(方法签名?)中定义时,SWIXML 反映查找操作的方式似乎失败了:但是覆盖现有操作方法确实有效。

很高兴看到这里发生了什么——我可能会在这个例子中记录一个新的 StackOverFlow 问题并参考这个问题。

能够使用 SWIXMl 使用 JRuby / Jython (etc) 快速将简单的 SWING 应用程序组合在一起会很棒;但我认为需要一个如何做到这一点的工作模板。

另一件我无法解释的奇怪事情;如果将“self.frame=MyFrame()”行更改为实例化标准 JFrame:“self.frame.JFrame()” - 这会导致类加载器错误:

SwixML 2.5
11-Nov-2011 12:19:14 org.swixml.XAction <init>
WARNING: error on Action initialization [null ClassLoader]
11-Nov-2011 12:19:14 org.swixml.XAction <init>
WARNING: error on Action initialization [null ClassLoader]
11-Nov-2011 12:19:14 org.swixml.XAction <init>
WARNING: error on Action initialization [null ClassLoader]
于 2011-11-10T13:12:46.817 回答
0

本周我一直在努力整合 JRuby 和 SwiXml。我得出的结论是,您不能让 SwiXml 自动从 XML 绑定您的变量/操作。(我认为这是因为在 Java 中变量已经存在,而在 JRuby 中它们是“即时”创建的,所以 SwiXml 不确定该怎么做。无论如何,在对源代码进行数小时挖掘之后,这就是我的结论. JRuby 对我来说相当新,所以更高级的人可能会告诉我为什么这不起作用。)

解决方案是在 JRuby 代码中简单地手动绑定它们。这实际上相当容易,因为这是 Ruby。

include Java
java_import 'org.swixml.SwingEngine'

class HelloWorld

  def initialize
    @swix = SwingEngine.new(self)
    @swix.render("xml/helloworld.xml")
    btn = @swix.find("submit")
    btn.add_action_listener { |event| btn.text = 'Hi' }
  end

  def run
    @swix.getRootComponent.setVisible(true)
  end

end

看?还不错。在我的例子中,“提交”被定义为<button>的 ID 属性。因此,在我的 XML 文件中,我<button text="Click Here" id="submit" />将 find() 方法视为 findById() 方法(如果您熟悉通过 JavaScript 进行的 DOM 操作......)。

请注意,由于add_action_listener需要一个块,因此可以将实例变量(ivars)包含在块中(换句话说,它的行为就像您期望 Java 匿名类/块工作一样)。还有其他方法可以实现/添加动作监听器。请参阅此页面:https ://github.com/jruby/jruby/wiki/FAQs并向下滚动到标题为如何使用 Ruby 类实现 Java 接口的部分?

任何元素(据我所知)都可以通过 SwingEngine 类的find()方法检索,只要它的 id 在 XML 文件中定义。

一些小事:include_class现在已弃用。你应该java_import改用。此外,您传递给 SwingEngine 的类不需要继承自Object或类似的东西。在与 Java 集成时,JRuby 在使事情更“像 ruby​​”方面做得更好。

希望这可以帮助。关于这些东西的信息并不多。

PS我从这个链接中找到了关于“手动绑定”的信息:http: //www.mail-archive.com/forum@carlsbadcubes.com/msg00062.html

于 2012-01-13T20:11:48.227 回答