2015-11-06 120 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的多個顯示設備進行測試,所以我會急於聽到有人在此類設備上使用此方法會導致錯誤(或正確)的結果。