Multi-threaded Jython applet


Above is a port of the ParticleApplet from section 1.1.1 of Concurrent Programming in Java by Doug Lea from Java to Jython. The full code listing is shown below.

A few interesting points here:

  • I have removed all attempts at thread exclusion since Python doesn’t offer language-level support. Despite the absense of a synchronized keyword or any explicit monitor locking the applet seems to run just fine. (or at least as fine as any applet ;)) That’s because the synchronization (or lack of it) in the example will not actually affect the applet running… but will determine where the individual particles are drawn. A difference that would not be detectable to human eyes.
  • Notice the use of a nested class definition to emulate an anonymous Java class. In this case, it’s an implementation of the java.lang.Runnable interface that will be passed to my Thread instance. This seems to work very well… and the inner class has access to the enclosing class’ members! Do people do this in Python? Seems a shame to miss out on when it works so beautifully. The only kludge is the use of the variable name this rather than self in one instance. This is done to prevent hiding the enclosing class’ member variables.
  • I had to import the nested_scopes feature from the future as Jython is stuck at roughly Python 2.1 — If you haven’t heard of Python, it’s a C port of the Java scripting language, Jython ;)
  • Compiling the applet’s jar (even with the Jython dependencies included) under Java 1.5 was causing the applet to die on machines with an eariler VM. I set my default JDK back to 1.4, re-archived the jar, and redeployed… now everyone was happy. This doesn’t happen with normal applets. Looks like you have to shoot for a lowest common denominator JVM when creating Jython applets. I know there are just scores of developers out there dying to release Jython-applet based web applications… Applets are uber-lame, but they do offer a unique method of easily displaying to anyone the results of a coding session in Java or Jython.

from __future__ import nested_scopes
import java.lang as lang
import java.util as util
import java.awt as awt
import javax.swing as swing

class Particle:

    def __init__(self,initX,initY):
        self.x = initX
        self.y = initY
        self.rng = util.Random()

    def move(self):
        self.x += self.rng.nextInt(10) - 5
        self.y += self.rng.nextInt(20) - 10

    def draw(self,g2):
        g2.drawRect(self.x,self.y,10,10)

class ParticleCanvas(awt.Canvas):

    def __init__(self,newSize):
        awt.Canvas.__init__(self,size=(newSize,newSize))

    def paint(self,g2):
        for p in self.particles:
            p.draw(g2)

class ParticleApplet(swing.JApplet):

    def init(self):
        self.canvas = ParticleCanvas(self.getWidth())
        self.contentPane.add(self.canvas)

    def start(self):
        n = 10
        particles = []
        for i in range(n):
            particles.append(Particle(150,150))
        self.canvas.particles = particles

        self.threads = []
        for i in range(n):
            self.threads.append(self.makeThread(particles[i]))
            self.threads[i].start()

    def makeThread(self,p):

        class MyRunnable(lang.Runnable):
            def run(this):
                try:
                    while 1:
                        p.move()
                        self.canvas.repaint()
                        lang.Thread.sleep(100)
                except lang.InterruptedException:
                    return

        return lang.Thread(MyRunnable())


About this entry