I created a new Clojure app with clojure -Tclj-new app :name myname/myapp and added the javafx deps to deps.edn
org.openjfx/javafx-controls {:mvn/version "17.0.2"}
org.openjfx/javafx-base {:mvn/version "17.0.2"}
org.openjfx/javafx-graphics {:mvn/version "17.0.2"}
org.openjfx/javafx-media {:mvn/version "17.0.2"}
org.openjfx/javafx-web {:mvn/version "17.0.2"}
I copied the initialization of a UI using JavaFX, extending the class Application.
(ns myname.myapp
(:import
(javafx.application Application)
(javafx.scene Scene)
(javafx.scene.layout VBox)
(javafx.scene.control Label)
(javafx.stage Stage))
(:gen-class :extends javafx.application.Application))
(def app (atom nil))
(defn -start [this stage]
(let [root (VBox.)]
(reset! app this)
(.setTitle stage "Hello From Clojure!")
(.add (.getChildren root) (Label. "Hello World"))
(.show stage)))
(defn -main [& args]
(Application/launch myname.myapp args))
I cannot run the project. With clj -M:run-m it returns
Syntax error (ClassNotFoundException) compiling at (myname/myapp.clj:20:3). myname.myapp
It seems that Clojure is not generating any class since no folder target is created. I'm using Clojure 1.11.1 on macOS 12.4
I think you really have to create uberjar- you can also use this command:
lein uberjarand then use
java -jar your-app-standalone.jarin the folder with the created jar (probablytarget/uberjar/).Also, if you want to display your
Label, you have to createSceneand add that label there. This works:Note that there's a wrapper over JavaFX called Cljfx, which would allow you to -among other things- test your project in REPL, without creating any uberjars.
Minimal example:
Dependency:
[cljfx "1.7.21"]Core: