Graphics2D.drawString,带有来自Clojure的浮点参数



我创建了这个Java示例代码的Clojure实现,它绘制了一个PNG图像。我的Clojure版本如下。它是有效的,但是如果我drawString()的参数强制为整数,Clojure编译器会抛出一个错误。API文档显示Graphics2D.drawString()接受float参数,但其超类Graphics.drawString()不接受。我如何说服/tick/inmit Clojure使用drawString()的浮动版本?

(defn render-image [message]
(let [width 200 height 200
bi (java.awt.image.BufferedImage. width height java.awt.image.BufferedImage/TYPE_INT_ARGB)
font (java.awt.Font. "TimesRoman" java.awt.Font/BOLD 20)
ig (doto ^java.awt.Graphics2D (.createGraphics bi) (.setFont font))
metrics (.getFontMetrics ig)
str-width (.stringWidth metrics message)
str-height (.getAscent metrics)]
(doto ig
(.setPaint java.awt.Color/BLACK)
;; Compiler complains if x- and y-arguments to .drawString
;; are not integers. Why?
(.drawString message
(int (/ (- width str-width) 2))
(int (+ (/ height 2) (/ str-height 4)))))

bi))
(defn -main [filename]
(-> (render-image "Hello world")
(javax.imageio.ImageIO/write "PNG" (java.io.File. filename))))

运行时(而不是编译器(必须决定使用.drawString的哪些重载。它愿意自动执行的转换集可以在Reflector.java中找到。请注意,对于声明为float(如您希望调用的(的方法参数,它只接受floatFloatdouble。但是两个整数的除法结果是一个有理数。因此,float方法不适用。int方法也没有,因为同样没有从有理到int的自动转换。

你可以在一个简单得多的案例中看到同样的事情:(Float/valueOf (/ 1 2))

由于没有自动转换,因此必须显式转换。您使用int成功地做到了这一点,但显然您不想调用int方法。解决方案很简单:改为使用float进行转换。

drawstring调用更改为

(.drawString message
(float (/ (- width str-width) 2))
(float (+ (/ height 2) (/ str-height 4)))))

最新更新