How to truly replace java methods using jruby?

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

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

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

On Jan 2, 2013 6:22 PM, “Keith B.” [email protected] 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 [email protected]
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.

On Jan 2, 2013 6:51 PM, “Keith B.” [email protected] 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 B. [email protected]
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 <
[email protected]> 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.