(See my full list of Clojure Swing examples and tutorials at Clojure Swing Interop)
Every complex GUI uses message dialogs. When using Clojure Swing interop, you will use the JOptionPane for your message dialogs. Two keys to remember when using JOptionPane s, is that they should always be called from within the Event Dispatch Thread (EDT). Sometimes the JOptionPane is shown by an ActionListener that is already on the EDT, and sometimes you need to call invokeAndWait , because your current thread is not the EDT.
The other key point to remember with JOptionPane s is that you can associate the message dialog with a frame, or set the frame to nil . If a JOptionPane ‘s frame is set to nil , then the message dialog will center itself on the screen when it displays. If a JFrame is provided to the JOptionPane , then the message dialog will center itself on the JFrame it is associated with.
Here is a basic example that provides a button to click, and that displays a plain JOptionPane with a message. The ActionListener is called from the EDT, so the JOptionPane is being called from the EDT.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
(ns swingproject.core (:gen-class) (:import [javax.swing SwingUtilities JFrame JButton JOptionPane] [java.awt FlowLayout] [java.awt.event ActionListener])) (defn create-and-show-gui [] (let [my-frame (doto (JFrame. "JOptionPane Example") (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) (.setLocationRelativeTo nil)) my-button (JButton. "Click ME!") content-pane (doto (.getContentPane my-frame) (.setLayout (FlowLayout.)))] (.addActionListener my-button (reify ActionListener (actionPerformed [this e] (JOptionPane/showMessageDialog my-frame "Betcha always wanted a message in a JOptionPane!")))) (.add content-pane my-button) (.pack my-frame) (.setSize my-frame 300 200) (.setVisible my-frame true))) (defn -main "entry point for app" [& args] (SwingUtilities/invokeLater create-and-show-gui)) |
Here is an example that shows a JOptionPane that displays from a normal thread. The EDT must be explicitly called with invokeAndWait . The four most common types of message dialogs are shown.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
(ns swingproject.core (:gen-class) (:import [javax.swing SwingUtilities JOptionPane])) (defn example-message-dialogs [] ;; Default message dialog (SwingUtilities/invokeAndWait #(JOptionPane/showMessageDialog nil "This is the default style")) ;; Plain message dialog (SwingUtilities/invokeAndWait #(JOptionPane/showMessageDialog nil "This is the 'plain' style message dialog" "My Plain Title" JOptionPane/PLAIN_MESSAGE)) ;; Warning message dialog (SwingUtilities/invokeAndWait #(JOptionPane/showMessageDialog nil "I'm a 'warning' message dialog" "My Warning" JOptionPane/WARNING_MESSAGE)) ;; Error message dialog (SwingUtilities/invokeAndWait #(JOptionPane/showMessageDialog nil "This is the 'error' message dialog" "My Error" JOptionPane/ERROR_MESSAGE)) ) (defn -main "entry point for app" [& args] (example-message-dialogs)) |