diff options
author | scgilardi <scgilardi@gmail.com> | 2009-06-06 17:22:55 +0000 |
---|---|---|
committer | scgilardi <scgilardi@gmail.com> | 2009-06-06 17:22:55 +0000 |
commit | 2c75edd4a1764b9453107e50feceb0fc185faae2 (patch) | |
tree | a8d2a06062db3887c43df22b9042b752144c300c /src | |
parent | 83fa7099432d5af2febbad9c33e076b9a03c3d1e (diff) |
swing-utils: add action and menu(bar) builders from Meikel Brandmeyer, inspired by Waterfront
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/contrib/swing_utils.clj | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/src/clojure/contrib/swing_utils.clj b/src/clojure/contrib/swing_utils.clj index ac41b29a..013d7d29 100644 --- a/src/clojure/contrib/swing_utils.clj +++ b/src/clojure/contrib/swing_utils.clj @@ -15,7 +15,10 @@ (ns clojure.contrib.swing-utils (:import (java.awt.event ActionListener KeyAdapter) - (javax.swing SwingUtilities))) + (javax.swing AbstractAction Action + JMenu JMenuBar JMenuItem + SwingUtilities)) + (:use [clojure.contrib.def :only (defvar)])) (defn add-action-listener "Adds an ActionLister to component. When the action fires, f will be @@ -64,4 +67,86 @@ [& body] `(do-swing* :now (fn [] ~@body))) +(defvar action-translation-table + (atom {:name Action/NAME + :accelerator Action/ACCELERATOR_KEY + :command-key Action/ACTION_COMMAND_KEY + :long-desc Action/LONG_DESCRIPTION + :short-desc Action/SHORT_DESCRIPTION + :mnemonic Action/MNEMONIC_KEY + :icon Action/SMALL_ICON}) + "Translation table for the make-action constructor.") + +(defn make-action + "Create an Action proxy from the given action spec. The standard keys + recognised are: :name, :accelerator, :command-key, :long-desc, + :short-desc, :mnemonic and :icon - corresponding to the similar named + Action properties. The :handler value is used in the actionPerformed + method of the proxy to pass on the event." + [spec] + (let [t-table @action-translation-table + handler (:handler spec) + spec (dissoc spec :handler) + spec (map (fn [[k v]] [(t-table k) v]) spec) + action (proxy [AbstractAction] [] + (actionPerformed [evt] (handler evt)))] + (doseq [[k v] spec] + (.putValue action k v)) + action)) + +(defvar menu-constructor-dispatch + (atom #{:action :handler :items}) + "An atom containing the dispatch set for the add-menu-item method.") + +(defmulti add-menu-item + "Adds a menu item to the parent according to the item description. + The item description is a map of the following structure. + + Either: + - one single :action specifying a javax.swing.Action to be associated + with the item. + - a specification suitable for make-action + - a set of :name, :mnemonic and :items keys, specifying a submenu with + the given sequence of item entries. + - an empty map specifying a separator." + {:arglists '([parent item])} + (fn add-menu-item-dispatch [_ item] + (some @menu-constructor-dispatch (keys item)))) + +(defmethod add-menu-item :action + add-menu-item-action + [parent {:keys [action]}] + (let [item (JMenuItem. action)] + (.add parent item))) + +(defmethod add-menu-item :handler + add-menu-item-handler + [parent spec] + (add-menu-item parent {:action (make-action spec)})) + +(defmethod add-menu-item :items + add-menu-item-submenu + [parent {:keys [items mnemonic name]}] + (let [menu (JMenu. name)] + (when mnemonic + (.setMnemonic menu mnemonic)) + (doseq [item items] + (add-menu-item menu item)) + (.add parent menu))) + +(defmethod add-menu-item nil ; nil meaning separator + add-menu-item-separator + [parent _] + (.addSeparator parent)) + +(defn make-menubar + "Create a menubar containing the given sequence of menu items. The menu + items are described by a map as is detailed in the docstring of the + add-menu-item function." + [menubar-items] + (let [menubar (JMenuBar.)] + (doseq [item menubar-items] + (add-menu-item menubar item)) + menubar)) + ;; ---------------------------------------------------------------------- |