2

我一直在尝试让http://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm在 clojure 中运行。

我发现通过省略@FXMLjava 版本中的注释并将内容公开,来自:

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

到:

public class FXMLExampleController {
    public Text actiontarget;  
    public void handleSubmitButtonAction(ActionEvent event) {
        actiontarget.setText("Sign in button pressed");
    }
}

...当我单击按钮时它基本上仍然有效,并且 fxml 能够到达控制器的public Text actiontarget,其访问通常只能通过@FXML注释启用。

所以我试图让我的基于 clojure 的控制器类具有公共可变字段,但是在过去几个小时通过 :gen-class 和 deftypes 寻找时,我找不到让它工作的方法。我能够final从 java 测试代码访问(默认)deftype 字段,但我看到的唯一在线讨论说你不能有公共和可变字段,并尝试 :gen-class。好吧,我在 gen-class 中也找不到,而且我能找到的所有 gen-class 示例都仅使用 clojure 中的类字段;我不确定如何在 :gen-class 中定义 :state 以便可以从 java 访问它,而且我不知道如何使这些可变和公开。

我的下一件事是尝试 clojure 注释,然后使用 fx:script 字段而不是 fx:controller 来定义 clojure 回调......但我想确保它首先使用 deftype 或 gen-class 是可行/不可行的。

那么有人可以告诉我是否可以在 clojure 中创建一个具有公共可变字段的 Java 可访问类?

谢谢。

4

2 回答 2

3

不,您不能在 Clojure 中定义公共可变字段。这适用于deftypegen-class

我想您可以尝试找出 JavaFX 是否愿意调用 getter,如果是,请getFoo在 Clojure 中定义一些方法。

于 2013-05-19T16:08:31.317 回答
1

作为一个答案很晚了,但如果我发现这个问题其他人也可能...... :)

我偶然发现了 OP 的同样问题(也就是说,我试图在 clojure 中复制 javafx 教程中的 FXML 示例),这是我的解决方案:

1)创建一个接口,其中包含我的 FXML 中用于事件驱动交互的所有方法(在我的例子中只有一个,它反映了示例中间控制器中定义的方法):

(definterface MyFXMLControllerMethods                                                                                                                 
  (^void handleSubmitButtonAction (^javafx.event.ActionEvent event )))

2)然后使用实例化一个新的实现接口的java类型,这很漂亮,用注释deftype定义一个私有的可变字段:@FXML

(deftype MyFXMLController [^{:volatile-mutable true javafx.fxml.FXML true} actiontarget]
    MyFXMLControllerMethods
        (^void handleSubmitButtonAction [this ^javafx.event.ActionEvent event]
            (.setText actiontarget "Sign in button pressed!"))
    Initializable
        (^void initialize [this ^java.net.URL location ^java.util.ResourceBundle resources]
          (assert (not= actiontarget nil)))) ; this test passes! =)

正如 OP 正确指出的那样,这是允许 FXML 加载器通过自省访问控制器私有字段的关键。

这种方法真正好的地方在于它不需要静态编译,因此除了 之外Application class,其他一切都可以是动态的。

其他解决方案可能涉及手动初始化每个字段lookup(工作,我尝试过)或使用自省(没有尝试过)。

希望这可以帮助

于 2016-08-27T19:48:05.133 回答