特定大小的JavaFX打印节点
我正在为一个家庭成员制作一本打印拼图的书,通过修改以前编写的桌面程序来打印拼图。我需要每个拼图打印在一个特定的大小,在这种情况下5平方米。我似乎找不到一种可靠的编程方法 下面是一个实现,它使用由反复试验确定的比例因子来缩放绘制拼图的画布。这是用Clojure编写的,但我认为任何使用Java的人都可以理解特定大小的JavaFX打印节点,javafx,clojure,Javafx,Clojure,我正在为一个家庭成员制作一本打印拼图的书,通过修改以前编写的桌面程序来打印拼图。我需要每个拼图打印在一个特定的大小,在这种情况下5平方米。我似乎找不到一种可靠的编程方法 下面是一个实现,它使用由反复试验确定的比例因子来缩放绘制拼图的画布。这是用Clojure编写的,但我认为任何使用Java的人都可以理解 (defn create-print-button-click-handler "Handle a click on the 'Print...' button." [canvas st
(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))))))))
我见过一些使用可打印宽度和高度的示例,但我还没有得到可以理解的结果,这些结果太大,无法容纳页面
正如我所说,这是可行的,但我希望当使用其他可能具有不同分辨率、不同水平和垂直分辨率等的打印机时,程序能够正确响应。好吧,我想出了一些似乎可行的方法。下面是一个演示如何做的示例
(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))
在本例中,程序仅绘制一个带有两条对角线的框,用于屏幕上的电路板表示
当用户单击“打印”按钮时,程序将创建一个用于打印的新画布对象。它根据显示屏的dpi调整画布的大小。在我的例子中,我希望打印出一块5平方的电路板,所以这就是*DPI5在显示器上计算像素的方法。用于在屏幕上绘制电路板的相同功能用于在专门创建的画布上绘制电路板
缩放的诀窍是简单地使用基于每英寸72的打印机点与显示器dpi的比率的缩放因子,通常为96、120或更高。将该比例因子添加到画布上使用的变换会导致以所需大小打印电路板。这在不同分辨率的打印机上正常工作
这还没有在具有不同dpi的多个显示设备上进行过测试,因此我很想知道是否有人在此类设备上使用此方法得到错误或正确的结果