Denis
Denis

Reputation: 1555

Listener seesaw.core clojure

a new to Clojure here.

I would like to share a behaviour which seems strange to me, but may be it's totally ok. I followed the tutorial on github https://gist.github.com/daveray/1441520#file-seesaw-repl-tutorial-clj-L381 , and more precisely the part where I am supposed to add a Listener to a Label. Let's make a constructor and display helper:

(defn make-lb [s]
  (listbox :model (-> (symbol s) ns-publics keys sort)))
(defn display [content frame]
  (config! frame :content content)
  content)

This works perfectly:

(def lb (make-lb "clojure.core"))
(display (scrollable lb) f)
(listen lb :selection (fn [e] (println "Selection is " (selection e))))

Howevever, this doesn't:

(def lb (scrollable (make-lb "clojure.core")))
(display lb f)
(listen lb :selection (fn [e] (println "Selection is " (selection e))))

Notice the different "Scrollable" emplacement. In the second case, compilier tells me "Unknown event type :selection seesaw.util/illegal-Argument (utils.clj:19)"

I don't see any reason why the first snippet works, and the second doesn't. I don't have any knowledge of Swing and/or other Java libraries

Upvotes: 0

Views: 216

Answers (1)

Hoagy Carmichael
Hoagy Carmichael

Reputation: 1028

Why doesn't this work? (implied)

tl;dr

  • listbox and scrollable return different things

Details

  • Check out the return values of the different calls (original make-lb included for clarity):
(defn make-lb [s]
  (listbox :model (-> (symbol s) ns-publics keys sort)))

(class (make-lb "clojure.core"))
;;=> seesaw.core.proxy$javax.swing.JList$Tag$fd407141

(class (scrollable (make-lb "clojure.core")))
;;=> seesaw.core.proxy$javax.swing.JScrollPane$Tag$fd407141
  • For our purposes, we'll just say that listbox returns a JList and scrollable returns a JScrollPane

  • Given that, the calls to display are equivalent

  • However, the calls to listen are not equivalent

    • In the first case, lb resolves to a JList, and in the second case, lb resolves to a JScrollPane

More details

; :selection is an artificial event handled specially for each class
; of widget, so we hack...

  • What I'll call a "real selection type" is resolved in resolve-event-aliases

    • You'll notice that there's a case for JList, but not for JScrollPane
  • In the JScrollPane case, the artificial :selection is simply handed back from the call to resolve-event-aliases

    • Since this isn't a "real selection type", it's only a matter of time before things go pear-shaped
  • And sure enough, get-or-install-handlers attempts to look up :selection, gets nothing back, and calls (illegal-argument "Unknown event type %s" event-name) where event-name is bound to :selection, which matches the exception that you were receiving

Upvotes: 1

Related Questions