我正在通过调整以前编写的桌面程序打印谜题,为家庭成员创建一本印刷谜题书。我需要在特定尺寸下打印每个拼图,在这种情况下为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))))))))
我见过一些使用可打印宽度和高度的例子,但我没有得到可理解的结果(太大而不适合页面)。
就像我说的,这有效,但我希望程序在使用其他可能具有不同分辨率,不同水平和垂直分辨率等的打印机时能够正确响应。
答案 0 :(得分:0)
好吧,我想出了一些似乎有用的东西。这是一个显示如何操作的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)
根据显示器上的像素计算的内容。用于在屏幕上绘制板的相同功能用于在特殊情况下绘制它创建了Canvas
。
缩放的技巧只是使用基于每英寸打印机点数(72)与显示器dpi(通常为96,120或更高)之比的缩放系数。将该缩放因子添加到Canvas
上使用的变换会导致电路板以所需大小打印。这适用于具有不同分辨率的打印机。
目前尚未对具有不同dpi的多个显示设备进行测试,因此我非常希望听到有人在这些设备上使用此方法获得不正确(或正确)的结果。