2010-06-05 Clojure Mouse Listener

Ok, so I got a bit further compared to last time. As you can see I got rid of that fancy macro and decided to just write simple code that works for this particular situation. And it works. 😄

last time

(import '(javax.swing JLabel JPanel JFrame ImageIcon)
	'(java.awt.event MouseListener)
        '(java.awt GridBagLayout GridBagConstraints))

(defn empty-tile []
  (JLabel. (ImageIcon. "empty.png")))

(defn floor-tile []
  (JLabel. (ImageIcon. "floor.png")))

(defn simple-grid [panel width height]
  "creates a grid of WIDTH + 1 columns and HEIGHT + 1 rows
where each cell contains the result of a call to (EMPTY-TILE)
and adds it to the PANEL"
  (let [c (GridBagConstraints.)]
    (loop [x 0 y 0]
      (set! (. c gridx) x)
      (set! (. c gridy) y)
      (. panel add (empty-tile) c)
      (cond (and (= x width) (= y height)) panel
	    (= y height) (recur (+ x 1) 0)
	    true (recur x (+ y 1))))))

(defn app []
  (let [frame (proxy
		  [JFrame MouseListener]
		  ["Grid Mapper"]
		(mouseClicked [e] (println e)))
	panel (doto (JPanel. (GridBagLayout.))
		(simple-grid 5 5))]
    (doto frame
      (.setContentPane panel)
      (.pack)
      ;; (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
      (.setVisible true))))

(app)

My problem right now is that the mouseClicked code is never called. I wonder why. ¹ ²

¹

²

It turns out that I needed to call addMouseListener at some place. So app changed:

(defn edit-grid [e]
  "placeholder"
  (println e))

(defn mouse-listener []
  "A mouse listener that will call EDIT-GRID when the mouse is clicked"
  (proxy [MouseListener] []
    (mouseClicked [e] (edit-grid e))
    (mouseEntered [e])
    (mouseExited [e])
    (mousePressed [e])
    (mouseReleased [e])))

(defn app []
  (let [frame (JFrame. "Grid Mapper")
	panel (doto (JPanel. (GridBagLayout.))
		(simple-grid 5 5))]
    (doto frame
      (.addMouseListener (mouse-listener))
      (.setContentPane panel)
      (.pack)
      ;; (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
      (.setVisible true))))

If I don’t implement all of the MouseListener interface, I end up getting a ton of exceptions whenever the mouse entered or exited the frame and whenever the button was pressed or released. It felt weird adding all those empty methods.

I think I should start thinking about getting a working SlimeMode. 😄

​#Clojure

Comments

(Please contact me if you want to remove your comment.)

Hi, extending MouseListener from the JFrame is not sufficient. This provides a “host” class for your implementation of the listener code, but you still have to register the MouseListener to the JFrame ! In your case, you’ll add the JFrame itself as a MouseListener of itself, something like (not tested) (.addMouseListener jframe jframe)

– Laurent Petit 2010-06-05 11:13 UTC

Laurent Petit

---

Thanks! I got some help on the ​#clojure channel and rewrote the code. Will update the page! 😄

I think your code would have worked, but somehow making the JFrame a MouseListener is way too weird. I was confused.

And you’re working on a Clojure Eclipse plugin! Awesome. At work I’ve been using Eclipse a lot, lately. 😄

– Alex Schroeder 2010-06-05 11:36 UTC

Alex Schroeder