Mercurial > lasercutter
diff src/clojure/inspector.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/inspector.clj Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,185 @@ 1.4 +; Copyright (c) Rich Hickey. All rights reserved. 1.5 +; The use and distribution terms for this software are covered by the 1.6 +; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 1.7 +; which can be found in the file epl-v10.html at the root of this distribution. 1.8 +; By using this software in any fashion, you are agreeing to be bound by 1.9 +; the terms of this license. 1.10 +; You must not remove this notice, or any other, from this software. 1.11 + 1.12 +(ns ^{:doc "Graphical object inspector for Clojure data structures." 1.13 + :author "Rich Hickey"} 1.14 + clojure.inspector 1.15 + (:import 1.16 + (java.awt BorderLayout) 1.17 + (java.awt.event ActionEvent ActionListener) 1.18 + (javax.swing.tree TreeModel) 1.19 + (javax.swing.table TableModel AbstractTableModel) 1.20 + (javax.swing JPanel JTree JTable JScrollPane JFrame JToolBar JButton SwingUtilities))) 1.21 + 1.22 +(defn atom? [x] 1.23 + (not (coll? x))) 1.24 + 1.25 +(defn collection-tag [x] 1.26 + (cond 1.27 + (instance? java.util.Map$Entry x) :entry 1.28 + (instance? java.util.Map x) :map 1.29 + (sequential? x) :seq 1.30 + :else :atom)) 1.31 + 1.32 +(defmulti is-leaf collection-tag) 1.33 +(defmulti get-child (fn [parent index] (collection-tag parent))) 1.34 +(defmulti get-child-count collection-tag) 1.35 + 1.36 +(defmethod is-leaf :default [node] 1.37 + (atom? node)) 1.38 +(defmethod get-child :default [parent index] 1.39 + (nth parent index)) 1.40 +(defmethod get-child-count :default [parent] 1.41 + (count parent)) 1.42 + 1.43 +(defmethod is-leaf :entry [e] 1.44 + (is-leaf (val e))) 1.45 +(defmethod get-child :entry [e index] 1.46 + (get-child (val e) index)) 1.47 +(defmethod get-child-count :entry [e] 1.48 + (count (val e))) 1.49 + 1.50 +(defmethod is-leaf :map [m] 1.51 + false) 1.52 +(defmethod get-child :map [m index] 1.53 + (nth (seq m) index)) 1.54 + 1.55 +(defn tree-model [data] 1.56 + (proxy [TreeModel] [] 1.57 + (getRoot [] data) 1.58 + (addTreeModelListener [treeModelListener]) 1.59 + (getChild [parent index] 1.60 + (get-child parent index)) 1.61 + (getChildCount [parent] 1.62 + (get-child-count parent)) 1.63 + (isLeaf [node] 1.64 + (is-leaf node)) 1.65 + (valueForPathChanged [path newValue]) 1.66 + (getIndexOfChild [parent child] 1.67 + -1) 1.68 + (removeTreeModelListener [treeModelListener]))) 1.69 + 1.70 + 1.71 +(defn old-table-model [data] 1.72 + (let [row1 (first data) 1.73 + colcnt (count row1) 1.74 + cnt (count data) 1.75 + vals (if (map? row1) vals identity)] 1.76 + (proxy [TableModel] [] 1.77 + (addTableModelListener [tableModelListener]) 1.78 + (getColumnClass [columnIndex] Object) 1.79 + (getColumnCount [] colcnt) 1.80 + (getColumnName [columnIndex] 1.81 + (if (map? row1) 1.82 + (name (nth (keys row1) columnIndex)) 1.83 + (str columnIndex))) 1.84 + (getRowCount [] cnt) 1.85 + (getValueAt [rowIndex columnIndex] 1.86 + (nth (vals (nth data rowIndex)) columnIndex)) 1.87 + (isCellEditable [rowIndex columnIndex] false) 1.88 + (removeTableModelListener [tableModelListener])))) 1.89 + 1.90 +(defn inspect-tree 1.91 + "creates a graphical (Swing) inspector on the supplied hierarchical data" 1.92 + {:added "1.0"} 1.93 + [data] 1.94 + (doto (JFrame. "Clojure Inspector") 1.95 + (.add (JScrollPane. (JTree. (tree-model data)))) 1.96 + (.setSize 400 600) 1.97 + (.setVisible true))) 1.98 + 1.99 +(defn inspect-table 1.100 + "creates a graphical (Swing) inspector on the supplied regular 1.101 + data, which must be a sequential data structure of data structures 1.102 + of equal length" 1.103 + {:added "1.0"} 1.104 + [data] 1.105 + (doto (JFrame. "Clojure Inspector") 1.106 + (.add (JScrollPane. (JTable. (old-table-model data)))) 1.107 + (.setSize 400 600) 1.108 + (.setVisible true))) 1.109 + 1.110 + 1.111 +(defmulti list-provider class) 1.112 + 1.113 +(defmethod list-provider :default [x] 1.114 + {:nrows 1 :get-value (fn [i] x) :get-label (fn [i] (.getName (class x)))}) 1.115 + 1.116 +(defmethod list-provider java.util.List [c] 1.117 + (let [v (if (vector? c) c (vec c))] 1.118 + {:nrows (count v) 1.119 + :get-value (fn [i] (v i)) 1.120 + :get-label (fn [i] i)})) 1.121 + 1.122 +(defmethod list-provider java.util.Map [c] 1.123 + (let [v (vec (sort (map (fn [[k v]] (vector k v)) c)))] 1.124 + {:nrows (count v) 1.125 + :get-value (fn [i] ((v i) 1)) 1.126 + :get-label (fn [i] ((v i) 0))})) 1.127 + 1.128 +(defn list-model [provider] 1.129 + (let [{:keys [nrows get-value get-label]} provider] 1.130 + (proxy [AbstractTableModel] [] 1.131 + (getColumnCount [] 2) 1.132 + (getRowCount [] nrows) 1.133 + (getValueAt [rowIndex columnIndex] 1.134 + (cond 1.135 + (= 0 columnIndex) (get-label rowIndex) 1.136 + (= 1 columnIndex) (print-str (get-value rowIndex))))))) 1.137 + 1.138 +(defmulti table-model class) 1.139 + 1.140 +(defmethod table-model :default [x] 1.141 + (proxy [AbstractTableModel] [] 1.142 + (getColumnCount [] 2) 1.143 + (getRowCount [] 1) 1.144 + (getValueAt [rowIndex columnIndex] 1.145 + (if (zero? columnIndex) 1.146 + (class x) 1.147 + x)))) 1.148 + 1.149 +;(defn make-inspector [x] 1.150 +; (agent {:frame frame :data x :parent nil :index 0})) 1.151 + 1.152 + 1.153 +(defn inspect 1.154 + "creates a graphical (Swing) inspector on the supplied object" 1.155 + {:added "1.0"} 1.156 + [x] 1.157 + (doto (JFrame. "Clojure Inspector") 1.158 + (.add 1.159 + (doto (JPanel. (BorderLayout.)) 1.160 + (.add (doto (JToolBar.) 1.161 + (.add (JButton. "Back")) 1.162 + (.addSeparator) 1.163 + (.add (JButton. "List")) 1.164 + (.add (JButton. "Table")) 1.165 + (.add (JButton. "Bean")) 1.166 + (.add (JButton. "Line")) 1.167 + (.add (JButton. "Bar")) 1.168 + (.addSeparator) 1.169 + (.add (JButton. "Prev")) 1.170 + (.add (JButton. "Next"))) 1.171 + BorderLayout/NORTH) 1.172 + (.add 1.173 + (JScrollPane. 1.174 + (doto (JTable. (list-model (list-provider x))) 1.175 + (.setAutoResizeMode JTable/AUTO_RESIZE_LAST_COLUMN))) 1.176 + BorderLayout/CENTER))) 1.177 + (.setSize 400 400) 1.178 + (.setVisible true))) 1.179 + 1.180 + 1.181 +(comment 1.182 + 1.183 +(load-file "src/inspector.clj") 1.184 +(refer 'inspector) 1.185 +(inspect-tree {:a 1 :b 2 :c [1 2 3 {:d 4 :e 5 :f [6 7 8]}]}) 1.186 +(inspect-table [[1 2 3][4 5 6][7 8 9][10 11 12]]) 1.187 + 1.188 +)