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.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs