如果您阅读JavaFX Application 类文档,您会看到 Application 类是一个抽象类,不能直接实例化。这意味着,您至少必须创建 javafx.application.Application 的子类。
生命周期
JavaFX 应用程序的入口点是 Application 类。每当启动应用程序时,JavaFX 运行时都会按顺序执行以下操作:
- 构造指定 Application 类的实例
- 调用 init() 方法
- 调用 start(javafx.stage.Stage) 方法
- 等待应用程序完成,当以下任一情况发生时会发生这种情况:应用程序调用 Platform.exit() 最后一个窗口已关闭且 Platform 上的 implicitExit 属性为 true 调用 stop() 方法 注意 start 方法是抽象的,必须被覆盖。
因此,您需要生成一个类 - 使用博客文章中可以看到的 gen-class 宏 - 使用 start 方法来启动应用程序。
编辑:使用添加的 gen-class 方法链接到示例应用程序
我创建了一个Github 存储库,其中包含 Clojure 中的一个简单示例 JavaFX 应用程序。这是遵循 gen-class 方法的 Clojure 文件:
(ns jfx.app
(:import (javafx.beans.value ChangeListener ObservableValue)
(javafx.concurrent Worker$State)
(javafx.event ActionEvent EventHandler)
(javafx.scene Scene)
(javafx.scene.control Button)
(javafx.scene.layout StackPane)
(javafx.stage Stage)
(javafx.scene.web WebView)))
(gen-class
:name clj.jfx.App
:extends javafx.application.Application
:prefix "app-")
(defn app-start [app ^Stage stage]
(let [root (StackPane.)
btn (Button.)
web-view (WebView.)
state-prop (.stateProperty (.getLoadWorker (.getEngine web-view)))
url "http://clojure.org"]
;; Add a WebView (headless browser)
(.add (.getChildren root) web-view)
;; Register listener for WebView state changes
(.addListener state-prop
(proxy [ChangeListener] []
(changed [^ObservableValue ov
^Worker$State old-state
^Worker$State new-state]
(println (str "Current state:" (.name new-state)))
(if (= new-state Worker$State/SUCCEEDED)
(println (str "URL '" url "' load completed!"))))))
;; Load a URL
(.load (.getEngine web-view) url)
;; add a Button with a click handler class floating on top of the WebView
(.setTitle stage "JavaFX app with Clojure")
(.setText btn "Just a button")
(.setOnAction btn
(proxy [EventHandler] []
(handle [^ActionEvent event]
(println "The button was clicked"))))
(.add (.getChildren root) btn)
;; Set scene and show stage
(.setScene stage (Scene. root 800 600))
(.show stage)))
(defn app-stop
"Stop method is called when the application exits."
[app]
(println "Exiting application!")
)
(defn launch
"Launch a JavaFX Application using class clj.jfx.App"
[]
(javafx.application.Application/launch clj.jfx.App (into-array String [])))
必须编译 jfx.app命名空间才能启动应用程序,如果您直接在 REPL 中运行代码,这将不起作用。如果您想尝试代码,请按照项目的 README.md 文件中使用 Maven 和 Leiningen 设置 JavaFX 的说明进行操作。