【问题标题】:Writing a JavaFX project in Clojure在 Clojure 中编写 JavaFX 项目
【发布时间】:2016-09-11 23:03:17
【问题描述】:

我正在尝试了解如何正确设置 JavaFX 以使用 Clojure 项目。通过阅读各种来源,这是我想出的:

这是project.clj:

(defproject cljfx "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :resource-paths ["lib/jfxrt.jar"]
  :main ^:skip-aot cljfx.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

我不知道我应该使用 :resource-paths 还是通过 :dependencies 向量将 JavaFX 添加到类路径...

这是 core.clj:

我基本上已经将本教程中的一个示例翻译成 Clojure:

http://docs.oracle.com/javafx/2/get_started/hello_world.htm

(ns cljfx.core
  (:gen-class
    :extends javafx.application.Application)
  (:import
    [javafx.application Application]
    [javafx.stage Stage]
    [javafx.scene Scene]
    [javafx.scene.control Button]
    [javafx.scene.layout StackPane]
    [javafx.event ActionEvent EventHandler]))


(defn -main [& args]
  (Application/launch cljfx.core args))

(defn button [text]
  (doto (Button.)
    (.setText (str "Say " text))
    (.setOnAction (proxy [EventHandler] []
                    (handle [event]
                      (println text))))))

(defn -start [primaryStage]
  (let [root (doto (StackPane.)
               (-> (.getChildren)
                   (.add (button "Hello World!"))))]
    (doto primaryStage
      (.setScene (Scene. root 300 250))
      (.show))))

这不能编译,我也不知道自己做错了什么……你能帮帮我吗?

这是错误: http://pastebin.com/sYeK7MJd

【问题讨论】:

    标签: javafx clojure leiningen


    【解决方案1】:

    可能还有其他问题,但是pastebin日志中的根本问题是:

    Caused by: clojure.lang.ArityException: Wrong number of args (2) passed to: core/-start
    

    在使用 gen-class 并提供方法实现时,每个方法都需要将实例本身作为第一个参数。约定是使用“this”:

    (defn -start [this primaryStage] 
    

    尝试一下,并确保将本地实例方法调用应用于“this”。

    【讨论】:

    • 我的错,我不知道...但是本地实例方法是什么意思? -main 应该有 [this & args] 而不是 [& args]?我注意到在 -start 中添加 'this' 可以使其工作,但我不能在 -main 中使用它来代替 cljfx.core,可以吗?
    • 不,main 是一个公共静态,就像一个全局函数。它所在的命名空间在 project.clj 中指定。 start,otoh,是一个 Application 实例方法。它仅对 Application 类中可用字段的特定实例或副本具有可见性。无论如何,可能需要 this 的另一个地方是在 handle 方法中,它可能需要是 (handle [this event]... 因为正在创建的是 EventHandler 的实例。
    • 嗯好吧...project.clj 呢?我仍然无法使用 'lein run' 编译项目(它会抛出一个带有 cljfx.core 的 ClassNotFound 异常......奇怪),但如果我构建 uberjar 然后将其作为 java 程序运行......我应该使用它吗? :resource-paths 或 :dependencies 添加 javafx?
    • 擦除项目并使用 :resource-paths 现在可以工作,但我仍然不知道为什么以前没有
    • 问题可能出在使用“aot”或提前编译。问题的症结在于有两种依赖解析机制——clojure 命名空间和 java 类路径。这些可能会以奇怪且有时不恰当的方式进行交互,需要巧妙地使用 aot。简短版本是 - project.clj 中的 ^skip-aot 子句可能是错误的,应该删除(我认为),并在重大更改之间使用“lein clean”来清理从 clojure 源生成的编译类文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2013-10-01
    相关资源
    最近更新 更多