在leiningen主要返回后继续运行应用程序

时间:2014-12-03 20:59:04

标签: clojure javafx leiningen

在我的clojure应用程序中,我有一个JavaFX窗口,应用程序在main函数返回后关闭。我希望应用程序在用户关闭窗口之前保持打开状态(或从菜单中选择"退出"或其他内容)。

我该怎么做?

这里是core.clj文件,最后20行是相关的:

(ns pdb-java-client.core
  (:gen-class)
  (:import (javafx.scene.control LabelBuilder)))



;; JavaFX UI

(import '(javafx.scene SceneBuilder)
        '(javafx.scene.canvas CanvasBuilder Canvas GraphicsContext)
        '(javafx.scene.control ButtonBuilder)
        '(javafx.scene.layout VBoxBuilder)
        '(javafx.scene.image WritableImage PixelWriter)
        '(javafx.scene.transform Scale Translate)
        '(javafx.stage StageBuilder))

; instead of extending javafx.application.Application
(defonce force-toolkit-init (javafx.embed.swing.JFXPanel.))

; some helper functions and macros to make JavaFX easier to type
(defn run-later*
  [f]
  (javafx.application.Platform/runLater f))

(defmacro run-later
  [& body]
  `(run-later* (fn [] ~@body)))

(defn run-now*
  [f]
  (let [result (promise)]
    (run-later
      (deliver result (try (f) (catch Throwable e e))))
    @result))

(defmacro run-now
  [& body]
  `(run-now* (fn [] ~@body)))

(defn event-handler*
  [f]
  (reify javafx.event.EventHandler
    (handle [this e] (f e))))

(defmacro event-handler [arg & body]
  `(event-handler* (fn ~arg ~@body)))

(def stage (atom nil))

; build a scene
(run-now (reset! stage (.. StageBuilder create
                           (title "Fracjure")
                           (scene (.. SceneBuilder create
                                      ;(height 480) (width 640)
                                      (root (.. VBoxBuilder create
                                                ;(minHeight 480) (minWidth 640)
                                                (children [(.. LabelBuilder create
                                                               (text "Hello World!")
                                                               build)])
                                                build))
                                      build))
                           build)))

;(run-now (.show @stage))


(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!")
  (run-now (.show @stage)))

请注意,上面的代码可以工作,显示的是JavaFX窗口" Hello World!"," Hello,World!"打印到终端,然后程序退出。

2 个答案:

答案 0 :(得分:0)

将最后一行更改为

(run-now (.showAndWait @stage)))

答案 1 :(得分:0)

另一种可能性,也许是更健壮和符合标准,是提供JavaFX Application类的实现。

您可以在Leiningen项目中包含Java代码

package mypackage;

import javafx.application.Application;
import javafx.stage.Stage;

public class MyApplication extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        // Do nothing. This is just to get JavaFX started properly.
    }
    public static void initJavaFXApplication() {
        Application.launch();
    }
}

然后从Clojure打来电话:

(MyApplication/initJavaFXApplication)

Leiningen通过在project.clj文件中添加以下行来支持Java和Clojure源:

:source-paths ["src/clojure"]
:java-source-paths ["src/java"]

并相应地更新您的目录结构。