2

Trying to make menus in seesaw. I can't figure out what the "items" new-action open-action etc is supposed to be in the code below inside main. I thought it could be the menu item texts, or perhaps function callbacks. Ultimately it would be nice to have an example that shows how to control the menu item text, and then to be able to give the callback in my code. Don't know how to do this.

MODIFIED: This code now works correctly.

(ns hello-seesaw.core
  (:gen-class)
  (:use seesaw.core))

(defn handler
  [event]
  (alert event
    (str "<html>Hello from <b>Clojure</b>. Button "
      (.getActionCommand event) " clicked.")))

(defn menu-handler
  [event]
  ()
)

(def new-action   (menu-item :text "New"   :listen [:action menu-handler]))
(def open-action  (menu-item :text "Open"  :listen [:action menu-handler]))
(def save-action  (menu-item :text "Save"  :listen [:action menu-handler]))
(def exit-action  (menu-item :text "Exit"  :listen [:action menu-handler]))
(def copy-action  (menu-item :text "Copy"  :listen [:action menu-handler]))
(def paste-action (menu-item :text "Paste" :listen [:action menu-handler]))


(defn -main [& args]
  (invoke-later
        (->
                (frame :title "Hello Swing" :on-close :exit
                :content (button :text "Click Me" :listen [:action handler])
                :menubar
                        (menubar :items
                        [
                                (menu :text "File" :items [new-action open-action save-action exit-action])
                                (menu :text "Edit" :items [copy-action paste-action])
                        ]
                        )
                )
        pack!
        show!))
)
user1676605
  • 1,337
  • 3
  • 13
  • 21

1 Answers1

3

Each of the *-action items refer to a kind of menu item (menu-item, checkbox-menu-item, or radio-menu-item). Each of these has the same options as button, so you configure each one like you do the button in your first frame.

Your definition for the new button might look like:

(def new-action (menu-item :text "New" :listen [:action handler]))

As an aside, if you try to run the program as written with both frames defined, you will get an IllegalArgumentException (because you are passing the result of the first frame call to the second). An easy solution is to combine the two.

(frame :title "Hello Swing" :on-close :exit
           :content (button :text "Click Me" :listen [:action handler])
           :menubar
           (menubar :items
                    [(menu :text "File" :items [new-action open-action save-action exit-action])
                     (menu :text "Edit" :items [copy-action paste-action])]))
Chad Taylor
  • 746
  • 5
  • 7
  • Thank you. See the modified section in the original post. Now I get Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: opts must be a map or have an even number of entries at seesaw.util$check_args.invoke(util.clj:23) ... – user1676605 Feb 09 '14 at 14:44
  • Ok, there are two small issues with the code you have pasted. The first that you are missing a closing parens at the very end (likely just not copied from your source considering the error you are getting). The other is that the `frame` call is closed in the wrong place. In your modified code, it is closed at the end of the line starting with `:content`. Move one closing parens from that line to the end of the line containing the last element of the menu item array. After these two small changes, I was able to execute your code. – Chad Taylor Feb 09 '14 at 16:55
  • Thank you. I got it to work. See above section MODIFIED for final working code. One thing, I really don't know what is best practice to format "lisp" style code. Is there a place that shows how to indent "correctly"? – user1676605 Feb 09 '14 at 18:40
  • I try to follow the [community style guide](https://github.com/bbatsov/clojure-style-guide#source-code-layout--organization). – Chad Taylor Feb 09 '14 at 18:47