Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/swing/PrintingStatus.java
38829 views
/*1* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.swing;2526import javax.swing.*;27import java.awt.*;28import java.awt.event.ActionEvent;29import java.awt.event.WindowAdapter;30import java.awt.event.WindowEvent;31import java.awt.print.PageFormat;32import java.awt.print.Printable;33import java.awt.print.PrinterException;34import java.awt.print.PrinterJob;35import java.text.MessageFormat;36import java.util.concurrent.atomic.AtomicBoolean;37import java.lang.reflect.InvocationTargetException;3839/**40* The {@code PrintingStatus} provides a dialog that displays progress41* of the printing job and provides a way to abort it42* <p/>43* Methods of these class are thread safe, although most Swing methods44* are not. Please see45* <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency46* in Swing</A> for more information.47*48* @author Alexander Potochkin49* @since 1.650*/5152public class PrintingStatus {5354private final PrinterJob job;55private final Component parent;56private JDialog abortDialog;5758private JButton abortButton;59private JLabel statusLabel;60private MessageFormat statusFormat;61private final AtomicBoolean isAborted = new AtomicBoolean(false);6263// the action that will abort printing64private final Action abortAction = new AbstractAction() {65public void actionPerformed(ActionEvent ae) {66if (!isAborted.get()) {67isAborted.set(true);6869// update the status abortDialog to indicate aborting70abortButton.setEnabled(false);71abortDialog.setTitle(72UIManager.getString("PrintingDialog.titleAbortingText"));73statusLabel.setText(74UIManager.getString("PrintingDialog.contentAbortingText"));7576// cancel the PrinterJob77job.cancel();78}79}80};8182private final WindowAdapter closeListener = new WindowAdapter() {83public void windowClosing(WindowEvent we) {84abortAction.actionPerformed(null);85}86};8788/**89* Creates PrintingStatus instance90*91* @param parent a <code>Component</code> object to be used92* as parent component for PrintingStatus dialog93* @param job a <code>PrinterJob</code> object to be cancelled94* using this <code>PrintingStatus</code> dialog95* @return a <code>PrintingStatus</code> object96*/97public static PrintingStatus98createPrintingStatus(Component parent, PrinterJob job) {99return new PrintingStatus(parent, job);100}101102protected PrintingStatus(Component parent, PrinterJob job) {103this.job = job;104this.parent = parent;105}106107private void init() {108// prepare the status JOptionPane109String progressTitle =110UIManager.getString("PrintingDialog.titleProgressText");111112String dialogInitialContent =113UIManager.getString("PrintingDialog.contentInitialText");114115// this one's a MessageFormat since it must include the page116// number in its text117statusFormat = new MessageFormat(118UIManager.getString("PrintingDialog.contentProgressText"));119120String abortText =121UIManager.getString("PrintingDialog.abortButtonText");122String abortTooltip =123UIManager.getString("PrintingDialog.abortButtonToolTipText");124int abortMnemonic =125getInt("PrintingDialog.abortButtonMnemonic", -1);126int abortMnemonicIndex =127getInt("PrintingDialog.abortButtonDisplayedMnemonicIndex", -1);128129abortButton = new JButton(abortText);130abortButton.addActionListener(abortAction);131132abortButton.setToolTipText(abortTooltip);133if (abortMnemonic != -1) {134abortButton.setMnemonic(abortMnemonic);135}136if (abortMnemonicIndex != -1) {137abortButton.setDisplayedMnemonicIndex(abortMnemonicIndex);138}139statusLabel = new JLabel(dialogInitialContent);140JOptionPane abortPane = new JOptionPane(statusLabel,141JOptionPane.INFORMATION_MESSAGE,142JOptionPane.DEFAULT_OPTION,143null, new Object[]{abortButton},144abortButton);145abortPane.getActionMap().put("close", abortAction);146147// The dialog should be centered over the viewport if the table is in one148if (parent != null && parent.getParent() instanceof JViewport) {149abortDialog =150abortPane.createDialog(parent.getParent(), progressTitle);151} else {152abortDialog = abortPane.createDialog(parent, progressTitle);153}154// clicking the X button should not hide the dialog155abortDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);156abortDialog.addWindowListener(closeListener);157}158159/**160* Shows PrintingStatus dialog.161* if dialog is modal this method returns only162* after <code>dispose()</code> was called otherwise returns immediately163*164* @param isModal <code>true</code> this dialog should be modal;165* <code>false</code> otherwise.166* @see #dispose167*/168public void showModal(final boolean isModal) {169if (SwingUtilities.isEventDispatchThread()) {170showModalOnEDT(isModal);171} else {172try {173SwingUtilities.invokeAndWait(new Runnable() {174public void run() {175showModalOnEDT(isModal);176}177});178} catch(InterruptedException e) {179throw new RuntimeException(e);180} catch(InvocationTargetException e) {181Throwable cause = e.getCause();182if (cause instanceof RuntimeException) {183throw (RuntimeException) cause;184} else if (cause instanceof Error) {185throw (Error) cause;186} else {187throw new RuntimeException(cause);188}189}190}191}192193/**194* The EDT part of the showModal method.195*196* This method is to be called on the EDT only.197*/198private void showModalOnEDT(boolean isModal) {199assert SwingUtilities.isEventDispatchThread();200init();201abortDialog.setModal(isModal);202abortDialog.setVisible(true);203}204205/**206* Disposes modal PrintingStatus dialog207*208* @see #showModal(boolean)209*/210public void dispose() {211if (SwingUtilities.isEventDispatchThread()) {212disposeOnEDT();213} else {214SwingUtilities.invokeLater(new Runnable() {215public void run() {216disposeOnEDT();217}218});219}220}221222/**223* The EDT part of the dispose method.224*225* This method is to be called on the EDT only.226*/227private void disposeOnEDT() {228assert SwingUtilities.isEventDispatchThread();229if (abortDialog != null) {230abortDialog.removeWindowListener(closeListener);231abortDialog.dispose();232abortDialog = null;233}234}235236/**237* Returns whether the printng was aborted using this PrintingStatus238*239* @return whether the printng was aborted using this PrintingStatus240*/241public boolean isAborted() {242return isAborted.get();243}244245/**246* Returns printable which is used to track the current page being247* printed in this PrintingStatus248*249* @param printable to be used to create notification printable250* @return printable which is used to track the current page being251* printed in this PrintingStatus252* @throws NullPointerException if <code>printable</code> is <code>null</code>253*/254public Printable createNotificationPrintable(Printable printable) {255return new NotificationPrintable(printable);256}257258private class NotificationPrintable implements Printable {259private final Printable printDelegatee;260261public NotificationPrintable(Printable delegatee) {262if (delegatee == null) {263throw new NullPointerException("Printable is null");264}265this.printDelegatee = delegatee;266}267268public int print(final Graphics graphics,269final PageFormat pageFormat, final int pageIndex)270throws PrinterException {271272final int retVal =273printDelegatee.print(graphics, pageFormat, pageIndex);274if (retVal != NO_SUCH_PAGE && !isAborted()) {275if (SwingUtilities.isEventDispatchThread()) {276updateStatusOnEDT(pageIndex);277} else {278SwingUtilities.invokeLater(new Runnable() {279public void run() {280updateStatusOnEDT(pageIndex);281}282});283}284}285return retVal;286}287288/**289* The EDT part of the print method.290*291* This method is to be called on the EDT only.292*/293private void updateStatusOnEDT(int pageIndex) {294assert SwingUtilities.isEventDispatchThread();295Object[] pageNumber = new Object[]{296new Integer(pageIndex + 1)};297statusLabel.setText(statusFormat.format(pageNumber));298}299}300301/**302* Duplicated from UIManager to make it visible303*/304static int getInt(Object key, int defaultValue) {305Object value = UIManager.get(key);306if (value instanceof Integer) {307return ((Integer) value).intValue();308}309if (value instanceof String) {310try {311return Integer.parseInt((String) value);312} catch(NumberFormatException nfe) {313}314}315return defaultValue;316}317}318319320