JRuby
java interfaces
JRuby classes can mixin Java interfaces as modules in order to implement them.
class SomeFlexibleClass
include java.lang.Runnable
include java.lang.Comparable
end
JRuby does a wonderful thing with Ruby’s blocks, where a block can be converted to the appropriate Java interface. It works by converting the block to a Proc, and then decorating it with a proxy object that runs the block for any method called on the interface. Runnable is the prime example here. You should try this yourself, also see using callbacks hype library examples for more sophisticated stuff.
button = javax.swing.JButton.new "Press me!"
button.add_action_listener { |event| event.source.text = "I done been pressed." }
Read more about java interface etc. Otherwise see wiki
java reflection
In vanilla processing, you can create libraries in java that can access the sketch pre
, draw
, post
, mouseEvent
and keyEvent
methods by java reflection, but you must register
these methods with the PApplet
. We can also register custom methods (but sadly only those without parameters, which is why we found another way of dealing with selectInput
see chooser, movieEvent
see video_event).
Here we show you how to registerMethods
in a ruby class by java reflection in JRuby (requires the !become_java
method).
#!/usr/bin/env jruby
require 'propane'
require_relative 'register_send'
class ReflectionVoodoo < Propane::App
def settings
size 300, 200
# pixel_density(2) # for HiDpi screens
# smooth # see https://processing.org/reference/smooth_.html
end
def setup
sketch_title 'Reflection Voodoo'
RegisterSend.new self
no_loop
end
def draw
fill 0, 0, 200
ellipse(170, 115, 70, 100)
end
end
ReflectionVoodoo.new
Here is the class that does the reflection (it needs to become java so that self gets recognized as a java object)
require 'jruby/core_ext' # required to add become_java! method
# This class demonstrates how to use 'reflection' methods in ruby-processing
# NB: the class must become a java object to get registered. This is an
# advanced feature in vanilla processing, mainly used by libraries.
class RegisterSend
attr_reader :parent
def initialize(parent)
@parent = parent
parent.java_send :registerMethod, [java.lang.String, java.lang.Object], :draw, self
parent.java_send :registerMethod, [java.lang.String, java.lang.Object], :pre, self
end
def pre
puts 'before draw'
parent.background(100)
end
def draw
puts 'at begin draw...'
parent.fill(200, 100)
parent.ellipse(150, 100, 200, 60)
end
# putting become_java! here works OK
become_java!
end
Note how the transparent ellipse is placed on top of the solid ellipse, so the reflection element must get drawn after the original sketch element.
Java Extensions for JRuby
JRuby is a 100% Java implementation of the Ruby programming language. It is Ruby for the JVM. So it is quite possible to write your own ruby code in java, you might do this to better integrate jruby with java or to write your own ruby classes (modules etc) in java see Method Signatures and Annotations in JRuby extensions and jruby-examples.