【问题标题】:Can't load FXML in Clojure using FXMLLoader无法使用 FXMLLoader 在 Clojure 中加载 FXML
【发布时间】:2013-05-13 11:27:57
【问题描述】:

我正在尝试实现此处显示的基本 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

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

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

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

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

谢谢

【问题讨论】:

    标签: clojure javafx fxml


    【解决方案1】:

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

    (FXMLLoader/load ...)
    

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

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

    【讨论】:

    • 谢谢,使用静态方法有效。但是,当我直接尝试 (.getResource (.getClass this) "fxml_example.fxml") 而不是 clojure.java.io/resource 时,它返回 nil 并且加载失败。没关系,我会坚持有效的。
    【解决方案2】:

    我能够通过单独创建 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))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 2021-04-27
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      相关资源
      最近更新 更多