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