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.

On Sep 15, 5:32 am, Lee Spector <lspec...@hampshire.edu> wrote:
> On Sep 14, 2010, at 4:59 PM, Alan wrote:
>
> > I think you could just keep a vector of (color,shape) pairs as an
> > atom, and reify a subclass of JPanel whose paint() method closes
> > around that atom, calling (.draw shape color). Then as long as you
> > call repaint every time you modify the atom, you should be done. Seems
> > like it's hard to see a library making this much easier, as there's
> > not much incidental complexity to begin with. And alpha will be
> > trivial, since java.awt.Color supports alpha values - you won't even
> > have to know about it.
>
> Thanks Alan. Following is one of my current versions, which does something 
> similar to what you suggest, although it differs in some details. It also 
> differs somewhat from what I originally requested insofar as it just sticks 
> size limits and the panel object in vars, rather than allowing them to be set 
> dynamically in a window-creating function call (although that could easily be 
> fixed in various ways). It also has a single draw-shape function that takes a 
> shape name as its first arg, rather than having separate functions for 
> rectangles and ovals -- just because that also made things a little more 
> concise. And I haven't added line-drawing to this yet. All of this could be 
> fixed easily, but I think that this is enough for me to ask my question about 
> minimality more concretely.
>
> The code below is still more than I would like, and I'm wondering if there's 
> a more concise way to do this (again, without additional libraries). One way 
> to reframe my question is to imagine that you're in front of a class (as I 
> will be in a couple of hours :-), and you want to say "And here's how you can 
> draw a circle in a graphics window..." and (for pedagogical reasons into 
> which I won't digress here) you don't want to use any additional libraries or 
> open a file with pre-written code that does magic that you haven't explained. 
> You want to start with an empty file and literally type in the code needed to 
> draw shapes, from scratch. You want to provide functionality sufficient to do 
> the kind or random-shape-drawing example that I have at the bottom of the 
> code. How little code can you get away with writing to do this?
>
> The sources of "more code than I would like" in my code below include:
>
> - All that stuff in the initialization value of my panel var. Is that really 
> the simplest way to create a graphics window and store the reference that 
> allows me to draw to it?
>
> - The code to store and redraw all of my shapes. I know I could clean up my 
> representation a bit (and probably will do so to add lines, since they will 
> have a different number of parameters), but is there some different kind of 
> java graphics canvas that buffers automatically so that I don't have to do 
> this explicitly myself?
>
> - The "case" in render-shape, which is there because the various more concise 
> approaches that I thought of all founder on the fact that I can't seem to 
> treat methods like functions, passing them and applying them, etc. Is there a 
> more elegant approach to this?
>
> Any advice would be appreciated.
>
> Thanks!
>
> ;;; simple shape drawing code
>
> (def max-x 500)
> (def max-y 500)
> (def shapes (atom ()))
>
> (defn render-shape [g [shape-name x y h w color]]
>   (.setColor g color)
>   (case shape-name
>     rect (.fillRect g x y h w)
>     oval (.fillOval g x y h w)))
>
> (def panel
>   (let [jp (proxy [javax.swing.JPanel]
>              []
>              (getPreferredSize [] (java.awt.Dimension. max-x max-y))
>              (paint [g] (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-name x y h w color]
>   (swap! shapes concat (list (list shape-name x y h w color)))
>   (.paint panel (.getGraphics panel)))
>
> ;; test it out by drawing a bunch of random shapes
> (dotimes [_ 20]
>   (draw-shape (rand-nth '(rect oval))
>     (rand-int 400) (rand-int 200) (rand-int 400) (rand-int 400)
>     (new java.awt.Color
>       (rand-int 256) (rand-int 256) (rand-int 256) (rand-int 256))))
>
> --
> 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