Problem importing JOptionPane from a string evaluated by load-string
I'm just trying out Clojure a bit, so this may be an obvious simple thing I'm misunderstanding. This code in the test file below allows editing a Clojure function that is updated when an Update Code button is pressed, with the new value connected to a GUI button Click Me! as a proxy ActionListener. It starts with a default function that has not been dynamically loaded from a string that pops up a JOptionPane that displays the text in the text pane. Evaluating simple code like (fn [] (println \Hello World\)) with no import dependencies works. What am I doing wrong to not have the evaluated code have access to JOptionPane? I get: user= Exception in thread AWT-EventQueue-0 java.lang.Exception: No such namespace: JOptionPane (NO_SOURCE_FILE:6) when I try the Update Code button. The initial text includes an import statement. What do I misunderstand that the import does not seem to work? Anyway, I'm new to Clojure, so I don't really get the import or ns command that well yet. Any suggestions would be appreciated. Feel free to treat this code example as if it were in the public domain. === guitest2.clj (ns org.pointrel.guitest2 ;(:require ) ;(:use ) ;(:import ) ) (import '(javax.swing JFrame JPanel JButton JOptionPane JTextPane) '(java.awt.event ActionListener)) (defn hookupActionPerformed [receiver function] (println updating hook receiver function) (let [act (proxy [ActionListener] [] (actionPerformed [event] (function)))] (.addActionListener receiver act) ) ) (def initial-text (fn [] (println \Hello World\) (println (+ 2 2)) ;(ns org.pointrel.guitest2) (import '(javax.swing JOptionPane)) (JOptionPane/showMessageDialog nil \Hello from the text panel\ \Greeting\ JOptionPane/INFORMATION_MESSAGE) ) ) (defn window [] (def frame (JFrame. Hello Frame)) (def panel (JPanel.)) (.setContentPane frame panel) (def test-button (JButton. Click Me!)) (.add panel test-button) (def update-button (JButton. Update code)) (.add panel update-button) (def text (JTextPane.)) (.setText text initial-text) (.add panel text) (defn say-hello [] (let [text-contents (.getText text)] (JOptionPane/showMessageDialog nil text-contents Greeting JOptionPane/INFORMATION_MESSAGE))) (hookupActionPerformed test-button say-hello) (defn update-code [] (let [text-contents (.getText text) discard (printf text-contents) user-function (load-string text-contents)] (println update-code) (.removeActionListener test-button (aget (.getListeners test-button ActionListener) 0)) (hookupActionPerformed test-button user-function) )) (hookupActionPerformed update-button update-code) (.setSize frame 200 200) (.setVisible frame true) ) (window) ; (eval (read-string (println \Hello World\))) ; (load-string (fn [] (println \Hello World\))) ; (eval ((fn [] (println Hello World2 === There's probably stylistic issue, too. :-) By the way, the println calls don't seem to show up in NetBeans 6.9.1 with Enclojure after the window opens, and when I try to use code that generates an error I get Repl is disconnected that I don't know how to recover from without restarting NetBeans, so I am testing this with: $ java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.main Clojure 1.2.0 user= (load-file guitest2.clj) --Paul Fernhout http://www.pdfernhout.net/ The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Problem importing JOptionPane from a string evaluated by load-string
Try printing out the *ns* variable in the fn. Chances are your code is being created in a different *ns* than it is being run. You can also try using the fully qualified path to get to JOptionPane, that may help too. On Sep 9, 9:43 pm, Paul D. Fernhout pdfernh...@kurtz-fernhout.com wrote: I'm just trying out Clojure a bit, so this may be an obvious simple thing I'm misunderstanding. This code in the test file below allows editing a Clojure function that is updated when an Update Code button is pressed, with the new value connected to a GUI button Click Me! as a proxy ActionListener. It starts with a default function that has not been dynamically loaded from a string that pops up a JOptionPane that displays the text in the text pane. Evaluating simple code like (fn [] (println \Hello World\)) with no import dependencies works. What am I doing wrong to not have the evaluated code have access to JOptionPane? I get: user= Exception in thread AWT-EventQueue-0 java.lang.Exception: No such namespace: JOptionPane (NO_SOURCE_FILE:6) when I try the Update Code button. The initial text includes an import statement. What do I misunderstand that the import does not seem to work? Anyway, I'm new to Clojure, so I don't really get the import or ns command that well yet. Any suggestions would be appreciated. Feel free to treat this code example as if it were in the public domain. === guitest2.clj (ns org.pointrel.guitest2 ;(:require ) ;(:use ) ;(:import ) ) (import '(javax.swing JFrame JPanel JButton JOptionPane JTextPane) '(java.awt.event ActionListener)) (defn hookupActionPerformed [receiver function] (println updating hook receiver function) (let [act (proxy [ActionListener] [] (actionPerformed [event] (function)))] (.addActionListener receiver act) ) ) (def initial-text (fn [] (println \Hello World\) (println (+ 2 2)) ;(ns org.pointrel.guitest2) (import '(javax.swing JOptionPane)) (JOptionPane/showMessageDialog nil \Hello from the text panel\ \Greeting\ JOptionPane/INFORMATION_MESSAGE) ) ) (defn window [] (def frame (JFrame. Hello Frame)) (def panel (JPanel.)) (.setContentPane frame panel) (def test-button (JButton. Click Me!)) (.add panel test-button) (def update-button (JButton. Update code)) (.add panel update-button) (def text (JTextPane.)) (.setText text initial-text) (.add panel text) (defn say-hello [] (let [text-contents (.getText text)] (JOptionPane/showMessageDialog nil text-contents Greeting JOptionPane/INFORMATION_MESSAGE))) (hookupActionPerformed test-button say-hello) (defn update-code [] (let [text-contents (.getText text) discard (printf text-contents) user-function (load-string text-contents)] (println update-code) (.removeActionListener test-button (aget (.getListeners test-button ActionListener) 0)) (hookupActionPerformed test-button user-function) )) (hookupActionPerformed update-button update-code) (.setSize frame 200 200) (.setVisible frame true) ) (window) ; (eval (read-string (println \Hello World\))) ; (load-string (fn [] (println \Hello World\))) ; (eval ((fn [] (println Hello World2 === There's probably stylistic issue, too. :-) By the way, the println calls don't seem to show up in NetBeans 6.9.1 with Enclojure after the window opens, and when I try to use code that generates an error I get Repl is disconnected that I don't know how to recover from without restarting NetBeans, so I am testing this with: $ java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.main Clojure 1.2.0 user= (load-file guitest2.clj) --Paul Fernhouthttp://www.pdfernhout.net/ The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Problem importing JOptionPane from a string evaluated by load-string
Got it. You cannot invoke (import) (or (ns)) from within the function definition. The function is already being evaluated, and it's too late. This works fine for me: (do (import '(javax.swing JOptionPane)) ((fn [] (println Hello World) (println (+ 2 2)) (JOptionPane/showMessageDialog nil Hello from the text panel Greeting JOptionPane/INFORMATION_MESSAGE So be aware that then some namespace will be changed by the call to import (side effect on *ns*). I would suggest either you create a temporary namespace for the code to execute, either as Sean suggested, you write the call to JOptionPane static methods and fields fully qualified: (javax.swing.JOptionPane/showMessageDialog ...) HTH, -- Laurent 2010/9/10 Paul D. Fernhout pdfernh...@kurtz-fernhout.com: I'm just trying out Clojure a bit, so this may be an obvious simple thing I'm misunderstanding. This code in the test file below allows editing a Clojure function that is updated when an Update Code button is pressed, with the new value connected to a GUI button Click Me! as a proxy ActionListener. It starts with a default function that has not been dynamically loaded from a string that pops up a JOptionPane that displays the text in the text pane. Evaluating simple code like (fn [] (println \Hello World\)) with no import dependencies works. What am I doing wrong to not have the evaluated code have access to JOptionPane? I get: user= Exception in thread AWT-EventQueue-0 java.lang.Exception: No such namespace: JOptionPane (NO_SOURCE_FILE:6) when I try the Update Code button. The initial text includes an import statement. What do I misunderstand that the import does not seem to work? Anyway, I'm new to Clojure, so I don't really get the import or ns command that well yet. Any suggestions would be appreciated. Feel free to treat this code example as if it were in the public domain. === guitest2.clj (ns org.pointrel.guitest2 ;(:require ) ;(:use ) ;(:import ) ) (import '(javax.swing JFrame JPanel JButton JOptionPane JTextPane) '(java.awt.event ActionListener)) (defn hookupActionPerformed [receiver function] (println updating hook receiver function) (let [act (proxy [ActionListener] [] (actionPerformed [event] (function)))] (.addActionListener receiver act) ) ) (def initial-text (fn [] (println \Hello World\) (println (+ 2 2)) ;(ns org.pointrel.guitest2) (import '(javax.swing JOptionPane)) (JOptionPane/showMessageDialog nil \Hello from the text panel\ \Greeting\ JOptionPane/INFORMATION_MESSAGE) ) ) (defn window [] (def frame (JFrame. Hello Frame)) (def panel (JPanel.)) (.setContentPane frame panel) (def test-button (JButton. Click Me!)) (.add panel test-button) (def update-button (JButton. Update code)) (.add panel update-button) (def text (JTextPane.)) (.setText text initial-text) (.add panel text) (defn say-hello [] (let [text-contents (.getText text)] (JOptionPane/showMessageDialog nil text-contents Greeting JOptionPane/INFORMATION_MESSAGE))) (hookupActionPerformed test-button say-hello) (defn update-code [] (let [text-contents (.getText text) discard (printf text-contents) user-function (load-string text-contents)] (println update-code) (.removeActionListener test-button (aget (.getListeners test-button ActionListener) 0)) (hookupActionPerformed test-button user-function) )) (hookupActionPerformed update-button update-code) (.setSize frame 200 200) (.setVisible frame true) ) (window) ; (eval (read-string (println \Hello World\))) ; (load-string (fn [] (println \Hello World\))) ; (eval ((fn [] (println Hello World2 === There's probably stylistic issue, too. :-) By the way, the println calls don't seem to show up in NetBeans 6.9.1 with Enclojure after the window opens, and when I try to use code that generates an error I get Repl is disconnected that I don't know how to recover from without restarting NetBeans, so I am testing this with: $ java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.main Clojure 1.2.0 user= (load-file guitest2.clj) --Paul Fernhout http://www.pdfernhout.net/ The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to
Re: Problem importing JOptionPane from a string evaluated by load-string
I've also used the with-ns package in contrib to fix this. On Sep 10, 9:03 am, Laurent PETIT laurent.pe...@gmail.com wrote: Got it. You cannot invoke (import) (or (ns)) from within the function definition. The function is already being evaluated, and it's too late. This works fine for me: (do (import '(javax.swing JOptionPane)) ((fn [] (println Hello World) (println (+ 2 2)) (JOptionPane/showMessageDialog nil Hello from the text panel Greeting JOptionPane/INFORMATION_MESSAGE So be aware that then some namespace will be changed by the call to import (side effect on *ns*). I would suggest either you create a temporary namespace for the code to execute, either as Sean suggested, you write the call to JOptionPane static methods and fields fully qualified: (javax.swing.JOptionPane/showMessageDialog ...) HTH, -- Laurent 2010/9/10 Paul D. Fernhout pdfernh...@kurtz-fernhout.com: I'm just trying out Clojure a bit, so this may be an obvious simple thing I'm misunderstanding. This code in the test file below allows editing a Clojure function that is updated when an Update Code button is pressed, with the new value connected to a GUI button Click Me! as a proxy ActionListener. It starts with a default function that has not been dynamically loaded from a string that pops up a JOptionPane that displays the text in the text pane. Evaluating simple code like (fn [] (println \Hello World\)) with no import dependencies works. What am I doing wrong to not have the evaluated code have access to JOptionPane? I get: user= Exception in thread AWT-EventQueue-0 java.lang.Exception: No such namespace: JOptionPane (NO_SOURCE_FILE:6) when I try the Update Code button. The initial text includes an import statement. What do I misunderstand that the import does not seem to work? Anyway, I'm new to Clojure, so I don't really get the import or ns command that well yet. Any suggestions would be appreciated. Feel free to treat this code example as if it were in the public domain. === guitest2.clj (ns org.pointrel.guitest2 ;(:require ) ;(:use ) ;(:import ) ) (import '(javax.swing JFrame JPanel JButton JOptionPane JTextPane) '(java.awt.event ActionListener)) (defn hookupActionPerformed [receiver function] (println updating hook receiver function) (let [act (proxy [ActionListener] [] (actionPerformed [event] (function)))] (.addActionListener receiver act) ) ) (def initial-text (fn [] (println \Hello World\) (println (+ 2 2)) ;(ns org.pointrel.guitest2) (import '(javax.swing JOptionPane)) (JOptionPane/showMessageDialog nil \Hello from the text panel\ \Greeting\ JOptionPane/INFORMATION_MESSAGE) ) ) (defn window [] (def frame (JFrame. Hello Frame)) (def panel (JPanel.)) (.setContentPane frame panel) (def test-button (JButton. Click Me!)) (.add panel test-button) (def update-button (JButton. Update code)) (.add panel update-button) (def text (JTextPane.)) (.setText text initial-text) (.add panel text) (defn say-hello [] (let [text-contents (.getText text)] (JOptionPane/showMessageDialog nil text-contents Greeting JOptionPane/INFORMATION_MESSAGE))) (hookupActionPerformed test-button say-hello) (defn update-code [] (let [text-contents (.getText text) discard (printf text-contents) user-function (load-string text-contents)] (println update-code) (.removeActionListener test-button (aget (.getListeners test-button ActionListener) 0)) (hookupActionPerformed test-button user-function) )) (hookupActionPerformed update-button update-code) (.setSize frame 200 200) (.setVisible frame true) ) (window) ; (eval (read-string (println \Hello World\))) ; (load-string (fn [] (println \Hello World\))) ; (eval ((fn [] (println Hello World2 === There's probably stylistic issue, too. :-) By the way, the println calls don't seem to show up in NetBeans 6.9.1 with Enclojure after the window opens, and when I try to use code that generates an error I get Repl is disconnected that I don't know how to recover from without restarting NetBeans, so I am testing this with: $ java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.main Clojure 1.2.0 user= (load-file guitest2.clj) --Paul Fernhout http://www.pdfernhout.net/ The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to
Re: Problem importing JOptionPane from a string evaluated by load-string
On 9/10/10 9:03 AM, Laurent PETIT wrote: Got it. You cannot invoke (import) (or (ns)) from within the function definition. The function is already being evaluated, and it's too late. This works fine for me: (do (import '(javax.swing JOptionPane)) ((fn [] (println Hello World) (println (+ 2 2)) (JOptionPane/showMessageDialog nil Hello from the text panel Greeting JOptionPane/INFORMATION_MESSAGE So be aware that then some namespace will be changed by the call to import (side effect on *ns*). I would suggest either you create a temporary namespace for the code to execute, either as Sean suggested, you write the call to JOptionPane static methods and fields fully qualified: (javax.swing.JOptionPane/showMessageDialog ...) I see, those are good suggestions that help me better understand what is going on with namespaces. I can remember now in my work that I had other errors related to where I placed an import statement in the base code that I had resolved by pulling them out of a function (not really understanding then what worked, because at the same time I changed the form of it). Strangely, when I click on Update code to evaluate that code it popped up the JOptionPane right away. I would think it would have not done that, because I was trying to return an anonymous function I could bind to the button action. And then Click Me! to actually call the function produces an error. Exception in thread AWT-EventQueue-0 java.lang.NullPointerException at org.pointrel.guitest2$hookupActionPerformed$fn__54.invoke(guitest2.clj:13) at org.pointrel.guitest2.proxy$java.lang.Object$ActionListener$46793e3a.actionPerformed(Unknown Source) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1882) I'm presuming that (do ...) returns nil and so the nil gets bound instead of a function and that causes the error. I just removed a set of parens that caused the anonymous fn to evaluate during the load-string call, and now it works the way I wanted to. I can't say the GUI design was very self-explanatory, so I can see how you might have thought success was different then I expected. :-) This is the variant that works the way I wanted: (do (import '(javax.swing JOptionPane)) (fn [] (println Hello World) (println (+ 2 2)) (JOptionPane/showMessageDialog nil Hello from the text panel Greeting JOptionPane/INFORMATION_MESSAGE))) And this works also with the complete path as Sean suggested: (fn [] (println Hello World) (println (+ 2 2)) (JOptionPane/showMessageDialog nil Hello from the text panel2 Greeting javax.swing.JOptionPane/INFORMATION_MESSAGE)) So, my thanks go to you and Sean, for two different solutions. :-) I'll need to look more into that namespace thing. I'm more used to Python/Jython recently where you can import stuff wherever you want (suboptimally if done in a frequently called function, of course). Obviously, I can see a functional language making different tradeoffs. Anyway, I've just been noodling around in terms of what it would take to build an interactive GUI building system where you could easily change how some of the system worked at run-time as a sort of rapid prototyping (like Smalltalk systems usually can do). This amount of code seems to be the bare bones to doing that (at least as a proof-of-concept), so thanks again for the solutions. I know there are other Clojure GUI building stuff out there, already; I was just starting playing with something interesting to show the power and elegance of Clojure. :-) --Paul Fernhout http://www.pdfernhout.net/ The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en