【问题标题】:JavaFX print node at specific size特定大小的 JavaFX 打印节点
【发布时间】:2015-11-06 15:48:18
【问题描述】:

我正在通过改编以前编写的桌面程序来打印拼图,为一位家庭成员制作了一本打印拼图的书。我需要每个拼图都以特定尺寸打印,在这种情况下为 5" 正方形。我似乎无法找到一种可靠的方式以编程方式进行打印。

这是一个实现,它使用通过反复试验确定的缩放因子来缩放绘制拼图的画布。这是用 Clojure 编写的,但我认为任何使用 Java 的人都可以理解。

(defn create-print-button-click-handler
  "Handle a click on the 'Print...' button."
  [canvas stage]
  (reify EventHandler
    (handle [this event]
      (if false
        (batch-print)
        ;; else
        (let [job (PrinterJob/createPrinterJob)]
          (if (.showPrintDialog job stage)
            (let [printer (.getPrinter job)
                  job-settings (.getJobSettings job)
                  ;; Margin settings are in points. Set to half inch left margin,
                  ;; 3/4 inch for the rest.
                  layout (.createPageLayout printer Paper/NA_LETTER PageOrientation/PORTRAIT
                                            36.0 54.0 54.0 54.0)
                  printable-width (.getPrintableWidth layout)
                  printable-height (.getPrintableHeight layout)
                  printer-dpi (.getFeedResolution (.getPrintResolution job-settings))
                  dots-across (* printer-dpi 5) ;; five inches
                  cnvs (Canvas. dots-across dots-across)
                  scale 0.25]
              (.setPrintColor job-settings PrintColor/MONOCHROME)
              (.setPageLayout job-settings layout)
              ;; Scale by the same amount along both axes.
              (.add (.getTransforms cnvs) (Scale. scale scale))
              ;; This ugliness is because I want to print the background completely white.
              ;; Since we are using the same function to draw the board to the screen and
              ;; to the canvas for printing, we need to change the background before
              ;; drawing then back afterwards.
              (def board-color (Color/web "#ffffff"))
              (redraw-board cnvs)
              (def board-color (Color/web board-web-color))
              (.printPage job cnvs)
              (.endJob job))))))))

我见过一些使用可打印宽度和高度的示例,但我没有得到可以理解的结果(太大而无法容纳页面)。

就像我说的,这可行,但我希望程序在使用其他可能具有不同分辨率、不同水平和垂直分辨率等的打印机时正确响应。

【问题讨论】:

    标签: javafx clojure


    【解决方案1】:

    好吧,我想出了一些似乎可行的方法。这是一个MCVE,它展示了如何做到这一点。

    (ns printscaling.core
      (:gen-class
       :extends javafx.application.Application)
      (:import
       [javafx.application Application]
       [javafx.beans.value ChangeListener]
       [javafx.event EventHandler]
       [javafx.geometry Insets Pos]
       [javafx.print PrinterJob]
       [javafx.scene Scene]
       [javafx.scene.canvas Canvas]
       [javafx.scene.control Button]
       [javafx.scene.layout BorderPane Pane Region VBox]
       [javafx.scene.paint Color]
       [javafx.scene.transform Scale]
       [javafx.stage Screen]))
    
    (def points-per-inch 72.0)
    
    (defn redraw-board
      "Draw the board on the canvas."
      [canvas]
      (let [w (.getWidth canvas)
            h (.getHeight canvas)
            gc (.getGraphicsContext2D canvas)]
        
        (doto gc
          (.clearRect 0 0 w h)
          (.setLineWidth 3)
          (.setFill (Color/BLUE))
          (.setStroke (Color/BLUE))
          (.strokeRect 0 0 w h)
          (.strokeLine 0 0 w h)
          (.strokeLine w 0 0 h))))
    
    (defn create-print-button-handler
      "Handle a click on the 'Print' button. Print a 5 inch square version
       of the board."
      [stage]
      (reify EventHandler
        (handle [this event]
          (let [job (PrinterJob/createPrinterJob)]
            (if (.showPrintDialog job stage)
              (let [dpi (.getDpi (Screen/getPrimary))
                    pixels (* dpi 5)
                    canvas (Canvas. pixels pixels)
                    scale (/ points-per-inch dpi)]
                (.add (.getTransforms canvas) (Scale. scale scale))
                (redraw-board canvas)
                (if (.printPage job canvas)
                  (.endJob job))))))))
    
    (defn create-print-btn [stage]
      (let [btn (Button. "Print")]
        (.setOnAction btn (create-print-button-handler stage))
        btn))
    
    (defn -start
      "Build the application interface and start it up."
      [this stage]
      (let [root (BorderPane.)
            center (Pane.)
            spacer (Region.)
            btn-pane (VBox.)
            scene (Scene. root)
            canvas (Canvas.)
            print-btn (create-print-btn stage)]
    
        (doto (.widthProperty canvas)
          (.bind (.widthProperty center))
          (.addListener
           (reify ChangeListener
             (changed [_ _ _ _]
               (redraw-board canvas)))))
        (doto (.heightProperty canvas)
          (.bind (.heightProperty center))
          (.addListener
           (reify ChangeListener
             (changed [_ _ _ _]
               (redraw-board canvas)))))
        
        (doto btn-pane
          (.setId "btn-pane")
          (.setPadding (Insets. 10))
          (.setAlignment Pos/CENTER)
          (.setStyle "-fx-background-color: slategray;"))
    
        (.setPrefHeight spacer Integer/MAX_VALUE)
        (.addAll (.getChildren btn-pane) [print-btn spacer])
    
        (.add (.getChildren  center) canvas)
        (.setCenter root center)
        (.setRight root btn-pane)
    
        (doto stage
          (.setTitle "Print Scaling")
          (.setScene scene)
          (.setHeight 400)
          (.setWidth 600)
          (.show))))
    
    (defn -main [& args]
      (Application/launch printscaling.core args))
    

    在示例中,程序只是在屏幕上绘制了一个带有两条对角线的框来表示棋盘。

    当用户单击打印按钮时,程序会创建一个新的Canvas 对象用于打印。它根据显示屏的 dpi 调整画布的大小。在我的例子中,我想要一个 5" 的方板打印出来,这就是 (* dpi 5) 以显示器上的像素计算的。用于在屏幕上绘制板的相同函数用于在特别创建的 @ 上绘制它987654325@.

    缩放的技巧只是使用基于打印机每英寸点数 (72) 与显示器 dpi 的比率(通常为 96、120 或更多)的比例因子。将该比例因子添加到Canvas 上使用的变换中,会使电路板以所需的尺寸打印。这适用于不同分辨率的打印机。

    这尚未在具有不同 dpi 的多个显示设备上进行测试,因此我很想知道是否有人在此类设备上使用此方法得到不正确(或正确)的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多