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を使用しようとすると同様の問題が発生します。この例は部分的に機能します (「quit」アクションを取り上げます)。

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 に 2 番目のボタンを追加しました。

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

しかし、追加の 'action1' メソッドは swixml には表示されないようです。アプリケーションを開始 (および終了) すると、次の出力が得られます。

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 (など) を使用して簡単な SWING アプリをすばやくまとめることができれば素晴らしいことです。しかし、これを行う方法の作業テンプレートが必要だと思います。

説明できないもう1つの奇妙なこと。'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

見る?悪くない。私の場合、 "submit" は<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 インターフェイスを実装するにはどうすればよいですか?という見出しのあるセクションまでスクロールします。

find()XML ファイルで ID が定義されている限り、任意の要素 (私の知る限り) を SwingEngine クラスのメソッドで取得できます。

いくつかのマイナーなこと:include_class現在は非推奨です。java_import代わりに使用する必要があります。また、SwingEngine に渡すクラスは、継承する必要はありませんObject。JRuby は、Java との統合時に物事をより「ルビーに似た」ものにすることに関して、はるかに優れています。

お役に立てれば。この件についてはあまり情報がありません。

PS このリンクから「手動バインディング」に関する情報を見つけました: http://www.mail-archive.com/forum@carlsbadcubes.com/msg00062.html

于 2012-01-13T20:11:48.227 に答える