The strange thing is that typing in the field belonging to any of the first 3 rows WILL update the text in the fourth (which I call the command row, since it belongs to a map like {:command {:label lbl :field fld :button btn}}). So my suspicion is that filling in the text via calling the JTextField.setText function did NOT fire an event that the DocumentListener was listening for.
I was correct and learned that setText is not a bound property and thus doesn't trigger event. I then learned that I needed to make a change to the JTextField's underlying Document to trigger an event that insertUpdate would be called on. I tried doing this, and my code now looks like this:
36 ;; Create a proxy for clicking on the Browse button
37 (defn on-click
38 "Returns a proxy handler for a given button"
39 [ field ]
40 ;; closures are cool.
41 (proxy [ActionListener] []
42 (actionPerformed [ event ]
43 (let [text (.getText field)
44 selection (get-file-selection)
45 fld-doc (.getDocument field)
46 fld-len (.getLength fld-doc)]
47 (if (empty? text)
48 (.insertString fld-doc 0 selection nil)
49 (let [ tx (apply str text ":" selection) ]
50 (doto fld-doc
51 (.remove 0 fld-len)
52 (.insertString 0 tx nil))))))))
53
54 (defn set-fld
55 [ field fld-string ]
56 (.setText field fld-string))
57
58
59 ;; When any of the textfields (except the cmd-fld) changes, we
60 ;; need to add those changes to cmd-fld. cmd-fld should always
61 ;; hold the concatenation of: ext-jar row's fld, classpath fld
62 ;; and clojars fld
63 (defn cp-string [ src flds ]
64 (if (.isFocusOwner src)
65 (let [ ext-jar-txt (.getText (flds :ext-jar-row))
66 cp-txt (.getText (flds :classpath-row))
67 clj-txt (.getText (flds :clojars-row))
68 cmd-fld (flds :cmd-row)
69 all-flds (str-join ":" [ext-jar-txt cp-txt clj-txt])]
70 (println "external jar = " ext-jar-txt)
71 (println "classpath = "cp-txt)
72 (println "clojars = " clj-txt)
73 (set-fld cmd-fld (str "java -cp " all-flds)))))
74
75
76 ;; We need a proxy that will be a TextHandler for the cmd-fld.
77 ;; As text is entered into any of the first three rows (either
78 ;; manually or via the FileChooser), the command JTextField
79 ;; should reflect those changes
80 (defn text-handler
81 "Returns a proxy for a given JTextField"
82 [ src txt-flds ]
83 (.. src getDocument
84 (addDocumentListener
85 (proxy [DocumentListener] []
86 (insertUpdate [e] (cp-string src txt-flds))
87 (removeUpdate [e] (cp-string src txt-flds))
88 (changedUpdate [e] (cp-string src txt-flds))))))
The insertString is supposed to alter the Document object which in turn should fire a DocumentEvent. So the basic flow is like this:
1. user selects file
2. this causes actionPerformed to be called
3. this causes the JTextField Document to change
4. this should cause a DocumentEvent to be fired
5. if that happened, insertUpdate should be called from the DocumentListener
6. which would call cp-string to concatenate all the JTextFields and return the result in the command JTextField
I know the DocumentListener works, because if you manually type into the field...the command row's JTextField immediately updates with whatever is typed in. So I'm not sure what I'm doing wrong here.
Here's the latest screenshot:
No comments:
Post a Comment