scala/ScalaBook/chapter-06/graphics2.scala

import scala.swing._
import scala.swing.event._

object sketcher extends SimpleGUIApplication {
  def top = new MainFrame {
    val width = 500
    val height = 450
    var prevX = 0
    var prevY = 0
    var colorSpacing = (height - 56) / 7
    var dragging = false
    val BLACK = 0
    val RED = 1
    val GREEN = 2
    val BLUE = 3
    val CYAN = 4
    val MAGENTA = 5
    val YELLOW = 6
    var currentColor = BLACK
    var G2 : java.awt.Graphics2D = null
    title = "Curve Sketcher"  
    val canvas = new Panel {
      opaque = false
      preferredSize = (width, height)
      override def paintComponent(g: java.awt.Graphics) {
        val g2 = g.asInstanceOf[java.awt.Graphics2D]
        //
        g2.setColor(java.awt.Color.white)
        g2.fill(new java.awt.Rectangle(3, 3, width - 59, height - 6))
        g2.setColor(java.awt.Color.gray)
        g2.drawRect(0, 0, width - 1, height - 1)
        g2.drawRect(1, 1, width - 3, height - 3)
        g2.drawRect(2, 2, width - 5, height - 5)
        g2.fill(new java.awt.Rectangle(width - 56, 0, 56, height))
        //
        g2.setColor(java.awt.Color.white)
        g2.fill(new java.awt.Rectangle(width - 53, height - 53, 50, 50))
        g2.setColor(java.awt.Color.black)
        g2.drawRect(width - 53, height - 53, 49, 49)
        g2.drawString("CLEAR", width - 48, height - 23)
        // draw seven rectangles
        g2.setColor(java.awt.Color.black)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 0*colorSpacing, 50, colorSpacing-3))
        g2.setColor(java.awt.Color.red)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 1*colorSpacing, 50, colorSpacing-3))
        g2.setColor(java.awt.Color.green)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 2*colorSpacing, 50, colorSpacing-3))
        g2.setColor(java.awt.Color.blue)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 3*colorSpacing, 50, colorSpacing-3))
        g2.setColor(java.awt.Color.cyan)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 4*colorSpacing, 50, colorSpacing-3))
        g2.setColor(java.awt.Color.magenta)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 5*colorSpacing, 50, colorSpacing-3))
        g2.setColor(java.awt.Color.yellow)
        g2.fill(new java.awt.Rectangle(width - 53, 3 + 6*colorSpacing, 50, colorSpacing-3))
        // 
        g2.setColor(java.awt.Color.white)
        g2.drawRect(width-55, 1 + currentColor*colorSpacing, 53, colorSpacing)
        g2.drawRect(width-54, 2 + currentColor*colorSpacing, 51, colorSpacing - 2)
      } //paint
      //
      def changeColor(y: Int) {
        val newColor = y / colorSpacing
        if ( newColor >= 0 && newColor <= 6 ) {
          val g = peer.getGraphics()
          val g2 = g.asInstanceOf[java.awt.Graphics2D]
          g2.setColor(java.awt.Color.gray)
          g2.drawRect(width-55, 1 + currentColor*colorSpacing, 53, colorSpacing)
          g2.drawRect(width-54, 2 + currentColor*colorSpacing, 51, colorSpacing - 2)
          currentColor = newColor
          g2.setColor(java.awt.Color.white)
          g2.drawRect(width-55, 1 + currentColor*colorSpacing, 53, colorSpacing)
          g2.drawRect(width-54, 2 + currentColor*colorSpacing, 51, colorSpacing - 2)    
          g2.dispose()
        }
      }
      //
      def setUpDrawingGraphics {
        val g = peer.getGraphics()
        G2 = g.asInstanceOf[java.awt.Graphics2D]       
        G2.setColor(currentColor match {
          case BLACK   => java.awt.Color.black
          case RED     => java.awt.Color.red
          case GREEN   => java.awt.Color.green
          case BLUE    => java.awt.Color.blue
          case CYAN    => java.awt.Color.cyan
          case MAGENTA => java.awt.Color.magenta
          case YELLOW  => java.awt.Color.yellow })
      }
      listenTo(Mouse.clicks)
      reactions += {
        case MousePressed(_, p, _, _, _) => {
          var x = p.x
          var y = p.y
          if ( ! dragging ) {
            if ( x > width - 53 ) {
              if ( y > height - 53 )
                repaint    //  Clicked on "CLEAR button".
              else
                changeColor(y) // Clicked on the color palette.
            }
            else if (x > 3 && x < width - 56 && y > 3 && y < height - 3) {
                // The user has clicked on the white drawing area.
                // Start drawing a curve from the point (x,y).
              prevX = x
              prevY = y
              dragging = true
              setUpDrawingGraphics
            }
          } //if ( ! dragging ) 
        } //MousePressed
      }
      reactions += {
        case MouseReleased(_, p, _, _, _) => {
          if ( dragging ) {
            dragging = false
            G2.dispose()
            G2 = null
          }
        } // MouseReleased
      }
      listenTo(Mouse.moves)
      reactions += {
        case MouseDragged(_, p, _) => { 
          if ( dragging ) {
            var x = p.x
            var y = p.y
            if ( x < 3 )              // Adjust the value of x,
              x = 3                   //   to make sure it's in
            if ( x > width - 57 )     //   the drawing area.
              x = width - 57
            if ( y < 3 )               // Adjust the value of y,
              y = 3                    //   to make sure it's in
            if ( y > height - 4 )      //   the drawing area.
              y = height - 4
       
            G2.drawLine(prevX, prevY, x, y)  // Draw the line.

            prevX = x  // Get ready for the next line segment in the curve.
            prevY = y
          } //if ( dragging )
        } //MouseDragged
      }
    }
    contents = canvas
  }
}