Search code examples
javaclojureinteropthisgen-class

Clojure gen-class this keyword


Is it possible to refer to Java's 'this' keyword from within a gen-class method?

I am trying to implement daredesm's answer here, in Clojure. However, when I try to use 'this' in the run function, I get "java.lang.RuntimeException: Unable to resolve symbol: this in this context."

(gen-class
  :name ClipboardListener
  :extends java.lang.Thread
  :implements [java.awt.datatransfer.ClipboardOwner]
  :prefix ClipboardListener-
  :methods [[takeOwnership [Transferable] void]])

(def systemClipboard (.getSystemClipboard (java.awt.Toolkit/getDefaultToolkit)))

(defn ClipboardListener-run []
  (let [transferable (.getContents systemClipboard this)]
    (.takeOwnership transferable)))

(defn ClipboardListener-lostOwnership [clipboard trasferable] (prn "hit lost"))
(defn ClipboardListener-takeOwnership [transferable] (prn "hit take"))
(defn processClipboard [transferable clipboard] (prn "hit process"))

Note: This is my first time generating Java classes in Clojure, so any general feedback/resources is greatly appreciated.


Solution

  • Instance methods can take an implicit 'self' arg- as the first argument. So to take your example:

    (defn ClipboardListener-run [this]
      (let [transferable (.getContents systemClipboard this)]
        (.takeOwnership transferable)))
    

    Note the this argument :)

    Same goes for any instance method, e.g:

    (defn ClipboardListener-toString [this]
      "override Object#toString with something cool")
    

    Have a look at this (no pun intended) for more info on gen-class.

    Also consider reify for cases like Runnable, Callable, e.t.c where you just need to implement a small-ish interface.