   "The number of pixels to keep blank between labels of adjacent buttons."
   4)
 
+(defn string-width
+  "Determines how many pixels wide a string will be in a given font
+  and render context."
+  [text font render-context]
+  (.getWidth (.getStringBounds font text render-context)))
+
 (defn fit-string
   "Truncates a string (appending an ellipsis) enough to fit within a
   given pixel width."
-  [text font-metrics max-width]
-  (if (or (clojure.string/blank? text) (<= (.stringWidth font-metrics text) max-width))
+  [text font render-context max-width]
+  (if (or (clojure.string/blank? text) (<= (string-width text font render-context) max-width))
     text
     (loop [truncated (subs text 0 (dec (count text)))]
       (let [result (str truncated "…")]
-        (if (or (clojure.string/blank? truncated) (<= (.stringWidth font-metrics result) max-width))
+        (if (or (clojure.string/blank? truncated) (<= (string-width result font render-context) max-width))
           result
           (recur (subs truncated 0 (dec (count truncated)))))))))
 

  [controller index encoder-count text color]
  (let [graphics (create-graphics controller)
        space (space-for-encoder-button-label encoder-count)
        metrics (.getFontMetrics graphics font-for-encoder-button-label)
        label (fit-string text metrics space)
        width (.stringWidth metrics label)]
    (set-graphics-color graphics color)
    (.setFont graphics font-for-encoder-button-label)
    (.drawString graphics label

(defn calculate-text-width
  "Figure out how many pixels wide some text will be in a given font."
  [graphics font text]
  (let [context (.getFontRenderContext graphics)]
    (.getWidth (.getStringBounds text context))))

(defn draw-bottom-button-label
  "Draw a label for a button below the graphical display."
  [controller index text color]
  (let [graphics (create-graphics controller)
        font (get-display-font :roboto-medium Font/BOLD 14)
        context (.getFontRenderContext graphics)
        label (fit-string text font context (- button-cell-width button-cell-margin))
        width (string-width label font context)]
    (set-graphics-color graphics color)
    (.setFont graphics font)
    (.drawString graphics label (int (math/round (- (* (+ index 0.5) button-cell-width) (/ width 2))))
