I think you may have misunderstood the first suggestion I made, about keeping (shape, color) pairs in your atomic vector. I really meant java.awt.Shape and java.awt.Color objects, rather than a symbol (keyword is better as Christophe suggests) and a bunch of numbers. Like so: (defn render-shape [g shape color] (doto g (.setColor color) (.fill shape)))
(draw-shape (Rectangle. 50 50 200 100) (Color. 0 0 255 75)) Java already has the "multi-method" Christophe suggests, in the form of Graphics.fill(Shape); you don't have to implement it yourself. On Sep 15, 8:15 pm, Lee Spector <lspec...@hampshire.edu> wrote: > 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