2016-09-11 5 views
1

Я пытаюсь понять, как правильно настроить JavaFX для работы с проектом Clojure. Читая различные источники, это то, что я придумал:Написание проекта 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}}) 

Я не знаю, если я должен использовать: ресурсные пути или добавить 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

ответ

2

Там могут быть и другие проблемы, но корень проблемы в журнале Pastebin является:

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

При использовании GEN-класса и обеспечение реализации методов, каждый метод необходимо взять экземпляр как первый параметр. Соглашение состоит в том, чтобы использовать «это»:

(defn -start [this primaryStage] 

Попробуйте сделать это, и убедитесь, что местные вызовы методов экземпляра применяются к «это».

+1

Мой плохой, я не знал этого ... но что вы имеете в виду с помощью методов локального экземпляра? должен ли [this & args] вместо [& args]? Я заметил, что добавление «this» в -start заставляет его работать, но я не могу использовать его в -main вместо cljfx.core, не так ли? –

+1

Нет, main является публичным статиком, как глобальная функция. Пространство имен, в котором он живет, указано в project.clj. start, otoh, является методом экземпляра приложения. Он имеет только видимость для конкретного экземпляра или копию полей, доступных в классе Application. Во всяком случае, другое место, где это может понадобиться, - это метод дескриптора, возможно, он должен быть (обрабатывать [это событие] ... поскольку то, что создается, является экземпляром EventHandler. –

+1

Хм хорошо ... как насчет project.clj? Я до сих пор не могу скомпилировать проект с «lein run» (он выдает исключение ClassNotFound с cljfx.core ... странным), но он работает, если я создаю uberjar, а затем запускаю его как java-программу. Должен ли я использовать: пути ресурсов или зависимости для добавления javafx? –