Clojure: exit program when Window Frame is Closed
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 fra开发者_运维知识库me JFrame/EXIT_ON_CLOSE)
Note that that is:
setDefaultCloseOperation
not:
setDefaultOperationOnClose
In Java it's:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
More elaborate examples can be found in official Java Swing tutorial about Frames
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.
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.
精彩评论