Search in sources :

Example 1 with PrintingStatus

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;
}
Also used : PrintingStatus(sun.swing.PrintingStatus)

Example 2 with PrintingStatus

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(&quot;My text component header&quot;),
     *     new MessageFormat(&quot;Footer. Page - {0}&quot;), 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&lt;Boolean&gt; future =
     *         new FutureTask&lt;Boolean&gt;(
     *             new Callable&lt;Boolean&gt;() {
     *                 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;
}
Also used : PrinterException(java.awt.print.PrinterException) PrinterException(java.awt.print.PrinterException) PrintRequestAttributeSet(javax.print.attribute.PrintRequestAttributeSet) TextComponentPrintable(sun.swing.text.TextComponentPrintable) Printable(java.awt.print.Printable) PrintingStatus(sun.swing.PrintingStatus)

Aggregations

PrintingStatus (sun.swing.PrintingStatus)2 Printable (java.awt.print.Printable)1 PrinterException (java.awt.print.PrinterException)1 PrintRequestAttributeSet (javax.print.attribute.PrintRequestAttributeSet)1 TextComponentPrintable (sun.swing.text.TextComponentPrintable)1