2015-11-06 149 views
0

我正在通过调整以前编写的桌面程序来打印拼图,为家庭成员创建打印拼图。我需要每个拼图以特定尺寸打印,在这种情况下是5平方英寸,我似乎找不到可以可靠编程的方法。使用通过反复试验来确定一个比例系数。这是用Clojure写的,但我一点也被任何人谁使用Java可以理解的。特定尺寸的JavaFX打印节点

(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)))))))) 

我见过一些例子使用的打印宽度和高度,但我没有得到可理解的结果(太大,不适合页)。

就像我说的,这个工程,但我想要的程序m以正确响应,当其他打印机使用时可能有不同的分辨率,不同的水平和垂直分辨率等

回答

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英寸的正方形纸板打印出来,所以这就是显示屏上像素的计算方法。用于在屏幕上绘制纸板的相同功能用于在专门创建的Canvas上绘制它

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

这还没有用不同dpi的多个显示设备进行测试,所以我会急于听到有人在此类设备上使用此方法会导致错误(或正确)的结果。