Tuesday 11 October 2011

Click Counter

The next example comes also from the Swing Tutorial.  Here we have a button and a label.  The button click adds one to a counter, and the label shows the number on the counter, so you can see how often you have clicked the button.

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