28 import javafx.print.Collation; 29 import javafx.print.JobSettings; 30 import javafx.print.PageLayout; 31 import javafx.print.PageOrientation; 32 import javafx.print.PageRange; 33 import javafx.print.Paper; 34 import javafx.print.PaperSource; 35 import javafx.print.PrintColor; 36 import javafx.print.PrintResolution; 37 import javafx.print.PrintSides; 38 import javafx.print.Printer; 39 import javafx.print.Printer.MarginType; 40 import javafx.print.PrinterAttributes; 41 import javafx.scene.Group; 42 import javafx.scene.Node; 43 import javafx.scene.Parent; 44 import javafx.scene.Scene; 45 import javafx.stage.Window; 46 import javax.print.PrintService; 47 import javax.print.attribute.HashPrintRequestAttributeSet; 48 import javax.print.attribute.PrintRequestAttributeSet; 49 import javax.print.attribute.ResolutionSyntax; 50 import javax.print.attribute.Size2DSyntax; 51 import javax.print.attribute.standard.Chromaticity; 52 import javax.print.attribute.standard.Copies; 53 import javax.print.attribute.standard.DialogTypeSelection; 54 import javax.print.attribute.standard.Media; 55 import javax.print.attribute.standard.MediaPrintableArea; 56 import javax.print.attribute.standard.MediaSize; 57 import javax.print.attribute.standard.MediaSizeName; 58 import javax.print.attribute.standard.MediaTray; 59 import javax.print.attribute.standard.OrientationRequested; 60 import javax.print.attribute.standard.PageRanges; 61 import javax.print.attribute.standard.PrintQuality; 62 import javax.print.attribute.standard.PrinterResolution; 63 import javax.print.attribute.standard.SheetCollate; 64 import javax.print.attribute.standard.Sides; 65 import java.awt.*; 66 import java.awt.print.PageFormat; 67 import java.awt.print.Pageable; 68 import java.awt.print.Printable; 69 import java.awt.print.PrinterException; 70 import java.util.ArrayList; 71 import java.util.Set; 72 import com.sun.glass.ui.Application; 73 import com.sun.javafx.PlatformUtil; 74 import com.sun.javafx.print.PrintHelper; 75 import com.sun.javafx.print.PrinterImpl; 76 import com.sun.javafx.print.PrinterJobImpl; 77 import com.sun.javafx.scene.NodeHelper; 78 import com.sun.javafx.sg.prism.NGNode; 79 import com.sun.javafx.tk.Toolkit; 80 import com.sun.prism.j2d.PrismPrintGraphics; 81 82 public class J2DPrinterJob implements PrinterJobImpl { 83 84 javafx.print.PrinterJob fxPrinterJob; 85 java.awt.print.PrinterJob pJob2D; 86 javafx.print.Printer fxPrinter; 87 J2DPrinter j2dPrinter; 88 89 private JobSettings settings; 90 private PrintRequestAttributeSet printReqAttrSet; 91 private volatile Object elo = null; 92 93 public J2DPrinterJob(javafx.print.PrinterJob fxJob) { 94 95 fxPrinterJob = fxJob; 96 fxPrinter = fxPrinterJob.getPrinter(); 97 j2dPrinter = getJ2DPrinter(fxPrinter); 98 settings = fxPrinterJob.getJobSettings(); 99 pJob2D = java.awt.print.PrinterJob.getPrinterJob(); 100 try { 101 pJob2D.setPrintService(j2dPrinter.getService()); 102 } catch (PrinterException pe) { 103 } 104 printReqAttrSet = new HashPrintRequestAttributeSet(); 105 printReqAttrSet.add(DialogTypeSelection.NATIVE); 106 107 j2dPageable = new J2DPageable(); 108 pJob2D.setPageable(j2dPageable); 109 } 110 111 public boolean showPrintDialog(Window owner) { 112 113 if (jobRunning || jobDone) { 114 return false; 115 } 116 117 if (GraphicsEnvironment.isHeadless()) { 118 return true; 119 } 120 121 boolean rv = false; 122 syncSettingsToAttributes(); 123 if (!Toolkit.getToolkit().isFxUserThread()) { 124 rv = pJob2D.printDialog(printReqAttrSet); 125 } else { 126 // If we are on the event thread, we need to check whether we are 127 // allowed to call a nested event handler. 128 if (!Toolkit.getToolkit().canStartNestedEventLoop()) { 129 throw new IllegalStateException("Printing is not allowed during animation or layout processing"); 130 } 131 rv = showPrintDialogWithNestedLoop(owner); 132 } 133 if (rv) { 134 updateSettingsFromDialog(); 135 } 136 return rv; 137 } 138 139 private class PrintDialogRunnable implements Runnable { 140 141 public void run() { 142 boolean rv = false; 143 try { 144 rv = pJob2D.printDialog(printReqAttrSet); 145 } catch (Exception e) { 146 } finally { 147 Application.invokeLater(new ExitLoopRunnable(this, rv)); 148 } 149 } 150 } 151 152 private boolean showPrintDialogWithNestedLoop(Window owner) { 153 PrintDialogRunnable dr = new PrintDialogRunnable(); 154 Thread prtThread = new Thread(dr, "FX Print Dialog Thread"); 155 prtThread.start(); 156 // the nested event loop will return after the runnable exits. 157 Object rv = Toolkit.getToolkit().enterNestedEventLoop(dr); 158 159 boolean rvbool = false; 160 try { 161 rvbool = ((Boolean)rv).booleanValue(); 162 } catch (Exception e) { 163 } 164 return rvbool; 165 } 166 167 public boolean showPageDialog(Window owner) { 168 if (jobRunning || jobDone) { 169 return false; 170 } 171 if (GraphicsEnvironment.isHeadless()) { 172 return true; 173 } 174 boolean rv = false; 175 syncSettingsToAttributes(); 176 if (!Toolkit.getToolkit().isFxUserThread()) { 177 PageFormat pf = pJob2D.pageDialog(printReqAttrSet); 178 rv = pf != null; 179 } else { 180 // If we are on the event thread, we need to check whether we are 181 // allowed to call a nested event handler. 182 if (!Toolkit.getToolkit().canStartNestedEventLoop()) { 183 throw new IllegalStateException("Printing is not allowed during animation or layout processing"); 184 } 185 rv = showPageDialogFromNestedLoop(owner); 186 } 187 if (rv) { 188 updateSettingsFromDialog(); 189 } 190 return rv; 191 } 192 193 private class PageDialogRunnable implements Runnable { 194 195 public void run() { 196 PageFormat pf = null; 197 try { 198 pf = pJob2D.pageDialog(printReqAttrSet); 199 } catch (Exception e) { 200 } finally { 201 Boolean rv = Boolean.valueOf(pf != null); 202 Application.invokeLater(new ExitLoopRunnable(this, rv)); 203 } 204 } 205 } | 28 import javafx.print.Collation; 29 import javafx.print.JobSettings; 30 import javafx.print.PageLayout; 31 import javafx.print.PageOrientation; 32 import javafx.print.PageRange; 33 import javafx.print.Paper; 34 import javafx.print.PaperSource; 35 import javafx.print.PrintColor; 36 import javafx.print.PrintResolution; 37 import javafx.print.PrintSides; 38 import javafx.print.Printer; 39 import javafx.print.Printer.MarginType; 40 import javafx.print.PrinterAttributes; 41 import javafx.scene.Group; 42 import javafx.scene.Node; 43 import javafx.scene.Parent; 44 import javafx.scene.Scene; 45 import javafx.stage.Window; 46 import javax.print.PrintService; 47 import javax.print.attribute.HashPrintRequestAttributeSet; 48 import javax.print.attribute.PrintRequestAttribute; 49 import javax.print.attribute.PrintRequestAttributeSet; 50 import javax.print.attribute.ResolutionSyntax; 51 import javax.print.attribute.Size2DSyntax; 52 import javax.print.attribute.standard.Chromaticity; 53 import javax.print.attribute.standard.Copies; 54 import javax.print.attribute.standard.DialogTypeSelection; 55 import javax.print.attribute.standard.Media; 56 import javax.print.attribute.standard.MediaPrintableArea; 57 import javax.print.attribute.standard.MediaSize; 58 import javax.print.attribute.standard.MediaSizeName; 59 import javax.print.attribute.standard.MediaTray; 60 import javax.print.attribute.standard.OrientationRequested; 61 import javax.print.attribute.standard.PageRanges; 62 import javax.print.attribute.standard.PrintQuality; 63 import javax.print.attribute.standard.PrinterResolution; 64 import javax.print.attribute.standard.SheetCollate; 65 import javax.print.attribute.standard.Sides; 66 import java.awt.*; 67 import java.awt.print.PageFormat; 68 import java.awt.print.Pageable; 69 import java.awt.print.Printable; 70 import java.awt.print.PrinterException; 71 import java.util.ArrayList; 72 import java.util.Set; 73 import com.sun.glass.ui.Application; 74 import com.sun.javafx.PlatformUtil; 75 import com.sun.javafx.print.PrintHelper; 76 import com.sun.javafx.print.PrinterImpl; 77 import com.sun.javafx.print.PrinterJobImpl; 78 import com.sun.javafx.scene.NodeHelper; 79 import com.sun.javafx.sg.prism.NGNode; 80 import com.sun.javafx.stage.WindowHelper; 81 import com.sun.javafx.tk.TKStage; 82 import com.sun.javafx.tk.Toolkit; 83 84 import com.sun.prism.j2d.PrismPrintGraphics; 85 86 import java.lang.reflect.Constructor; 87 import java.security.AccessController; 88 import java.security.PrivilegedAction; 89 90 public class J2DPrinterJob implements PrinterJobImpl { 91 92 javafx.print.PrinterJob fxPrinterJob; 93 java.awt.print.PrinterJob pJob2D; 94 javafx.print.Printer fxPrinter; 95 J2DPrinter j2dPrinter; 96 97 private JobSettings settings; 98 private PrintRequestAttributeSet printReqAttrSet; 99 private volatile Object elo = null; 100 101 static private Class onTopClass = null; 102 PrintRequestAttribute getAlwaysOnTop(final long id) { 103 return AccessController.doPrivileged( 104 (PrivilegedAction<PrintRequestAttribute>) () -> { 105 106 PrintRequestAttribute alwaysOnTop = null; 107 try { 108 if (onTopClass == null) { 109 onTopClass = Class.forName("sun.print.DialogOnTop"); 110 } 111 Constructor<PrintRequestAttribute> cons = 112 onTopClass.getConstructor(long.class); 113 alwaysOnTop = cons.newInstance(id); 114 } catch (Throwable t) { 115 } 116 return alwaysOnTop; 117 }); 118 } 119 120 public J2DPrinterJob(javafx.print.PrinterJob fxJob) { 121 122 fxPrinterJob = fxJob; 123 fxPrinter = fxPrinterJob.getPrinter(); 124 j2dPrinter = getJ2DPrinter(fxPrinter); 125 settings = fxPrinterJob.getJobSettings(); 126 pJob2D = java.awt.print.PrinterJob.getPrinterJob(); 127 try { 128 pJob2D.setPrintService(j2dPrinter.getService()); 129 } catch (PrinterException pe) { 130 } 131 printReqAttrSet = new HashPrintRequestAttributeSet(); 132 printReqAttrSet.add(DialogTypeSelection.NATIVE); 133 j2dPageable = new J2DPageable(); 134 pJob2D.setPageable(j2dPageable); 135 } 136 137 private void setEnabledState(Window owner, boolean state) { 138 if (owner == null) { 139 return; 140 } 141 final TKStage stage = WindowHelper.getPeer(owner); 142 if (stage == null) { // just in case. 143 return; 144 } 145 Application.invokeAndWait(() -> stage.setEnabled(state)); 146 } 147 148 public boolean showPrintDialog(Window owner) { 149 150 if (jobRunning || jobDone) { 151 return false; 152 } 153 154 if (GraphicsEnvironment.isHeadless()) { 155 return true; 156 } 157 158 if (onTopClass != null) { 159 printReqAttrSet.remove(onTopClass); 160 } 161 if (owner != null) { 162 long id = WindowHelper.getPeer(owner).getRawHandle(); 163 PrintRequestAttribute alwaysOnTop = getAlwaysOnTop(id); 164 if (alwaysOnTop != null) { 165 printReqAttrSet.add(alwaysOnTop); 166 } 167 } 168 169 boolean rv = false; 170 syncSettingsToAttributes(); 171 try { 172 setEnabledState(owner, false); 173 if (!Toolkit.getToolkit().isFxUserThread()) { 174 rv = pJob2D.printDialog(printReqAttrSet); 175 } else { 176 // If we are on the event thread, we need to check whether 177 // we are allowed to call a nested event handler. 178 if (!Toolkit.getToolkit().canStartNestedEventLoop()) { 179 throw new IllegalStateException( 180 "Printing is not allowed during animation or layout processing"); 181 } 182 rv = showPrintDialogWithNestedLoop(owner); 183 } 184 if (rv) { 185 updateSettingsFromDialog(); 186 } 187 } finally { 188 setEnabledState(owner, true); 189 } 190 return rv; 191 } 192 193 private class PrintDialogRunnable implements Runnable { 194 195 public void run() { 196 boolean rv = false; 197 try { 198 rv = pJob2D.printDialog(printReqAttrSet); 199 } catch (Exception e) { 200 } finally { 201 Application.invokeLater(new ExitLoopRunnable(this, rv)); 202 } 203 } 204 } 205 206 private boolean showPrintDialogWithNestedLoop(Window owner) { 207 PrintDialogRunnable dr = new PrintDialogRunnable(); 208 Thread prtThread = new Thread(dr, "FX Print Dialog Thread"); 209 prtThread.start(); 210 // the nested event loop will return after the runnable exits. 211 Object rv = Toolkit.getToolkit().enterNestedEventLoop(dr); 212 213 boolean rvbool = false; 214 try { 215 rvbool = ((Boolean)rv).booleanValue(); 216 } catch (Exception e) { 217 } 218 return rvbool; 219 } 220 221 public boolean showPageDialog(Window owner) { 222 if (jobRunning || jobDone) { 223 return false; 224 } 225 if (GraphicsEnvironment.isHeadless()) { 226 return true; 227 } 228 229 if (onTopClass != null) { 230 printReqAttrSet.remove(onTopClass); 231 } 232 if (owner != null) { 233 long id = WindowHelper.getPeer(owner).getRawHandle(); 234 PrintRequestAttribute alwaysOnTop = getAlwaysOnTop(id); 235 if (alwaysOnTop != null) { 236 printReqAttrSet.add(alwaysOnTop); 237 } 238 } 239 240 boolean rv = false; 241 syncSettingsToAttributes(); 242 try { 243 setEnabledState(owner, false); 244 if (!Toolkit.getToolkit().isFxUserThread()) { 245 PageFormat pf = pJob2D.pageDialog(printReqAttrSet); 246 rv = pf != null; 247 } else { 248 // If we are on the event thread, we need to check whether 249 // we are allowed to call a nested event handler. 250 if (!Toolkit.getToolkit().canStartNestedEventLoop()) { 251 throw new IllegalStateException( 252 "Printing is not allowed during animation or layout processing"); 253 } 254 rv = showPageDialogFromNestedLoop(owner); 255 } 256 } finally { 257 setEnabledState(owner, true); 258 } 259 if (rv) { 260 updateSettingsFromDialog(); 261 } 262 return rv; 263 } 264 265 private class PageDialogRunnable implements Runnable { 266 267 public void run() { 268 PageFormat pf = null; 269 try { 270 pf = pJob2D.pageDialog(printReqAttrSet); 271 } catch (Exception e) { 272 } finally { 273 Boolean rv = Boolean.valueOf(pf != null); 274 Application.invokeLater(new ExitLoopRunnable(this, rv)); 275 } 276 } 277 } |