views:

82

answers:

1

I've been trying for hours to get my drawing method to work by drawing in a BufferedImage stored in a Clojure ref, and then to have that painted onto the component (in this case a JPanel) in order to display it. Unfortunately, this isn't working well at all.

My code is this (pared down, but showing the relevant parts:

(defn create-graph
  "Data-ref is [xs ys], buffered-image-ref holds the basic graph."
  [data-ref buffered-image-ref & {:keys [width height image]}]
  (proxy [JPanel]
      []
    (getPreferredSize [] (Dimension. width  height))
    (paintComponent [g]
                    (proxy-super paintComponent g)
                    (if-not @buffered-image-ref
                      (dosync
                       (ref-set buffered-image-ref
                                (xy-plot2
                                 (first @data-ref)
                                 (second @data-ref)
                                 (.getGraphics
                                  (BufferedImage. width height 
                                                  BufferedImage/TYPE_INT_ARGB))
                                 :axis? true
                                 :width width
                                 :height height))))
                    (.drawImage g @buffered-image-ref
                                0 0 
                                (proxy [ImageObserver]
                                         []
                                       (imageUpdate []
                                          (proxy-super imageUpdate)))))))

And, below, xy-plot2 (which doesn't appear to be the problem, but I'll include it for completeness:

(defn xy-plot2
  "Draws an xy-plot in the given Graphics context.
   'xs must be equal in length to 'ys."
  [xs ys gfx
   & {:keys [color max-y axis? y-buffer width height]
     :or {color Color/RED y-buffer 0}}]
  (let [h (/ height 2) ;; since we have -h to h (not 0 to h)
        w width ;; since we graph 0 to w
        len (count xs)
        min-x (apply min xs)
        xs (if-not (zero? min-x)
             (map #(- % min-x) xs)
             xs)
        max-y (or max-y (apply max ys))
        max-x (apply max xs)]
    (.setColor gfx color)
    (dorun ;; this is the key part, along with scale-xs and draw-l
     (take len
           (iterate (partial d-line gfx h)
                    [(scale-xs xs w 0)
                     (scale-xs ys h y-buffer)])))
    (and axis? (or (.setColor gfx Color/BLACK) (.drawLine gfx 0 h w h)))
    gfx))

When I run this, I get this error, which leads to to believe I've messed up in the last part of the paintComponent() method.

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException:
No matching method found: drawImage for class sun.java2d.SunGraphics2D

I've tried substituting nil for the ImageObserver, but to no avail. I've tried other arg orders (for other drawImage methods for other types of Graphics classes). All to no avail.

Sorry if I'm sounding a bit hard to understand, this bug's been plaguing me. I'll edit in the morning, if need be!

Thank you so, so much, Isaac

+3  A: 

It looks like buffered-image-ref is set to the graphics of the BufferedImage, not the image itself.

Nick Main
That was it. Good god. Is there a medicine to help this? Also, you one of those who wanted the cookies offered? :) Thanks so much, I have bad code reviewing skills apparently.
Isaac Hodes