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 を調べても、それを機能させる方法が見つかりません。Java テスト コードから (デフォルトの) deftype フィールドにアクセスできましfinalたが、私が見た唯一のオンライン ディスカッションでは、public および mutable フィールドを持つことはできず、:gen-class. まあ、gen-class でもそれを見つけることはできません。私が見つけたすべての gen-class の例では、clojure 内からのみクラス フィールドを使用しています。java からアクセスできるように :gen-class で :state を定義する方法がわかりません。また、それらを変更可能にして公開する方法もわかりません。

私の次のことは、clojure アノテーションを試してから、fx:controller ではなく fx:script フィールドを使用して clojure コールバックを定義することです...しかし、最初に deftype または gen-class で実行可能/実行不可であることを確認したいと思います。

クロージュアで公開可変フィールドを持つJavaアクセス可能なクラスを作成することが可能かどうか誰か教えてもらえますか?

ありがとう。

4

2 に答える 2

3

いいえ、Clojure で public 可変フィールドを定義することはできません。deftypeそれは と の両方に当てはまりますgen-class

JavaFX が getter を喜んで呼び出すかどうかを試してみて、もしそうなら、getFoo代わりに Clojure でいくつかのメソッドを定義することができると思います。

于 2013-05-19T16:08:31.317 に答える
1

答えとしてはかなり遅いですが、この質問を見つけたら、他の人も同様かもしれません... :)

OPの同じ問題に遭遇しました(つまり、javafxチュートリアルのFXMLの例をclojureで複製しようとしています)。これが私の解決策です:

1) イベント駆動型の相互作用のために FXML で必要なすべてのメソッドを含むインターフェイスを作成します (私の場合は 1 つだけで、例の途中でコントローラーで定義されたメソッドを反映しています)。

(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 に答える