我一直试图让http://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm在clojure中运行。
我发现通过省略java版本中的@FXML
注释并公开内容,
从:
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,我找不到让它工作的方法。我能够从java测试代码中访问final
(默认)deftype字段,但我见过的唯一在线讨论说你不能拥有公共和可变字段,并尝试:gen-class。好吧,我无法在gen-class中找到它,并且我能够找到的所有gen-class示例仅使用clojure中的类字段;我不确定如何在:gen-class中定义:state,以便可以从java访问它,而且我不知道如何使这些变为公共。
我的下一步是尝试使用clojure注释,然后使用fx:script字段而不是fx:controller来定义一个clojure回调...但是我想确保它对deftype或gen-是可行的/不可行的第一课。
有人可以告诉我是否可以在clojure中创建一个包含公共可变字段的java可访问类?
感谢。
答案 0 :(得分:3)
不,你不能在Clojure中定义公共可变字段。这适用于deftype
和gen-class
。
我想您可以尝试找出JavaFX是否愿意调用getter,如果是这样,请在Clojure中定义一些getFoo
方法。
答案 1 :(得分:0)
作为答案已经很晚了,但如果我发现这个问题,其他人也可能......:)
我偶然发现了OP的同一个问题(也就是说,我试图在javafx教程中复制cloML中的FXML示例),这是我的解决方案:
1)使用FXML中所需的所有方法创建一个接口,用于事件驱动的交互(在我的情况下只有一个,它反映了示例中间控制器中定义的方法):
(definterface MyFXMLControllerMethods
(^void handleSubmitButtonAction (^javafx.event.ActionEvent event )))
2)然后使用deftype
实例化一个实现接口的新java类型,这是一个很好的事情,用@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
手动初始化每个字段(有效,我尝试过)或使用内省(没有尝试过)。
希望这有帮助