/*
 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.reflect.InvocationTargetException;

The PrintingStatus provides a dialog that displays progress of the printing job and provides a way to abort it

Methods of these class are thread safe, although most Swing methods are not. Please see Concurrency in Swing for more information.

Author:Alexander Potochkin
Since:1.6
/** * The {@code PrintingStatus} provides a dialog that displays progress * of the printing job and provides a way to abort it * <p> * Methods of these class are 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. * * @author Alexander Potochkin * @since 1.6 */
public class PrintingStatus { private final PrinterJob job; private final Component parent; private JDialog abortDialog; private JButton abortButton; private JLabel statusLabel; private MessageFormat statusFormat; private final AtomicBoolean isAborted = new AtomicBoolean(false); // the action that will abort printing @SuppressWarnings("serial") // anonymous class private final Action abortAction = new AbstractAction() { public void actionPerformed(ActionEvent ae) { if (!isAborted.get()) { isAborted.set(true); // update the status abortDialog to indicate aborting abortButton.setEnabled(false); abortDialog.setTitle( UIManager.getString("PrintingDialog.titleAbortingText")); statusLabel.setText( UIManager.getString("PrintingDialog.contentAbortingText")); // cancel the PrinterJob job.cancel(); } } }; private final WindowAdapter closeListener = new WindowAdapter() { public void windowClosing(WindowEvent we) { abortAction.actionPerformed(null); } };
Creates PrintingStatus instance
Params:
  • parent – a Component object to be used as parent component for PrintingStatus dialog
  • job – a PrinterJob object to be cancelled using this PrintingStatus dialog
Returns:a PrintingStatus object
/** * Creates PrintingStatus instance * * @param parent a <code>Component</code> object to be used * as parent component for PrintingStatus dialog * @param job a <code>PrinterJob</code> object to be cancelled * using this <code>PrintingStatus</code> dialog * @return a <code>PrintingStatus</code> object */
public static PrintingStatus createPrintingStatus(Component parent, PrinterJob job) { return new PrintingStatus(parent, job); } protected PrintingStatus(Component parent, PrinterJob job) { this.job = job; this.parent = parent; } private void init() { // prepare the status JOptionPane String progressTitle = UIManager.getString("PrintingDialog.titleProgressText"); String dialogInitialContent = UIManager.getString("PrintingDialog.contentInitialText"); // this one's a MessageFormat since it must include the page // number in its text statusFormat = new MessageFormat( UIManager.getString("PrintingDialog.contentProgressText")); String abortText = UIManager.getString("PrintingDialog.abortButtonText"); String abortTooltip = UIManager.getString("PrintingDialog.abortButtonToolTipText"); int abortMnemonic = getInt("PrintingDialog.abortButtonMnemonic", -1); int abortMnemonicIndex = getInt("PrintingDialog.abortButtonDisplayedMnemonicIndex", -1); abortButton = new JButton(abortText); abortButton.addActionListener(abortAction); abortButton.setToolTipText(abortTooltip); if (abortMnemonic != -1) { abortButton.setMnemonic(abortMnemonic); } if (abortMnemonicIndex != -1) { abortButton.setDisplayedMnemonicIndex(abortMnemonicIndex); } statusLabel = new JLabel(dialogInitialContent); JOptionPane abortPane = new JOptionPane(statusLabel, JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[]{abortButton}, abortButton); abortPane.getActionMap().put("close", abortAction); // The dialog should be centered over the viewport if the table is in one if (parent != null && parent.getParent() instanceof JViewport) { abortDialog = abortPane.createDialog(parent.getParent(), progressTitle); } else { abortDialog = abortPane.createDialog(parent, progressTitle); } // clicking the X button should not hide the dialog abortDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); abortDialog.addWindowListener(closeListener); }
Shows PrintingStatus dialog. if dialog is modal this method returns only after dispose() was called otherwise returns immediately
Params:
  • isModal – true this dialog should be modal; false otherwise.
See Also:
/** * Shows PrintingStatus dialog. * if dialog is modal this method returns only * after <code>dispose()</code> was called otherwise returns immediately * * @param isModal <code>true</code> this dialog should be modal; * <code>false</code> otherwise. * @see #dispose */
public void showModal(final boolean isModal) { if (SwingUtilities.isEventDispatchThread()) { showModalOnEDT(isModal); } else { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { showModalOnEDT(isModal); } }); } catch(InterruptedException e) { throw new RuntimeException(e); } catch(InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } else { throw new RuntimeException(cause); } } } }
The EDT part of the showModal method. This method is to be called on the EDT only.
/** * The EDT part of the showModal method. * * This method is to be called on the EDT only. */
private void showModalOnEDT(boolean isModal) { assert SwingUtilities.isEventDispatchThread(); init(); abortDialog.setModal(isModal); abortDialog.setVisible(true); }
Disposes modal PrintingStatus dialog
See Also:
  • showModal(boolean)
/** * Disposes modal PrintingStatus dialog * * @see #showModal(boolean) */
public void dispose() { if (SwingUtilities.isEventDispatchThread()) { disposeOnEDT(); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { disposeOnEDT(); } }); } }
The EDT part of the dispose method. This method is to be called on the EDT only.
/** * The EDT part of the dispose method. * * This method is to be called on the EDT only. */
private void disposeOnEDT() { assert SwingUtilities.isEventDispatchThread(); if (abortDialog != null) { abortDialog.removeWindowListener(closeListener); abortDialog.dispose(); abortDialog = null; } }
Returns whether the printng was aborted using this PrintingStatus
Returns:whether the printng was aborted using this PrintingStatus
/** * Returns whether the printng was aborted using this PrintingStatus * * @return whether the printng was aborted using this PrintingStatus */
public boolean isAborted() { return isAborted.get(); }
Returns printable which is used to track the current page being printed in this PrintingStatus
Params:
  • printable – to be used to create notification printable
Throws:
Returns:printable which is used to track the current page being printed in this PrintingStatus
/** * Returns printable which is used to track the current page being * printed in this PrintingStatus * * @param printable to be used to create notification printable * @return printable which is used to track the current page being * printed in this PrintingStatus * @throws NullPointerException if <code>printable</code> is <code>null</code> */
public Printable createNotificationPrintable(Printable printable) { return new NotificationPrintable(printable); } private class NotificationPrintable implements Printable { private final Printable printDelegatee; public NotificationPrintable(Printable delegatee) { if (delegatee == null) { throw new NullPointerException("Printable is null"); } this.printDelegatee = delegatee; } public int print(final Graphics graphics, final PageFormat pageFormat, final int pageIndex) throws PrinterException { final int retVal = printDelegatee.print(graphics, pageFormat, pageIndex); if (retVal != NO_SUCH_PAGE && !isAborted()) { if (SwingUtilities.isEventDispatchThread()) { updateStatusOnEDT(pageIndex); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { updateStatusOnEDT(pageIndex); } }); } } return retVal; }
The EDT part of the print method. This method is to be called on the EDT only.
/** * The EDT part of the print method. * * This method is to be called on the EDT only. */
private void updateStatusOnEDT(int pageIndex) { assert SwingUtilities.isEventDispatchThread(); Object[] pageNumber = new Object[]{ pageIndex + 1}; statusLabel.setText(statusFormat.format(pageNumber)); } }
Duplicated from UIManager to make it visible
/** * Duplicated from UIManager to make it visible */
static int getInt(Object key, int defaultValue) { Object value = UIManager.get(key); if (value instanceof Integer) { return ((Integer) value).intValue(); } if (value instanceof String) { try { return Integer.parseInt((String) value); } catch(NumberFormatException nfe) { } } return defaultValue; } }