1

我正在尝试实现此处显示的基本 JavaFX 示例:http: //docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm。我能够让基本的东西工作(以编程方式创建 gui)并使用 css,但我在使用 FXMLLoader 时遇到了问题。

java版本是这样的:

@Override
public void start(Stage stage) throws Exception {
   Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));

    stage.setTitle("FXML Welcome");
    stage.setScene(new Scene(root, 300, 275));
    stage.show();
}

我不是 Java 专家,但我不认为 FXMLLoader 对象是实例化的,即。没有new FXMLLoader();声明。那么从哪里来load呢?

当我尝试以下 clojure 代码时:

(ns jfxtwo.core
  (:gen-class
   :extends javafx.application.Application)

  (:import (javafx.application Application)
           (javafx.fxml FXMLLoader)
           (javafx.scene Parent Scene)
           (javafx.stage Stage)))

(defn -main []
  (javafx.application.Application/launch jfxtwo.core (into-array String [])))

(defn -start [this primaryStage]
  (let [loc (clojure.java.io/resource "fxml_example.fxml")
        root (.load FXMLLoader ^java.net.URL loc)
        scene (Scene. root 300 250)]
    (.setScene primaryStage scene)
    (.show primaryStage)))

...我明白了Caused by: java.lang.IllegalArgumentException: No matching method found: load for class java.lang.Class

所以我在 FXMLLoader 之后放了一个点来创建一个实例:(FXMLLoader.)我明白了:ClassCastException java.net.URL cannot be cast to java.io.InputStream

所以这告诉我我正在做一些事情,因为loadFXMLLoader 的方法之一支持 InputStream。我尝试强制编译器知道资源是 java.net.URL 因为这是支持的重载之一FXMLLoader.load,通过将调用(clojure.java.io/resource...)直接放在调用中(.load...)但它仍然不喜欢它(我知道它很长射击)。我也尝试过类型提示(.load (FXMLLoader.) ^java.net.URL loc)(.load (FXMLLoader.) #^java.net.URL loc),但没有骰子;它仍然尝试使用 java.io.InputStream 版本的load.

在 java 中还有 getClass() 调用,我认为它正在获取 Application 的超类,但我不确定在 clojure-land 中如何处理它。

关于如何加载 fxml 文件的任何想法?

之后,java 代码具有@FXML允许 FXML 进入私有类成员的注释。这在 clojure 中是否必要(删除时 java 代码中断)?@Override 注释似乎没有在 clojure 中使用。

谢谢

4

2 回答 2

1

我能够通过与设置位置分开创建 FXMLLoader 来解决我的问题。

(defn -start [this primaryStage]
  (let [loc (clojure.java.io/resource "fxml_example.fxml")
        fxmlloader (FXMLLoader.)]
    (.setLocation fxmlloader loc) 
    (let [root (.load fxmlloader )
          scene (Scene. root 300 250)]
      (.setScene primaryStage scene)
      (.show primaryStage))))
于 2013-05-18T15:57:01.130 回答
1

鉴于 Java 语法,load此处调用的方法似乎是FXMLLoader该类的静态方法。要在 Clojure 中调用静态方法,您需要使用(ClassName/methodName args...)语法:

(FXMLLoader/load ...)

(刚刚检查:FXMLLoader具有多个签名的静态方法和实例load方法。您需要调用与 Java 代码相同的方法;将使用FXMLLoader.loadJava 中的语法调用静态方法,实例方法 -- someFXMLLoaderInstance.load。)

至于getClass方法调用,它的目标隐含this在Java中;在 Clojure 中,您必须明确目标 ( (.getClass this))。

于 2013-05-18T11:25:54.253 回答