Skip to content

Instantly share code, notes, and snippets.

@lygaret
Created July 8, 2010 04:54
Show Gist options
  • Save lygaret/467653 to your computer and use it in GitHub Desktop.
Save lygaret/467653 to your computer and use it in GitHub Desktop.
attempt at easy swing graphics in cloj
(ns typoet.graphix
(:import [javax.swing JFrame])
(:import [java.awt Dimension Canvas])
(:import [java.awt.event WindowAdapter KeyAdapter MouseAdapter MouseMotionAdapter])
(:use [clojure.contrib.seq-utils]))
(defstruct window :height :width :title :frame :canvas :handlers)
(defn- get-handlers
[window key]
((get window :handlers) key []))
(defn add-handler
[window key handler]
(dosync
(let [handler-ref (get window :handlers)
orighandlers (get @handler-ref key [])
newhandlers (conj orighandlers handler)]
(alter handler-ref assoc key newhandlers))))
(defn- proxy-event
[window event & args]
(let [handlers (get-handlers window event)]
(doall (take-while (fn [handler] (true? (apply handler args))) handlers))))
(defn- get-time
[]
(/ (System/nanoTime) 1000000))
(defn- event-loop
[window]
(loop [last-time (get-time)]
(let [curr-time (get-time)
delta (- curr-time last-time)]
(proxy-event window :ontick delta (get window :canvas))
(Thread/sleep 100)
(recur curr-time))))
(defn create-window
"Create a window/canvas to draw on, and return it."
[title width height]
(let [frame (JFrame. title)
canvas (Canvas.)
panel (doto (.getContentPane frame)
(.setPreferredSize (Dimension. width height))
(.setLayout nil)
(.add canvas))
window (struct window height width title frame canvas (ref {}))]
(doto frame
(.addWindowListener (proxy [WindowAdapter] []
(windowClosing [e] (proxy-event window :onclose e))))
(.setResizable false)
(.pack))
(doto canvas
(.addKeyListener (proxy [KeyAdapter] []
(keyPressed [e] (proxy-event window :onkeypress e))))
(.addMouseListener (proxy [MouseAdapter] []
(mouseClicked [e] (proxy-event window :onmouseclick e))))
(.addMouseMotionListener (proxy [MouseMotionAdapter] []
(mouseMoved [e] (proxy-event window :onmousemove e))
(mouseDragged [e] (proxy-event window :onmousedrag e))))
(.setBounds 0 0 width height)
(.setIgnoreRepaint true)
(.createBufferStrategy 2))
window))
(defn start-window
"Show the window, and start the painting/event loop, at the given FPS (try to get as close as possible."
[window fps]
(let [looper (agent window)]
(.setVisible (get window :frame) true)
(send-off looper event-loop)))
(defn my-test []
(let [w (create-window "test" 640 480)]
(add-handler w :ontick (fn [delta canvas] (println delta)))
(start-window w 1)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment