1. /*
  2. * @(#)PrinterJob.java 1.36 04/01/28
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt.print;
  8. import java.awt.AWTError;
  9. import java.awt.HeadlessException;
  10. import java.util.Enumeration;
  11. import javax.print.DocFlavor;
  12. import javax.print.PrintService;
  13. import javax.print.PrintServiceLookup;
  14. import javax.print.StreamPrintServiceFactory;
  15. import javax.print.attribute.PrintRequestAttributeSet;
  16. import sun.security.action.GetPropertyAction;
  17. /**
  18. * The <code>PrinterJob</code> class is the principal class that controls
  19. * printing. An application calls methods in this class to set up a job,
  20. * optionally to invoke a print dialog with the user, and then to print
  21. * the pages of the job.
  22. */
  23. public abstract class PrinterJob {
  24. /* Public Class Methods */
  25. /**
  26. * Creates and returns a <code>PrinterJob</code> which is initially
  27. * associated with the default printer.
  28. * If no printers are available on the system, a PrinterJob will still
  29. * be returned from this method, but <code>getPrintService()</code>
  30. * will return <code>null</code>, and calling
  31. * {@link #print() print} with this <code>PrinterJob</code> might
  32. * generate an exception. Applications that need to determine if
  33. * there are suitable printers before creating a <code>PrinterJob</code>
  34. * should ensure that the array returned from
  35. * {@link #lookupPrintServices() lookupPrintServices} is not empty.
  36. * @return a new <code>PrinterJob</code>.
  37. */
  38. public static PrinterJob getPrinterJob() {
  39. SecurityManager security = System.getSecurityManager();
  40. if (security != null) {
  41. security.checkPrintJobAccess();
  42. }
  43. return (PrinterJob) java.security.AccessController.doPrivileged(
  44. new java.security.PrivilegedAction() {
  45. public Object run() {
  46. String nm = System.getProperty("java.awt.printerjob", null);
  47. try {
  48. return (PrinterJob)Class.forName(nm).newInstance();
  49. } catch (ClassNotFoundException e) {
  50. throw new AWTError("PrinterJob not found: " + nm);
  51. } catch (InstantiationException e) {
  52. throw new AWTError("Could not instantiate PrinterJob: " + nm);
  53. } catch (IllegalAccessException e) {
  54. throw new AWTError("Could not access PrinterJob: " + nm);
  55. }
  56. }
  57. });
  58. }
  59. /**
  60. * A convenience method which looks up 2D print services.
  61. * Services returned from this method may be installed on
  62. * <code>PrinterJob</code>s which support print services.
  63. * Calling this method is equivalent to calling
  64. * {@link javax.print.PrintServiceLookup#lookupPrintServices(
  65. * DocFlavor, AttributeSet)
  66. * <code>PrintServiceLookup.lookupPrintServices()</code>}
  67. * and specifying a Pageable DocFlavor.
  68. * @return a possibly empty array of 2D print services.
  69. * @since 1.4
  70. */
  71. public static PrintService[] lookupPrintServices() {
  72. return PrintServiceLookup.
  73. lookupPrintServices(DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
  74. }
  75. /**
  76. * A convenience method which locates factories for stream print
  77. * services which can image 2D graphics.
  78. * Sample usage :
  79. * <pre>
  80. * FileOutputStream outstream;
  81. * StreamPrintService psPrinter;
  82. * String psMimeType = "application/postscript";
  83. *
  84. * StreamPrintServiceFactory[] factories =
  85. * PrinterJob.lookupStreamPrintServices(psMimeType);
  86. * if (factories.length > 0) {
  87. * try {
  88. * outstream = new File("out.ps");
  89. * psPrinter = factories[0].getPrintService(fos);
  90. * // psPrinter can now be set as the service on a PrinterJob
  91. * } catch (FileNotFoundException e) {
  92. * }
  93. * }
  94. * </pre>
  95. * Services returned from this method may be installed on
  96. * <code>PrinterJob</code> instances which support print services.
  97. * Calling this method is equivalent to calling
  98. * {@link javax.print.StreamPrintServiceFactory#lookupStreamPrintServiceFactories(DocFlavor, String)
  99. * <code>StreamPrintServiceFactory.lookupStreamPrintServiceFactories()
  100. * </code>} and specifying a Pageable DocFlavor.
  101. *
  102. * @param mimeType the required output format, or null to mean any format.
  103. * @return a possibly empty array of 2D stream print service factories.
  104. * @since 1.4
  105. */
  106. public static StreamPrintServiceFactory[]
  107. lookupStreamPrintServices(String mimeType) {
  108. return StreamPrintServiceFactory.lookupStreamPrintServiceFactories(
  109. DocFlavor.SERVICE_FORMATTED.PAGEABLE,
  110. mimeType);
  111. }
  112. /* Public Methods */
  113. /**
  114. * A <code>PrinterJob</code> object should be created using the
  115. * static {@link #getPrinterJob() <code>getPrinterJob</code>} method.
  116. */
  117. public PrinterJob() {
  118. }
  119. /**
  120. * Returns the service (printer) for this printer job.
  121. * Implementations of this class which do not support print services
  122. * may return null;
  123. * @return the service for this printer job.
  124. * @see #setPrintService(PrintService)
  125. * @since 1.4
  126. */
  127. public PrintService getPrintService() {
  128. return null;
  129. }
  130. /**
  131. * Associate this PrinterJob with a new PrintService.
  132. * This method is overridden by subclasses which support
  133. * specifying a Print Service.
  134. *
  135. * Throws <code>PrinterException</code> if the specified service
  136. * cannot support the <code>Pageable</code> and
  137. * <code>Printable</code> interfaces necessary to support 2D printing.
  138. * @param service a print service that supports 2D printing
  139. * @exception PrinterException if the specified service does not support
  140. * 2D printing, or this PrinterJob class does not support
  141. * setting a 2D print service, or the specified service is
  142. * otherwise not a valid print service.
  143. * @see #getPrintService
  144. * @since 1.4
  145. */
  146. public void setPrintService(PrintService service)
  147. throws PrinterException {
  148. throw new PrinterException(
  149. "Setting a service is not supported on this class");
  150. }
  151. /**
  152. * Calls <code>painter</code> to render the pages. The pages in the
  153. * document to be printed by this
  154. * <code>PrinterJob</code> are rendered by the {@link Printable}
  155. * object, <code>painter</code>. The {@link PageFormat} for each page
  156. * is the default page format.
  157. * @param painter the <code>Printable</code> that renders each page of
  158. * the document.
  159. */
  160. public abstract void setPrintable(Printable painter);
  161. /**
  162. * Calls <code>painter</code> to render the pages in the specified
  163. * <code>format</code>. The pages in the document to be printed by
  164. * this <code>PrinterJob</code> are rendered by the
  165. * <code>Printable</code> object, <code>painter</code>. The
  166. * <code>PageFormat</code> of each page is <code>format</code>.
  167. * @param painter the <code>Printable</code> called to render
  168. * each page of the document
  169. * @param format the size and orientation of each page to
  170. * be printed
  171. */
  172. public abstract void setPrintable(Printable painter, PageFormat format);
  173. /**
  174. * Queries <code>document</code> for the number of pages and
  175. * the <code>PageFormat</code> and <code>Printable</code> for each
  176. * page held in the <code>Pageable</code> instance,
  177. * <code>document</code>.
  178. * @param document the pages to be printed. It can not be
  179. * <code>null</code>.
  180. * @exception NullPointerException the <code>Pageable</code> passed in
  181. * was <code>null</code>.
  182. * @see PageFormat
  183. * @see Printable
  184. */
  185. public abstract void setPageable(Pageable document)
  186. throws NullPointerException;
  187. /**
  188. * Presents a dialog to the user for changing the properties of
  189. * the print job.
  190. * This method will display a native dialog if a native print
  191. * service is selected, and user choice of printers will be restricted
  192. * to these native print services.
  193. * To present the cross platform print dialog for all services,
  194. * including native ones instead use
  195. * <code>printDialog(PrintRequestAttributeSet)</code>.
  196. * <p>
  197. * PrinterJob implementations which can use PrintService's will update
  198. * the PrintService for this PrinterJob to reflect the new service
  199. * selected by the user.
  200. * @return <code>true</code> if the user does not cancel the dialog;
  201. * <code>false</code> otherwise.
  202. * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  203. * returns true.
  204. * @see java.awt.GraphicsEnvironment#isHeadless
  205. */
  206. public abstract boolean printDialog() throws HeadlessException;
  207. /**
  208. * A convenience method which displays a cross-platform print dialog
  209. * for all services which are capable of printing 2D graphics using the
  210. * <code>Pageable</code> interface. The selected printer when the
  211. * dialog is initially displayed will reflect the print service currently
  212. * attached to this print job.
  213. * If the user changes the print service, the PrinterJob will be
  214. * updated to reflect this, unless the user cancels the dialog.
  215. * As well as allowing the user to select the destination printer,
  216. * the user can also select values of various print request attributes.
  217. * <p>
  218. * The attributes parameter on input will reflect the applications
  219. * required initial selections in the user dialog. Attributes not
  220. * specified display using the default for the service. On return it
  221. * will reflect the user's choices. Selections may be updated by
  222. * the implementation to be consistent with the supported values
  223. * for the currently selected print service.
  224. * <p>
  225. * As the user scrolls to a new print service selection, the values
  226. * copied are based on the settings for the previous service, together
  227. * with any user changes. The values are not based on the original
  228. * settings supplied by the client.
  229. * <p>
  230. * With the exception of selected printer, the PrinterJob state is
  231. * not updated to reflect the user's changes.
  232. * For the selections to affect a printer job, the attributes must
  233. * be specified in the call to the
  234. * <code>print(PrintRequestAttributeSet)</code> method. If using
  235. * the Pageable interface, clients which intend to use media selected
  236. * by the user must create a PageFormat derived from the user's
  237. * selections.
  238. * If the user cancels the dialog, the attributes will not reflect
  239. * any changes made by the user.
  240. * @param attributes on input is application supplied attributes,
  241. * on output the contents are updated to reflect user choices.
  242. * This parameter may not be null.
  243. * @return <code>true</code> if the user does not cancel the dialog;
  244. * <code>false</code> otherwise.
  245. * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  246. * returns true.
  247. * @exception NullPointerException if <code>attributes</code> parameter
  248. * is null.
  249. * @see java.awt.GraphicsEnvironment#isHeadless
  250. * @since 1.4
  251. *
  252. */
  253. public boolean printDialog(PrintRequestAttributeSet attributes)
  254. throws HeadlessException {
  255. if (attributes == null) {
  256. throw new NullPointerException("attributes");
  257. }
  258. return printDialog();
  259. }
  260. /**
  261. * Displays a dialog that allows modification of a
  262. * <code>PageFormat</code> instance.
  263. * The <code>page</code> argument is used to initialize controls
  264. * in the page setup dialog.
  265. * If the user cancels the dialog then this method returns the
  266. * original <code>page</code> object unmodified.
  267. * If the user okays the dialog then this method returns a new
  268. * <code>PageFormat</code> object with the indicated changes.
  269. * In either case, the original <code>page</code> object is
  270. * not modified.
  271. * @param page the default <code>PageFormat</code> presented to the
  272. * user for modification
  273. * @return the original <code>page</code> object if the dialog
  274. * is cancelled; a new <code>PageFormat</code> object
  275. * containing the format indicated by the user if the
  276. * dialog is acknowledged.
  277. * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  278. * returns true.
  279. * @see java.awt.GraphicsEnvironment#isHeadless
  280. * @since 1.2
  281. */
  282. public abstract PageFormat pageDialog(PageFormat page)
  283. throws HeadlessException;
  284. /**
  285. * A convenience method which displays a cross-platform page setup dialog.
  286. * The choices available will reflect the print service currently
  287. * set on this PrinterJob.
  288. * <p>
  289. * The attributes parameter on input will reflect the client's
  290. * required initial selections in the user dialog. Attributes which are
  291. * not specified display using the default for the service. On return it
  292. * will reflect the user's choices. Selections may be updated by
  293. * the implementation to be consistent with the supported values
  294. * for the currently selected print service.
  295. * <p>
  296. * The return value will be a PageFormat equivalent to the
  297. * selections in the PrintRequestAttributeSet.
  298. * If the user cancels the dialog, the attributes will not reflect
  299. * any changes made by the user, and the return value will be null.
  300. * @param attributes on input is application supplied attributes,
  301. * on output the contents are updated to reflect user choices.
  302. * This parameter may not be null.
  303. * @return a page format if the user does not cancel the dialog;
  304. * <code>null</code> otherwise.
  305. * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  306. * returns true.
  307. * @exception NullPointerException if <code>attributes</code> parameter
  308. * is null.
  309. * @see java.awt.GraphicsEnvironment#isHeadless
  310. * @since 1.4
  311. *
  312. */
  313. public PageFormat pageDialog(PrintRequestAttributeSet attributes)
  314. throws HeadlessException {
  315. if (attributes == null) {
  316. throw new NullPointerException("attributes");
  317. }
  318. return pageDialog(defaultPage());
  319. }
  320. /**
  321. * Clones the <code>PageFormat</code> argument and alters the
  322. * clone to describe a default page size and orientation.
  323. * @param page the <code>PageFormat</code> to be cloned and altered
  324. * @return clone of <code>page</code>, altered to describe a default
  325. * <code>PageFormat</code>.
  326. */
  327. public abstract PageFormat defaultPage(PageFormat page);
  328. /**
  329. * Creates a new <code>PageFormat</code> instance and
  330. * sets it to a default size and orientation.
  331. * @return a <code>PageFormat</code> set to a default size and
  332. * orientation.
  333. */
  334. public PageFormat defaultPage() {
  335. return defaultPage(new PageFormat());
  336. }
  337. /**
  338. * Returns the clone of <code>page</code> with its settings
  339. * adjusted to be compatible with the current printer of this
  340. * <code>PrinterJob</code>. For example, the returned
  341. * <code>PageFormat</code> could have its imageable area
  342. * adjusted to fit within the physical area of the paper that
  343. * is used by the current printer.
  344. * @param page the <code>PageFormat</code> that is cloned and
  345. * whose settings are changed to be compatible with
  346. * the current printer
  347. * @return a <code>PageFormat</code> that is cloned from
  348. * <code>page</code> and whose settings are changed
  349. * to conform with this <code>PrinterJob</code>.
  350. */
  351. public abstract PageFormat validatePage(PageFormat page);
  352. /**
  353. * Prints a set of pages.
  354. * @exception PrinterException an error in the print system
  355. * caused the job to be aborted.
  356. * @see Book
  357. * @see Pageable
  358. * @see Printable
  359. */
  360. public abstract void print() throws PrinterException;
  361. /**
  362. * Prints a set of pages using the settings in the attribute
  363. * set. The default implementation ignores the attribute set.
  364. * <p>
  365. * Note that some attributes may be set directly on the PrinterJob
  366. * by equivalent method calls, (for example), copies:
  367. * <code>setcopies(int)</code>, job name: <code>setJobName(String)</code>
  368. * and specifying media size and orientation though the
  369. * <code>PageFormat</code> object.
  370. * <p>
  371. * If a supported attribute-value is specified in this attribute set,
  372. * it will take precedence over the API settings for this print()
  373. * operation only.
  374. * The following behaviour is specified for PageFormat:
  375. * If a client uses the Printable interface, then the
  376. * <code>attributes</code> parameter to this method is examined
  377. * for attributes which specify media (by size), orientation, and
  378. * imageable area, and those are used to construct a new PageFormat
  379. * which is passed to the Printable object's print() method.
  380. * See {@link Printable} for an explanation of the required
  381. * behaviour of a Printable to ensure optimal printing via PrinterJob.
  382. * For clients of the Pageable interface, the PageFormat will always
  383. * be as supplied by that interface, on a per page basis.
  384. * <p>
  385. * These behaviours allow an application to directly pass the
  386. * user settings returned from
  387. * <code>printDialog(PrintRequestAttributeSet attributes</code> to
  388. * this print() method.
  389. * <p>
  390. *
  391. * @param attributes a set of attributes for the job
  392. * @exception PrinterException an error in the print system
  393. * caused the job to be aborted.
  394. * @see Book
  395. * @see Pageable
  396. * @see Printable
  397. */
  398. public void print(PrintRequestAttributeSet attributes)
  399. throws PrinterException {
  400. print();
  401. }
  402. /**
  403. * Sets the number of copies to be printed.
  404. * @param copies the number of copies to be printed
  405. * @see #getCopies
  406. */
  407. public abstract void setCopies(int copies);
  408. /**
  409. * Gets the number of copies to be printed.
  410. * @return the number of copies to be printed.
  411. * @see #setCopies
  412. */
  413. public abstract int getCopies();
  414. /**
  415. * Gets the name of the printing user.
  416. * @return the name of the printing user
  417. */
  418. public abstract String getUserName();
  419. /**
  420. * Sets the name of the document to be printed.
  421. * The document name can not be <code>null</code>.
  422. * @param jobName the name of the document to be printed
  423. * @see #getJobName
  424. */
  425. public abstract void setJobName(String jobName);
  426. /**
  427. * Gets the name of the document to be printed.
  428. * @return the name of the document to be printed.
  429. * @see #setJobName
  430. */
  431. public abstract String getJobName();
  432. /**
  433. * Cancels a print job that is in progress. If
  434. * {@link #print() print} has been called but has not
  435. * returned then this method signals
  436. * that the job should be cancelled at the next
  437. * chance. If there is no print job in progress then
  438. * this call does nothing.
  439. */
  440. public abstract void cancel();
  441. /**
  442. * Returns <code>true</code> if a print job is
  443. * in progress, but is going to be cancelled
  444. * at the next opportunity; otherwise returns
  445. * <code>false</code>.
  446. * @return <code>true</code> if the job in progress
  447. * is going to be cancelled; <code>false</code> otherwise.
  448. */
  449. public abstract boolean isCancelled();
  450. }