Clojure和JavaFX 2 - 将多个arity参数传递给JavaFX方法

时间:2013-05-29 11:52:42

标签: java clojure javafx-2 variadic-functions clojure-java-interop

许多JavaFx方法采用var args,例如Group,它在Java中声明为:

public Group(Node... children)

其他例如:

public KeyFrame(Duration time, KeyValue... values)

我发现...意味着我应该将java数组传递给方法,所以我一直在做这样的事情,

(-> timeline .getKeyFrames 
  (.addAll 
    (into-array [(KeyFrame. blabla) (KeyFrame. blabla)]))`

每次有一个var arg时都要做(into-array...)很烦人,当var arg是我实际传入的基类时,它会更烦人。例如

(Group. (into-array [(Circle. 100) (Rectangle. 100 100)]))

导致类型不匹配错误。相反,我必须这样做:

(Group. (into-array Node [(Circle. 100) (Rectangle. 100 100)]))

所以我做了这个功能:

(defn make-group [& items]
  (Group. (into-array Node items)))

这适用于群组,但不能解决一般问题。

那么解决省略号/ vararg问题有一个很好的方法,所以我不必为每个vararg方法创建特殊函数吗?这个函数的要求是它需要你想要调用的方法(例如Group),固定的args,var args,并且不知何故,函数会知道找到元素的公共基类。 var args。

由于

2 个答案:

答案 0 :(得分:2)

您是否尝试将参数放入向量中?我没有尝试过你提到的所有用例,但是当我使用addAll()方法时,我只是将参数放入一个文字向量中,例如。

    (.addAll (.getChildren btn-pane) [new-puzzle-pane check-box hint-btn
                                  check-btn solve-btn load-btn save-btn
                                  print-btn about-btn spacer])

答案 1 :(得分:1)

我使用了一个宏,我怀疑我需要它:

(defmacro jvar [method & args]
  (let [lastargs (last args)
        evaled-lastargs (eval lastargs)]
    (if (coll? evaled-lastargs)
      (let [firstargs (butlast args)
            klass (eval (last firstargs))
            supset (map #(supers (class %)) evaled-lastargs)
            common (apply intersection #{klass} supset)]
        (if (seq common)
          `(~method ~@(butlast firstargs) (into-array ~(first common) ~lastargs))
          `(~method ~@firstargs (into-array ~lastargs)))))))

这样的用法:

(jvar Group. Node [(Circle. 100) (Rectangle. 10 10)])