This is the code:-
(ns clojurecorner
(:import
(javax.swing JButton JPanel JFrame JLabel SwingUtilities)
(java.awt.event ActionListener)
(java.awt GridLayout)))
(def click-counter (atom 0))
(defn init-gui []
(. SwingUtilities invokeLater
(proxy [Runnable] []
(run []
(let
[frame (JFrame. "Swing application")
button (JButton. "I'm a Swing button!")
label (JLabel. "Number of click")]
(.addActionListener button
(proxy [ActionListener] []
(actionPerformed [e]
(.setText label
(str "Clicks: " (swap! click-counter inc))))))
(doto frame
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.setLayout (GridLayout. 0 1))
(.add button)
(.add label)
(.setSize 300 200)
(.setVisible true)))))))
(JFrame/setDefaultLookAndFeelDecorated true)
(init-gui)
The line (def click-counter (atom 0)) creates an atom - a repository for our click counter - sets the initial value to zero, and gives it the name click-counter.
The line (swap! click-counter inc)) updates the value of the counter atom with the result of applying the function inc to the current value, and it returns the new value - a thread-friendly way to maintain the counter.
The code that handles the click event is wired up to the button via another proxy implementing an interface that supports a single method, like the code that creates the gui - in this case a proxy implementing ActionListener by providing a method actionPerformed.
Stuart Sierra on Digital Digressions has pointed out that this pattern with a single abstract method is going to be common enough to warrant a macro. Yes I'll try that next week. Anyway, this is how the application looks:
No comments:
Post a Comment