318 lines · 10.9 KB · Java
RawDownload
/* * Copyright (c) 2005, 2006, 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 {@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="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</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    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     *     * @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 <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.     */    private void showModalOnEDT(boolean isModal) {        assert SwingUtilities.isEventDispatchThread();        init();        abortDialog.setModal(isModal);        abortDialog.setVisible(true);    }     /**     * 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.     */    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     *     * @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     *     * @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.         */        private void updateStatusOnEDT(int pageIndex) {            assert SwingUtilities.isEventDispatchThread();            Object[] pageNumber = new Object[]{                new Integer(pageIndex + 1)};            statusLabel.setText(statusFormat.format(pageNumber));        }    }     /**     * 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;    }}