scala/ScalaBook/chapter-07/pulse2.scala

import scala.swing._
import event._

class Pulse extends Applet {
  object ui extends UI with Reactor with Runnable {    
    var dotAx                              = 15 
    var dotAy                              = 15
    var dotBx                              = 400 
    var dotBy                              = 15
    var T : Thread                         = null
    var currentX                           = 0
    var currentY                           = 15
    var canvas : Panel                     = null
    var dir                                = 1
    var interval                           = 10
    var lock                               = new AnyRef
    var offscreenImage : java.awt.Image    = null
    var offscreenGraph : java.awt.Graphics = null
    var appletDim : java.awt.Dimension     = null
    var appletInsets : java.awt.Insets     = null

    override def init() = {
      canvas = new Panel {
        preferredSize = (dotAx+30,dotBx+30)
        opaque        = false
        override def paintComponent(g: java.awt.Graphics) {
          offscreenGraph.setColor(getBackground()) 
          offscreenGraph.fillRect(0,0,appletDim.width,appletDim.height)

          offscreenGraph.setColor(java.awt.Color.black)
          offscreenGraph.drawLine(dotAx,dotAy,dotBx,dotBy)
          offscreenGraph.setColor(java.awt.Color.yellow)
          offscreenGraph.fillOval(currentX,currentY-7,30,30)

          g.drawImage(offscreenImage,0,0,null)
          lock.synchronized {
            lock.notifyAll
          }
        }
      }
      contents       = canvas
      appletDim      = getSize()
      appletInsets   = getInsets()
      // Create the offscreen image and graphics context 
      offscreenImage = createImage(appletDim.width,appletDim.height)
      offscreenGraph = offscreenImage.getGraphics()
    }

    override def start() = {
      if (T == null) {
        T = new Thread(this)
        T.start()
      }
    }  

    override def stop() = {
      if (T != null)
        T = null
    }

    override def run(): Unit = 
       lock.synchronized {
         while ( T != null ) {
           if (currentX == 0)
             dir = 1
           else if (currentX == dotBx)
             dir = -1 
           canvas.repaint
           currentX += dir * interval 
           try {
             lock.wait 
             Thread.sleep(10) 
           } catch {
              case ex : InterruptedException => return
           } // catch
         } // while 
      } // lock..synchronized
  } // ui
}