2

遵循此处的 JavaFX 教程:http: //docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm,尝试使其在 Clojure 中运行。现在我只是lein run在设置:aot :all和使用(:gen-class)等之后才做。花了几天的时间弄清楚,但现在它似乎大部分都在工作。

src/jfxtwo/ClojureExampleController.clj

(defn -handleSubmitButtonAction [^ActionEvent event]
  (let [actiontarget (Text.)]
    (println "event button pressed")
    (println "Event instance:" event)
    (println "Event class:" (class event))
    (.setText actiontarget "Sign in button pressed...")))

resources/fxml_example.fxml

<GridPane fx:controller= "jfxtwo.ClojureExampleController"
      xmlns:fx= "http://javafx.com/fxml" 
      alignment= "center" hgap= "10" vgap= "10"
      styleClass= "root" >
...
    <Button text= "Sign In"
    onAction= "#handleSubmitButtonAction" />

...
    <Text fx:id= "actiontarget"
        GridPane.columnIndex= "1" GridPane.rowIndex= "6" />
...

我的 clojure 代码能够读取 fxml 和 css 文件以生成正确的 GUI。当我按下按钮时,我可以看到正在调用的事件处理程序,但我不知道如何访问Text我想要更改的,或者ActionEvent与按钮按下相关联的实例。我尝试(println event)(println (class event))期望看到有关ActionEvent实例的某些信息,但这只会向我展示无论出于何种原因,回调函数都认为该事件是 a ClojureExampleController,即使类型提示说它应该是 a ActionEvent

event button pressed
Event instance: #<ClojureExampleController jfxtwo.ClojureExampleController@3e61061d>
Event class: jfxtwo.ClojureExampleController

执行此操作的 Java 代码如下所示:

public class JFXAppSampleController  {
   @FXML private Text actiontarget;
   @FXML protected void handleSubmitButtonAction(ActionEvent event) {
       actiontarget.setText("Sign in button pressed");
   }
}

清除@FXML注释在这里起到了神奇的作用。发生了什么事,我如何在 Clojure 中完成这项工作?

此外,有没有办法将按钮按下直接绑定到 FXML 中的文本更改,所以我真的不必在代码隐藏中处理 gui->gui 更改,而只需处理与按钮按下?我猜是的,但我在教程中还没有达到这一点。

谢谢!

4

1 回答 1

1

您的处理程序中需要一个显式this参数:

(defn -handleSubmitButtonAction [this ^ActionEvent event]
  ...)

也许更准确的说法是问题文本中显示的处理程序event this参数,您需要添加第二个参数以接受事件并将类型提示移至它(并可能将第一个参数重命名为this为了可读性)。

鉴于您的代码完全被调用的事实,如果 JavaFX 不关心它,它似乎很乐意调用处理程序而不将事件传递给它(如没有与之对应的形式参数所证明的那样) .

类型提示的唯一目的是允许 Clojure 编译器在ActionEvent调用方法时避免发出反射代码event。这不会阻止将不同类型的对象传递给函数。

于 2013-05-19T07:17:42.110 回答