Problem importing JOptionPane from a string evaluated by load-string

2010-09-10 Thread Paul D. Fernhout
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

2010-09-10 Thread Sean Devlin
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

2010-09-10 Thread Laurent PETIT
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

2010-09-10 Thread Sean Devlin
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

2010-09-10 Thread Paul D. Fernhout

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