         panel (proxy [JPanel clojure.lang.IReference] []
                 (paintComponent [^Graphics graphics]
                   (proxy-super paintComponent graphics)
-                   ; (println "draw" (now))
                   (paint/paint-buffered graphics
-                  #(try
-                     (draw % @reference)
-                    (catch Throwable e (draw-error % e)))))
+                    #(try
+                       (draw % @reference)
+                       (catch Throwable e (draw-error % e)))))
                 (alterMeta [alter args]
                   (apply swap! meta-atom alter args))
                 (resetMeta [m]
                   (reset! meta-atom m))
                 (meta []
                   @meta-atom))]
-    ;(.setDoubleBuffered panel true)
     (add-watch reference panel (fn [_ _ old-val new-val]
-                                 (swap! count-paints inc)
-                                 ;(println "count: " @count-paints)
-                                 ;(clojure.pprint/pprint new-val)
                                  (when (not= old-val new-val)
-                                   ;(println "repaint")
                                    (.repaint panel))))
     (alter-meta! panel assoc ::data-source reference)
     panel))

        mouse-adapter
        (proxy [MouseAdapter] []
          (mouseClicked [e] (run-mouse-actions e :mouse-click reference))
          (mousePressed [e] (activate-dragging! e reference canvas)
                            (run-mouse-actions e :mouse-down reference))
          (mouseReleased [e] (stop-dragging! canvas)
                             (run-mouse-actions e :mouse-up reference))
          (mouseMoved [e] (handle-mouse-move e reference canvas))
          (mouseDragged [e] 
                        (continue-dragging e canvas)
                        (handle-mouse-move e reference canvas)))]
    (doto canvas
      (.addMouseListener mouse-adapter)

    (fn [x y] ((widget action-type)
                 (- x offset-x) (- y offset-y)))))

(defn shapes-containing-point
  "Returns the shapes in data that contain the
   point [x y]."
  [[x y] data]
  (->> data
       (filter #(-> (.createTransformedShape
                       (% :transform) (% :shape))
                    (.contains x y)))))

(defn shape-by-action [action-type [x y] data]
  (->> data
       expand-memo
       (filter action-type)
       (shapes-containing-point [x y])))

(defn run-mouse-actions [e action-type reference]
  (let [x (.getX e) y (.getY e)]                    
    (doseq [shape (shape-by-action action-type [x y] @reference)]
      ((:action-type shape) x y))))

(defn mouse-is-over
  "Returns the shapes that contain the point [x y] and
   expect a hovering mouse."
  [[x y] data]
  (->> data
       expand-memo
       (remove #(empty? (select-keys % [:mouse-in :mouse-out])))
       (shapes-containing-point [x y])))

(defn handle-mouse-move [e reference canvas]
  ;(println "move" (now))
