Has anybody looked at Applets since 1997 and Java 1.1? Why would you want to do this?
There are a couple of reasons:
- Clojure rocks. You want to show people online what your Clojure code is doing, without having them read the code, or interact with another servlet through a browser.
- The reality is that the tooling and libraries for the JVM are superior to Flash and Javascript, and will probably remain so for some time.
Isn’t Clojurescript Cooler?
Yes – but at this point in time is less ‘production ready’ than the main Clojure release.
But haven’t people done this online already?
They have. But there is no good lifecycle for testing it in Counterclockwise (or your REPL of choice). There is no way to change the code and easily debug it, without going through a full code->compile->deploy cycle.
In Eclipse for Java Applets, you can just extend the Applet, and then right-click and select ‘run as Applet’. In Clojure (as these examples show) you can also extend the Applet. But there is no easy way to ‘Run as Applet’. Simply executing the Clojure code doesn’t start it either.
So what does the basic Applet look like?
SimpleSwingApplet.clj
(ns demo.applet.SimpleSwingApplet
(:import
(javax.swing JApplet JPanel JLabel JFrame))
(:gen-class
:post-init post-init
:extends javax.swing.JApplet))
(defn -post-init [this]
(def jpanel (JPanel.))
(.add jpanel (JLabel. "This is my first applet"))
(.setContentPane this jpanel))
Now that’s what the other two blogs had. Great – but if you run that on your Clojure REPL, you’ll get a big fat nothing. So this is where we start adding value.
Here is what we’ll add to make it run in Counterclockwise (or your REPL of choice).
SimpleSwingAppletRunner.clj
(ns game.applet.SimpleSwingAppletRunner
(:import
(javax.swing JApplet JPanel JLabel JFrame)))
;------
(compile 'game.applet.SimpleSwingApplet)
(defn -main [s]
(let [applet (new demo.applet.SimpleSwingApplet)]
(doto (JFrame. "MyApplet")
(.add (.getContentPane applet))
(.pack)
(.setLocationByPlatform true)
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.setVisible true))
))
(-main "s")
Basically we instantiate the Applet and then get the contentPane which we pass to a newly created a Frame.