Here's a proof-of-concept of running a Swing UI from Python on the CLR and the JVM, following up on earlier experiments (which I had forgotten about).
try:
# IronPython must load the J# redistributable libraries
# Using the FullName of the assemblies is probably overkill
import clr
clr.AddReference( 'vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' )
clr.AddReference( 'vjssupuilib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' )
except ImportError:
pass
import javax.swing
import java.awt.event
import java.lang
class Exit(java.awt.event.WindowAdapter):
def windowClosing(self, evt):
evt.getWindow().setVisible(False)
evt.getWindow().dispose()
def windowClosed(self, evt):
java.lang.System.exit(0)
# With the 'import's above, we can now refer to things that are part of the
# standard Java platform via their full paths.
frame = javax.swing.JFrame("Window") # Creating a Java JFrame.
label = javax.swing.JLabel("Hello")
# We can transparently call Java methods on Java objects, just as if they were defined in Python.
frame.getContentPane().add(label) # Invoking the Java method 'getContentPane'.
frame.addWindowListener(Exit()) # Need to do this for IronPython/J# which is barely JDK 1.2 level
frame.pack()
frame.setVisible(True)
which works happily with java -jar jython-complete.jar HelloSwing.py using Jython 2.5β0 and with ipy.exe HelloSwing.py for IronPython2.0RC2 as well.
I was briefly conflicted earlier this week when I saw that IronRuby had reached α2, and wondered about a JRuby/IronRuby UI, but the nigh-equivalent
begin
require 'vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
require 'vjssupuilib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
rescue LoadError
# This is the 'magical Java require line'.
require 'java'
end
class Exit < java.awt.event.WindowAdapter
def windowClosing evt
evt.getWindow.setVisible(false)
evt.getWindow.dispose # make Closed
end
def windowClosed evt
java.lang.System.exit 0
end
end
# With the 'require' above, we can now refer to things that are part of the
# standard Java platform via their full paths.
frame = javax.swing.JFrame.new("Window") # Creating a Java JFrame.
label = javax.swing.JLabel.new("Hello")
# We can transparently call Java methods on Java objects, just as if they were defined in Ruby.
frame.getContentPane.add(label) # Invoking the Java method 'getContentPane'.
frame.addWindowListener(Exit.new()) # Need to do this for IronRuby/J# which is barely JDK 1.2 level
frame.pack
frame.setVisible(true)
which works on JRuby 1.1.5, fails in IronRuby α2 when trying to load Swing classes, and I've not found a dodge that will get me at even class metadata for the Swing files. Ruby's casing rules may make it impossible for IronRuby to recognise the lower-case Java namespaces (I had fun with that earlier with Ruby.Net).
LATER: I could do something VM dependent that takes the class name and argument list for construction in {Iron|J}Ruby. What is more tricky is inheritance like
class Exit < java.awt.event.WindowAdapter
which is a major use-case. I wonder if there might be a metaprogramming technique I can use for this...
LATER YET: The problem is that there is no exposed mechanism to wrap a System.Type as a Ruby Class; I could manually subclass everything that is not final that I want in a C# assembly with a My.JavaNamespace and emulate the way that JRuby maps namespace Java::JavaAwtEvent to a value named java.awt.event, but the nearest to automation I can see is to Reflection.Emit a whole ton of stuff.
So, for the moment, consider it a dead end.

