Graphics2D.drawString 带有来自 Clojure 的浮点参数
Graphics2D.drawString with float arguments from Clojure
我创建了这个 Java sample code that draws a PNG image. My Clojure version is below. It works, but the Clojure compiler throws an error if I don't coerce drawString()
's arguments to integers. The API docs show that Graphics2D.drawString()
accepts float arguments but its superclass, Graphics.drawString()
的 Clojure 实现,但没有。我如何 convince/trick/hint 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
(如您所愿调用)的方法参数,它仅接受 float
、Float
和 double
。但是两个整数相除的结果是有理数。因此,float
方法不适用。 int
方法也没有,因为同样没有从有理数到 int
.
的自动转换
您可以在更简单的情况下看到同样的事情发生:(Float/valueOf (/ 1 2))
。
由于没有自动转换,您必须显式转换。您使用 int
成功地做到了这一点,但显然您不想调用 int
方法。解决方案很简单:改为使用 float
进行转换。
将您的 drawstring
调用更改为
(.drawString message
(float (/ (- width str-width) 2))
(float (+ (/ height 2) (/ str-height 4)))))
我创建了这个 Java sample code that draws a PNG image. My Clojure version is below. It works, but the Clojure compiler throws an error if I don't coerce drawString()
's arguments to integers. The API docs show that Graphics2D.drawString()
accepts float arguments but its superclass, Graphics.drawString()
的 Clojure 实现,但没有。我如何 convince/trick/hint 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
(如您所愿调用)的方法参数,它仅接受 float
、Float
和 double
。但是两个整数相除的结果是有理数。因此,float
方法不适用。 int
方法也没有,因为同样没有从有理数到 int
.
您可以在更简单的情况下看到同样的事情发生:(Float/valueOf (/ 1 2))
。
由于没有自动转换,您必须显式转换。您使用 int
成功地做到了这一点,但显然您不想调用 int
方法。解决方案很简单:改为使用 float
进行转换。
将您的 drawstring
调用更改为
(.drawString message
(float (/ (- width str-width) 2))
(float (+ (/ height 2) (/ str-height 4)))))