Forum: JRuby How to truly replace java methods using jruby?

Posted by Christian MICHON (Guest)
on 2013-01-02 17:25
(Received via mailing list)
Hi,

I've been looking at the code (java+ruby) of jirb_swing: at first
glance, if I wish to emulate ansi color escape sequences to get colors
in the JTextPane, it seems I could do so by overwriting
Java::JavaxSwingText::DefaultStyledDocument#insertString

I'm trying to intercept the strings sent from jruby/jirb, detect any
ansi escape sequence, and use a proper SimpleAttributeSet to emulate
the colors. This seemed the right thing to do, as I wish not to
rewrite a complete TextAreaReadline or jirb_swing.

But all my attempts in overwriting
Java::JavaxSwingText::DefaultStyledDocument#insertString failed. I've
used for example this simple snippet I inserted before invocation of
org.jruby.demo.TextAreaReadline in jirb_swing:

class Java::JavaxSwingText::DefaultStyledDocument
  def insertString(offset,string,attributeset)
    puts 'bla'
    super(offset,string,attributeset)
  end
end

Can this be done? I've been trying to alias java methods, it did not 
work.

Thanks in advance.

--
Christian
Posted by Keith B. (keith_b)
on 2013-01-02 18:22
(Received via mailing list)
Christian -

If I understand correctly, the approach you're taking won't work.  I'm 
pretty sure that when you monkey patch a Java class in JRuby, and then 
instantiate the class on the Java side, the Ruby class modifications 
will be invisible.

If you can find a way to instantiate the object containing the monkey 
patched insertString function on the Ruby side, it might work.  For 
example, something like this:

class AnsiEnabledTextDocument < javax.swing.text.Document
  def insertString  # must use the Java camel case name so it will be 
called by Java

  end
end

class AnsiEnabledTextField < javax.swing.JTextField
  def initialize(*args)
    super
    # original document may have been initialized with text, so copy it 
to new document
    self.document = AnsiEnabledTextDocument.new(document.text)
  end
end

Then, use the AnsiEnabledTextField wherever you would normally use a 
JTextField.

You might want to do this for JTextArea as well.

- Keith

---
Keith R. Bennett
http://about.me/keithrbennett
Posted by Keith B. (keith_b)
on 2013-01-02 18:52
(Received via mailing list)
Sorry, I should have said to subclass JTextPane, and not JTextField or 
JTextArea.

Also, my example was rough and unused/untested code.  For example, the 
insertString function would of course need to take a String parameter.

- Keith
Posted by Christian MICHON (Guest)
on 2013-01-02 20:46
(Received via mailing list)
On Jan 2, 2013 6:22 PM, "Keith Bennett" <keithrbennett@gmail.com> wrote:
>
> Christian -
>
> If I understand correctly, the approach you're taking won't work.  I'm
pretty sure that when you monkey patch a Java class in JRuby, and then
instantiate the class on the Java side, the Ruby class modifications 
will
be invisible.

Ouch... I should have guessed.

>
> If you can find a way to instantiate the object containing the monkey
patched insertString function on the Ruby side, it might work.  For
example, something like this:
>
> class AnsiEnabledTextDocument < javax.swing.text.Document
>   def insertString  # must use the Java camel case name so it will be
called by Java
>
>   end
> end
>
> class AnsiEnabledTextField < javax.swing.JTextField
>   def initialize(*args)
>     super
>     # original document may have been initialized with text, so copy it
to new document
>     self.document = AnsiEnabledTextDocument.new(document.text)
>   end
> end
>
> Then, use the AnsiEnabledTextField wherever you would normally use a
JTextField.
>
> You might want to do this for JTextArea as well.

If I choose this path, I may as well recode what was in the ruby.jar (in
demo) and make it a pure jruby/swing app.

Thanks!

Christian

>
> - Keith
>
> ---
> Keith R. Bennett
> http://about.me/keithrbennett
>
> On Jan 2, 2013, at 11:24 AM, Christian MICHON <christian.michon@gmail.com>
wrote:
> > the colors. This seemed the right thing to do, as I wish not to
> >    super(offset,string,attributeset)
> >  end
> > end
> >
> > Can this be done? I've been trying to alias java methods, it did not
work.
Posted by Christian MICHON (Guest)
on 2013-01-02 20:49
(Received via mailing list)
On Jan 2, 2013 6:51 PM, "Keith Bennett" <keithrbennett@gmail.com> wrote:
>
> Sorry, I should have said to subclass JTextPane, and not JTextField or
JTextArea.
>
> Also, my example was rough and unused/untested code.  For example, the
insertString function would of course need to take a String parameter.
>
> - Keith

Thanks. I actually did a full reverse on the jar part I was looking for.

Christian

>
> On Jan 2, 2013, at 12:21 PM, Keith Bennett <keithrbennett@gmail.com>
wrote:
>
> > Christian -
> >
> > If I understand correctly, the approach you're taking won't work.  I'm
pretty sure that when you monkey patch a Java class in JRuby, and then
instantiate the class on the Java side, the Ruby class modifications 
will
be invisible.
> >
> > If you can find a way to instantiate the object containing the monkey
patched insertString function on the Ruby side, it might work.  For
example, something like this:
> >
> > class AnsiEnabledTextDocument < javax.swing.text.Document
> >  def insertString  # must use the Java camel case name so it will be
called by Java
> >
> >  end
> > end
> >
> > class AnsiEnabledTextField < javax.swing.JTextField
> >  def initialize(*args)
> >    super
> >    # original document may have been initialized with text, so copy it
to new document
> >    self.document = AnsiEnabledTextDocument.new(document.text)
> >  end
> > end
> >
> > Then, use the AnsiEnabledTextField wherever you would normally use a
JTextField.
> >
> > You might want to do this for JTextArea as well.
> >
> > - Keith
> >
> > ---
> > Keith R. Bennett
> > http://about.me/keithrbennett
> >
> > On Jan 2, 2013, at 11:24 AM, Christian MICHON <
christian.michon@gmail.com> wrote:
> >> the colors. This seemed the right thing to do, as I wish not to
> >>   super(offset,string,attributeset)
> >> end
> >> end
> >>
> >> Can this be done? I've been trying to alias java methods, it did not
work.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.