3

I'd like my Clojure program to exit when a JFrame is closed.

I'm attempting to trap and handle the close event as such:

(def exit-action (proxy [WindowAdapter] []
               (windowClosing [event] (fn [] (System/exit 0)))
               )
)
(.addWindowListener frame exit-action)

This doesn't throw any obvious errors but it also doesn't appear to do what I want.

Assistance is appreciated.

Answer:

Adapting Rekin's answer did the trick:

(.setDefaultCloseOperation frame JFrame/EXIT_ON_CLOSE)

Note that that is:

setDefaultCloseOperation 

not:

setDefaultOperationOnClose
SMTF
  • 705
  • 10
  • 16

3 Answers3

3

In Java it's:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

More elaborate examples can be found in official Java Swing tutorial about Frames

Rekin
  • 9,731
  • 2
  • 24
  • 38
  • I'm not sure why but setDefaultCloseOperation failed with an error about not being able to find JFrame.EXIT_ON_CLOSE (nothing about the function not being found) setDefaultCloseOperation did what was needed with no such error about not finding EXIT_ON_CLOSE. I suppose it could be different JVM versions. Thanks again. – SMTF Jun 22 '11 at 07:42
  • Oh, sorry, that's because i wrote it from memory. I'm going to edit out the answer. – Rekin Jun 22 '11 at 07:48
3

I would use EXIT_ON_CLOSE, but the reason your first attempt didn't work is that the body of proxy should contain (System/exit 0), not (fn [] (System/exit 0)). Rather than exiting, you were returning (and then throwing away) a function that, when called, would exit.

amalloy
  • 89,153
  • 8
  • 140
  • 205
  • Thanks for that clarification. I initially thought that I needed an ad-hock function to be sure that I was passing the proxy what it needed; it slipped my mind that the exit call would be a valid function itself. – SMTF Jun 29 '11 at 22:13
2

Here's a short demonstration program I showed on my blog a while ago

(ns net.dneclark.JFrameAndTimerDemo
  (:import (javax.swing JLabel JButton JPanel JFrame Timer))
  (:gen-class))

(defn timer-action [label counter]
   (proxy 1 []
     (actionPerformed
      [e]
       (.setText label (str "Counter: " (swap! counter inc))))))

(defn timer-fn []
  (let [counter (atom 0)
        label (JLabel. "Counter: 0")
        timer (Timer. 1000 (timer-action label counter))
        panel (doto (JPanel.)
                (.add label))]
    (.start timer)
    (doto (JFrame. "Timer App")
      (.setContentPane panel)
      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
      (.setLocation 300 300)
      (.setSize 200 200)
      (.setVisible true)))
  (println "exit timer-fn"))

(defn -main []
  (timer-fn))

Note the line in timer-fn[] that sets the default close operation. Just about like Java but with a little syntax fiddling.

The purpose of the blog entry was to show an example of a closure in Clojure.

clartaq
  • 5,320
  • 3
  • 39
  • 49