Как вы связываете элементы с SwiXML в JRuby? - PullRequest
2 голосов
/ 28 февраля 2011

Я пытаюсь воссоздать примеры SwiXML в JRuby.Но объекты, созданные в 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>

Код Java из примера SwiXML выглядит следующим образом:

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

Ответы [ 2 ]

0 голосов
/ 14 января 2012

На этой неделе я боролся с интеграцией 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» определяется как атрибут ID <button>. Так что в моем XML-файле я <button text="Click Here" id="submit" /> думаю о методе find () как о методе findById () (если вы знакомы с манипулированием DOM с помощью JavaScript ...).

Обратите внимание, что поскольку add_action_listener принимает блок, переменные экземпляра (ivars) могут быть включены в блок (другими словами, он действует так, как если бы вы ожидали, что анонимный класс / блок Java будет работать). Есть и другие способы реализации / добавления прослушивателя действий. См. Эту страницу: https://github.com/jruby/jruby/wiki/FAQs и прокрутите вниз до раздела с заголовком Как реализовать интерфейс Java с использованием класса Ruby?

Любой элемент (насколько мне известно) может быть извлечен методом find() класса SwingEngine, если его идентификатор определен в файле XML.

Несколько мелких вещей: include_class устарела. Вы должны использовать java_import вместо этого. Кроме того, ваш класс, который вы передаете SwingEngine, не должен наследоваться от Object или чего-то подобного. JRuby становится намного лучше, делая вещи более похожими на ruby ​​при интеграции с Java.

Надеюсь, это поможет. Там не так много информации об этом материале.

P.S. Я нашел информацию о «привязке вручную» по этой ссылке: http://www.mail-archive.com/forum@carlsbadcubes.com/msg00062.html

0 голосов
/ 10 ноября 2011

У меня нет вашего ответа здесь (мой 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 следующим образом:

<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;и поведение кнопки «выйти» меняется с выключения приложения на печать сообщения.

Так что кажется, что что-то в том, как SWIXML отражает поиск действий, не выполняется, когда действие чисто определено в Jython(Подпись метода?): Но переопределение существующего метода действия работает.

Было бы очень приятно увидеть, что здесь происходит - я мог бы записать новый вопрос StackOverFlow в этом примере и сослаться на этот.

Было бы замечательно иметь возможность быстро собрать простые приложения SWING, используя JRuby / Jython (и т. Д.), Используя SWIXMl;но я думаю, что нужен рабочий шаблон того, как это сделать.

Другая странная вещь, которую я не могу объяснить;если строка «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]
...