use of sun.swing.PrintingStatus in project jdk8u_jdk by JetBrains.
the class JTable method print.
/**
* Prints this <code>JTable</code>. Takes steps that the majority of
* developers would take in order to print a <code>JTable</code>.
* In short, it prepares the table, calls <code>getPrintable</code> to
* fetch an appropriate <code>Printable</code>, and then sends it to the
* printer.
* <p>
* A <code>boolean</code> parameter allows you to specify whether or not
* a printing dialog is displayed to the user. When it is, the user may
* use the dialog to change the destination printer or printing attributes,
* or even to cancel the print. Another two parameters allow for a
* <code>PrintService</code> and printing attributes to be specified.
* These parameters can be used either to provide initial values for the
* print dialog, or to specify values when the dialog is not shown.
* <p>
* A second <code>boolean</code> parameter allows you to specify whether
* or not to perform printing in an interactive mode. If <code>true</code>,
* a modal progress dialog, with an abort option, is displayed for the
* duration of printing . This dialog also prevents any user action which
* may affect the table. However, it can not prevent the table from being
* modified by code (for example, another thread that posts updates using
* <code>SwingUtilities.invokeLater</code>). It is therefore the
* responsibility of the developer to ensure that no other code modifies
* the table in any way during printing (invalid modifications include
* changes in: size, renderers, or underlying data). Printing behavior is
* undefined when the table is changed during printing.
* <p>
* If <code>false</code> is specified for this parameter, no dialog will
* be displayed and printing will begin immediately on the event-dispatch
* thread. This blocks any other events, including repaints, from being
* processed until printing is complete. Although this effectively prevents
* the table from being changed, it doesn't provide a good user experience.
* For this reason, specifying <code>false</code> is only recommended when
* printing from an application with no visible GUI.
* <p>
* Note: Attempting to show the printing dialog or run interactively, while
* in headless mode, will result in a <code>HeadlessException</code>.
* <p>
* Before fetching the printable, this method will gracefully terminate
* editing, if necessary, to prevent an editor from showing in the printed
* result. Additionally, <code>JTable</code> will prepare its renderers
* during printing such that selection and focus are not indicated.
* As far as customizing further how the table looks in the printout,
* developers can provide custom renderers or paint code that conditionalize
* on the value of {@link javax.swing.JComponent#isPaintingForPrint()}.
* <p>
* See {@link #getPrintable} for more description on how the table is
* printed.
*
* @param printMode the printing mode that the printable should use
* @param headerFormat a <code>MessageFormat</code> specifying the text
* to be used in printing a header,
* or <code>null</code> for none
* @param footerFormat a <code>MessageFormat</code> specifying the text
* to be used in printing a footer,
* or <code>null</code> for none
* @param showPrintDialog whether or not to display a print dialog
* @param attr a <code>PrintRequestAttributeSet</code>
* specifying any printing attributes,
* or <code>null</code> for none
* @param interactive whether or not to print in an interactive mode
* @param service the destination <code>PrintService</code>,
* or <code>null</code> to use the default printer
* @return true, unless printing is cancelled by the user
* @throws HeadlessException if the method is asked to show a printing
* dialog or run interactively, and
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @throws SecurityException if a security manager exists and its
* {@link java.lang.SecurityManager#checkPrintJobAccess}
* method disallows this thread from creating a print job request
* @throws PrinterException if an error in the print system causes the job
* to be aborted
* @see #getPrintable
* @see java.awt.GraphicsEnvironment#isHeadless
*
* @since 1.6
*/
public boolean print(PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat, boolean showPrintDialog, PrintRequestAttributeSet attr, boolean interactive, PrintService service) throws PrinterException, HeadlessException {
// complain early if an invalid parameter is specified for headless mode
boolean isHeadless = GraphicsEnvironment.isHeadless();
if (isHeadless) {
if (showPrintDialog) {
throw new HeadlessException("Can't show print dialog.");
}
if (interactive) {
throw new HeadlessException("Can't run interactively.");
}
}
// Get a PrinterJob.
// Do this before anything with side-effects since it may throw a
// security exception - in which case we don't want to do anything else.
final PrinterJob job = PrinterJob.getPrinterJob();
if (isEditing()) {
// try to stop cell editing, and failing that, cancel it
if (!getCellEditor().stopCellEditing()) {
getCellEditor().cancelCellEditing();
}
}
if (attr == null) {
attr = new HashPrintRequestAttributeSet();
}
final PrintingStatus printingStatus;
// fetch the Printable
Printable printable = getPrintable(printMode, headerFormat, footerFormat);
if (interactive) {
// wrap the Printable so that we can print on another thread
printable = new ThreadSafePrintable(printable);
printingStatus = PrintingStatus.createPrintingStatus(this, job);
printable = printingStatus.createNotificationPrintable(printable);
} else {
// to please compiler
printingStatus = null;
}
// set the printable on the PrinterJob
job.setPrintable(printable);
// if specified, set the PrintService on the PrinterJob
if (service != null) {
job.setPrintService(service);
}
// if requested, show the print dialog
if (showPrintDialog && !job.printDialog(attr)) {
// the user cancelled the print dialog
return false;
}
// if not interactive, just print on this thread (no dialog)
if (!interactive) {
// do the printing
job.print(attr);
// we're done
return true;
}
// make sure this is clear since we'll check it after
printError = null;
// to synchronize on
final Object lock = new Object();
// copied so we can access from the inner class
final PrintRequestAttributeSet copyAttr = attr;
// this runnable will be used to do the printing
// (and save any throwables) on another thread
Runnable runnable = new Runnable() {
public void run() {
try {
// do the printing
job.print(copyAttr);
} catch (Throwable t) {
// save any Throwable to be rethrown
synchronized (lock) {
printError = t;
}
} finally {
// we're finished - hide the dialog
printingStatus.dispose();
}
}
};
// start printing on another thread
Thread th = new Thread(runnable);
th.start();
printingStatus.showModal(true);
// look for any error that the printing may have generated
Throwable pe;
synchronized (lock) {
pe = printError;
printError = null;
}
// check the type of error and handle it
if (pe != null) {
// in this case, by the user
if (pe instanceof PrinterAbortException) {
return false;
} else if (pe instanceof PrinterException) {
throw (PrinterException) pe;
} else if (pe instanceof RuntimeException) {
throw (RuntimeException) pe;
} else if (pe instanceof Error) {
throw (Error) pe;
}
// can not happen
throw new AssertionError(pe);
}
return true;
}
use of sun.swing.PrintingStatus in project jdk8u_jdk by JetBrains.
the class JTextComponent method print.
/**
* Prints the content of this {@code JTextComponent}. Note: this method
* blocks until printing is done.
*
* <p>
* Page header and footer text can be added to the output by providing
* {@code MessageFormat} arguments. The printing code requests
* {@code Strings} from the formats, providing a single item which may be
* included in the formatted string: an {@code Integer} representing the
* current page number.
*
* <p>
* {@code showPrintDialog boolean} parameter allows you to specify whether
* a print dialog is displayed to the user. When it is, the user
* may use the dialog to change printing attributes or even cancel the
* print.
*
* <p>
* {@code service} allows you to provide the initial
* {@code PrintService} for the print dialog, or to specify
* {@code PrintService} to print to when the dialog is not shown.
*
* <p>
* {@code attributes} can be used to provide the
* initial values for the print dialog, or to supply any needed
* attributes when the dialog is not shown. {@code attributes} can
* be used to control how the job will print, for example
* <i>duplex</i> or <i>single-sided</i>.
*
* <p>
* {@code interactive boolean} parameter allows you to specify
* whether to perform printing in <i>interactive</i>
* mode. If {@code true}, a progress dialog, with an abort option,
* is displayed for the duration of printing. This dialog is
* <i>modal</i> when {@code print} is invoked on the <i>Event Dispatch
* Thread</i> and <i>non-modal</i> otherwise. <b>Warning</b>:
* calling this method on the <i>Event Dispatch Thread</i> with {@code
* interactive false} blocks <i>all</i> events, including repaints, from
* being processed until printing is complete. It is only
* recommended when printing from an application with no
* visible GUI.
*
* <p>
* Note: In <i>headless</i> mode, {@code showPrintDialog} and
* {@code interactive} parameters are ignored and no dialogs are
* shown.
*
* <p>
* This method ensures the {@code document} is not mutated during printing.
* To indicate it visually, {@code setEnabled(false)} is set for the
* duration of printing.
*
* <p>
* This method uses {@link #getPrintable} to render document content.
*
* <p>
* This method is thread-safe, although most Swing methods are not. Please
* see <A
* HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
* Concurrency in Swing</A> for more information.
*
* <p>
* <b>Sample Usage</b>. This code snippet shows a cross-platform print
* dialog and then prints the {@code JTextComponent} in <i>interactive</i> mode
* unless the user cancels the dialog:
*
* <pre>
* textComponent.print(new MessageFormat("My text component header"),
* new MessageFormat("Footer. Page - {0}"), true, null, null, true);
* </pre>
* <p>
* Executing this code off the <i>Event Dispatch Thread</i>
* performs printing on the <i>background</i>.
* The following pattern might be used for <i>background</i>
* printing:
* <pre>
* FutureTask<Boolean> future =
* new FutureTask<Boolean>(
* new Callable<Boolean>() {
* public Boolean call() {
* return textComponent.print(.....);
* }
* });
* executor.execute(future);
* </pre>
*
* @param headerFormat the text, in {@code MessageFormat}, to be
* used as the header, or {@code null} for no header
* @param footerFormat the text, in {@code MessageFormat}, to be
* used as the footer, or {@code null} for no footer
* @param showPrintDialog {@code true} to display a print dialog,
* {@code false} otherwise
* @param service initial {@code PrintService}, or {@code null} for the
* default
* @param attributes the job attributes to be applied to the print job, or
* {@code null} for none
* @param interactive whether to print in an interactive mode
* @return {@code true}, unless printing is canceled by the user
* @throws PrinterException if an error in the print system causes the job
* to be aborted
* @throws SecurityException if this thread is not allowed to
* initiate a print job request
*
* @see #getPrintable
* @see java.text.MessageFormat
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.util.concurrent.FutureTask
*
* @since 1.6
*/
public boolean print(final MessageFormat headerFormat, final MessageFormat footerFormat, final boolean showPrintDialog, final PrintService service, final PrintRequestAttributeSet attributes, final boolean interactive) throws PrinterException {
final PrinterJob job = PrinterJob.getPrinterJob();
final Printable printable;
final PrintingStatus printingStatus;
final boolean isHeadless = GraphicsEnvironment.isHeadless();
final boolean isEventDispatchThread = SwingUtilities.isEventDispatchThread();
final Printable textPrintable = getPrintable(headerFormat, footerFormat);
if (interactive && !isHeadless) {
printingStatus = PrintingStatus.createPrintingStatus(this, job);
printable = printingStatus.createNotificationPrintable(textPrintable);
} else {
printingStatus = null;
printable = textPrintable;
}
if (service != null) {
job.setPrintService(service);
}
job.setPrintable(printable);
final PrintRequestAttributeSet attr = (attributes == null) ? new HashPrintRequestAttributeSet() : attributes;
if (showPrintDialog && !isHeadless && !job.printDialog(attr)) {
return false;
}
/*
* there are three cases for printing:
* 1. print non interactively (! interactive || isHeadless)
* 2. print interactively off EDT
* 3. print interactively on EDT
*
* 1 and 2 prints on the current thread (3 prints on another thread)
* 2 and 3 deal with PrintingStatusDialog
*/
final Callable<Object> doPrint = new Callable<Object>() {
public Object call() throws Exception {
try {
job.print(attr);
} finally {
if (printingStatus != null) {
printingStatus.dispose();
}
}
return null;
}
};
final FutureTask<Object> futurePrinting = new FutureTask<Object>(doPrint);
final Runnable runnablePrinting = new Runnable() {
public void run() {
//disable component
boolean wasEnabled = false;
if (isEventDispatchThread) {
if (isEnabled()) {
wasEnabled = true;
setEnabled(false);
}
} else {
try {
wasEnabled = SwingUtilities2.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
boolean rv = isEnabled();
if (rv) {
setEnabled(false);
}
return rv;
}
}).get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof Error) {
throw (Error) cause;
}
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
throw new AssertionError(cause);
}
}
getDocument().render(futurePrinting);
//enable component
if (wasEnabled) {
if (isEventDispatchThread) {
setEnabled(true);
} else {
try {
SwingUtilities2.submit(new Runnable() {
public void run() {
setEnabled(true);
}
}, null).get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof Error) {
throw (Error) cause;
}
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
throw new AssertionError(cause);
}
}
}
}
};
if (!interactive || isHeadless) {
runnablePrinting.run();
} else {
if (isEventDispatchThread) {
(new Thread(runnablePrinting)).start();
printingStatus.showModal(true);
} else {
printingStatus.showModal(false);
runnablePrinting.run();
}
}
//dialog is hidden if needed.
try {
futurePrinting.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof PrinterAbortException) {
if (printingStatus != null && printingStatus.isAborted()) {
return false;
} else {
throw (PrinterAbortException) cause;
}
} else if (cause instanceof PrinterException) {
throw (PrinterException) cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new AssertionError(cause);
}
}
return true;
}
Aggregations