Se si legge JavaFX Application class documentation, si noterà che la classe Application è una classe astratta, che non può essere istanziata direttamente. Ciò significa che devi almeno creare una sottoclasse di javafx.application.Application.
del ciclo di vita
Il punto di ingresso per applicazioni JavaFX è la classe Application. Il JavaFX runtime fa seguito, in ordine, ogni volta che un'applicazione è lanciato:
- Costruisce un'istanza della classe Application specificato
- Chiama il metodo init()
- Chiamate l'inizio (JavaFX. stage.Stage)
- Attende il completamento dell'applicazione, che si verifica quando si verifica uno dei seguenti numeri : l'applicazione chiama Platform.exit() l'ultima finestra è stata chiusa e l'attributo implicitExit su Platform è true Chiama il 012.metodo stop() Si noti che il metodo di avvio è astratto e deve essere sottoposto a override .
Pertanto è necessario generare una classe - utilizzando la macro Gen-classe come si può vedere nel post del blog - con un metodo di avvio per poter avviare l'applicazione.
Modifica: collegamento a un'applicazione di esempio utilizzando l'approccio classe gen aggiunto
Ho creato un Github repository with a simple example JavaFX application in Clojure. qui è il file Clojure seguendo l'approccio gen-classe:
(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 [])))
Il jfx.app namespace deve essere compilato per lanciare l'applicazione, questo non funzionerà se si esegue il codice nella REPL direttamente. Se si desidera provare il codice, seguire le istruzioni per l'impostazione di JavaFX con Maven e Leiningen nello project's README.md file.
fonte
2012-08-17 17:22:16
Come si avvia il repl? A causa della dipendenza del runtime JavaFX, jfxrt.jar deve trovarsi sul classpath. Hai creato un progetto usando Leiningen? –