2017-10-23 1 views
2

Clojure를 사용하여 .jar 파일에서로드 할 Gluon SceneBuilder에 사용할 사용자 정의 JavaFX 구성 요소를 작성하려고합니다. 즉, SceneBuilder에서 사용자 정의 클래스로 .jar를 가리키고 왼쪽에있는 드래그 가능한 항목 목록에 해당 항목을 표시하고 싶습니다.Gluon SceneBuilder가 JAR 파일에서 찾는 것은 무엇입니까?

시각적 구조가 FXML로만 표시되도록 할 수는 있지만 일부 동작도 포함하고 싶습니다.

내 Clojure의 소스에 (:gen-class) 물건을 lein uberjar를 실행하고 FXML에서 fx:root 구조를 사용한 후, 나는 공식 자바 example의 수정 된 버전에서 생성 된 클래스를 사용할 수 있어요.

CustomControlExample에서 사용자 정의 클래스를 인스턴스화하면 printlns 및 기타 그래픽을 통해 실행되는 Clojure 초기화 코드의 증거를 볼 수 있습니다.

그래서 내 사용자 정의 클래스가 정상적으로 작동하는 것 같습니다. 그것은 두 개의 생성자 - String 인수가 있거나 없는데 HBox에서 확장됩니다. 결과적으로 NetBeans에서 .class 파일을 볼 때 JarExplorer를 사용할 때이를 확인할 수 있습니다. 클래스에는 Clojure 생성 클래스가 있기 때문에 톤이 더 많지만 예제와 최소한 동일한 수와 유형의 생성자가 있습니다.

uberjar 파일을 가져 오면 내 사용자 지정 구성 요소가 SceneBuilder에 표시되지 않는 문제가 있습니다.

그래서 정확히은 SceneBuilder가 클래스에서 볼 때 맞춤 드래그 가능한 구성 요소로 보이게해야합니까?

다음은 내 소스 파일 (FX 런타임 시작을 다루는 유틸리티 라이브러리 포함)의 관련 부분입니다.

SRC/toyui/GridSettingsPane.clj는 :

(ns toyui.GridSettingsPane 
    (:gen-class 
    :extends javafx.scene.layout.HBox 
    :post-init post-init 
    :init init 
    :constructors {[] [] 
        [String] []}) 
    (:use [jfxutils.core :exclude [-main]])) 


(defn -init 
    ([] 
    (-init "unnamed-init")) 
    ([name] 
    (println "hi from -init") 
    [[] []])) 

(defn -post-init 
    ([this] 
    (-post-init this "unnamed-post-init")) 
    ([this name] 
    (println "hi from -post-init") 
    (jfxutils.core/app-init) 
    (let [loader (javafx.fxml.FXMLLoader. (clojure.java.io/resource "GridSettingsPane.fxml"))] 
    (.setRoot loader this) 
    (.setController loader this) 
    (.load loader) 
    loader)))) 
+0

아마도 구성 요소의 너비와 높이가 필요합니다. –

+0

흠,'(.setWidth this 800)'및'(.setHeight this 600)'만 추가했지만 시가는 없습니다. 나는 SceneBuilder 코드를 파헤쳐서 무엇이 일어나는지 살펴볼 것이다. – Sonicsmooth

+0

JarExplorer.java에서'Thread.currentThread(). setContextClassLoader (classLoader);'를'instantiateWithFXMLLoader (...)'에 추가하면 즉각적인 문제는 해결되지 않았지만 이제는 IllegalStateException "Location is not set" FXML 로더에서. 아마 더 많은 classpath stuff ... – Sonicsmooth

답변

0

나는 SceneBuilder 일부 실시간 클래스 로딩을 사용하는 것을 발견했다. Clojure의 기본값은 *use-context-classloader* = true이므로 위의 내 코멘트와 같이 장면 코드를 약간 수정하여 클래스를로드 할 수있었습니다. 그러나 그것은 여전히 ​​몇 가지 유형의 자원을 찾는 데 어려움을 겪고있었습니다. 나는 그것이 아마 클래스 경로와 그 것이기 때문에 아직도 있었다고 상상했다.

과정에서 나는 SceneBuilder가 다른 것들 중에서 특히 <?import toyui.GridSettingsPane?>이라고 말한 작은 FXML 파일 (실제로는 스트림)을 동적으로 생성하고 해당 스트림에 일반 FXML 로더를 실행한다는 것을 발견했습니다.

그래서 가서 .fxml 파일 내에서 Clojure 클래스를 가져 오도록 FXMLExample을 수정했습니다.

결론은 그렇습니다. 일반 프로그램에서 실행할 때 내 클래스는 FXML에서 그대로 작동하지만 jar 탐색기를 찾을 때 어떤 이유로로드되지 않습니다.

관련 문제