On Sep 15, 2010, at 1:57 PM, Alan wrote:

> This looks a lot like what I would do - I'm afraid I don't have any
> brilliant insights for you. I do have a couple ways you could make
> this smaller, though:
> 
> - Instead of (atom ()) and convoluted swap! logic, what about (atom
> []) and (swap! shapes conj new-shape)?
> - Similarly don't use (list shape-name...), try [shape-name...]
> -- (defn render-shape [shape-name [x y w h] color])
> -- (render-shape 'rect (take 4 (repeatedly #(rand-int 400))) blue)
> 
> The last two combine to let you avoid writing rand-int so many times.


Thanks Alan. Using vectors instead of lists does clean things up a little. I've 
spent a lot of my life in other Lisps and so lists spring to mind first.

FYI below is a slightly nicer version that uses vectors and also adds line 
drawing. I didn't follow your other suggestions because I was interested in 
minimizing the tool, not the example.

I'd still be quite interested in any advise anyone has on minimizing the code 
for initializing/buffering the window (using only core, contrib, and built-in 
java libraries -- but maybe different built-in java libraries? I'm coming from 
Lisp, not from Java, and I'm not sure what's in there.)

Also, this would have a smaller impact but I'm curious about it: is there a way 
to treat method names as data and then make calls to them, as one can with 
clojure functions? Then I could pass things like fillRect, or map rect to 
fillRect, etc. This would make things slightly simpler here but be handy in 
other cases... but I don't see how to do it.

Thanks, -Lee

--------------
(def max-x 500)
(def max-y 500)
(def shapes (atom []))

(defn render-shape 
  [graphics [shape-name x y w h r g b a]]
    (.setColor graphics (java.awt.Color. r g b a)) 
    (case shape-name
      rect (.fillRect graphics x y w h)
      oval (.fillOval graphics x y w h)
      line (.drawLine graphics x y w h)))

(def panel 
  (let [jp (proxy [javax.swing.JPanel]
             []
             (getPreferredSize [] (java.awt.Dimension. max-x max-y))
             (paint [g] 
               (render-shape g ['rect 0 0 max-x max-y 255 255 255 255])
               (doall (map #(render-shape g %) @shapes))))]
    (doto (new javax.swing.JFrame "My graphics window")
      (.setSize max-x max-y)
      (.add jp)
      (.setVisible true))
    jp))

(defn draw-shape [& shape]
  "Adds a shape to the current drawing. The first argument should be one of 
the following symbols: rect, oval, or line. For rect or oval  this should
be followed by: x, y, width, height, red, green, blue, alpha. The x and y
coordinates specify the upper right corner. Color values (including alpha, 
which is opacity) should range from 0 to 255. For line the arguments are 
the remaining arguments are x-start, y-start, x-end, y-end, red, green, 
blue, alpha."
  (swap! shapes conj shape)
  (.paint panel (.getGraphics panel)))

;; test it out by drawing a bunch of shapes
(draw-shape 'rect 20 20 460 80 255 128 0 255)
(draw-shape 'oval 120 120 300 100 100 100 0 20)
(draw-shape 'oval 300 50 100 300 10 100 200 20)
(draw-shape 'line 0 0 500 500 255 0 0 255)






--
Lee Spector, Professor of Computer Science
School of Cognitive Science, Hampshire College
893 West Street, Amherst, MA 01002-3359
lspec...@hampshire.edu, http://hampshire.edu/lspector/
Phone: 413-559-5352, Fax: 413-559-5438

Check out Genetic Programming and Evolvable Machines:
http://www.springer.com/10710 - http://gpemjournal.blogspot.com/

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to