Home » openjdk-7 » sun » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package sun.swing;
   26   
   27   import javax.swing;
   28   import java.awt;
   29   import java.awt.event.ActionEvent;
   30   import java.awt.event.WindowAdapter;
   31   import java.awt.event.WindowEvent;
   32   import java.awt.print.PageFormat;
   33   import java.awt.print.Printable;
   34   import java.awt.print.PrinterException;
   35   import java.awt.print.PrinterJob;
   36   import java.text.MessageFormat;
   37   import java.util.concurrent.atomic.AtomicBoolean;
   38   import java.lang.reflect.InvocationTargetException;
   39   
   40   /**
   41    * The {@code PrintingStatus} provides a dialog that displays progress
   42    * of the printing job and provides a way to abort it
   43    * <p/>
   44    * Methods of these class are thread safe, although most Swing methods
   45    * are not. Please see
   46    * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
   47    * to Use Threads</A> for more information.
   48    *
   49    * @author Alexander Potochkin
   50    * @since 1.6
   51    */
   52   
   53   public class PrintingStatus {
   54   
   55       private final PrinterJob job;
   56       private final Component parent;
   57       private JDialog abortDialog;
   58   
   59       private JButton abortButton;
   60       private JLabel statusLabel;
   61       private MessageFormat statusFormat;
   62       private final AtomicBoolean isAborted = new AtomicBoolean(false);
   63   
   64       // the action that will abort printing
   65       private final Action abortAction = new AbstractAction() {
   66           public void actionPerformed(ActionEvent ae) {
   67               if (!isAborted.get()) {
   68                   isAborted.set(true);
   69   
   70                   // update the status abortDialog to indicate aborting
   71                   abortButton.setEnabled(false);
   72                   abortDialog.setTitle(
   73                       UIManager.getString("PrintingDialog.titleAbortingText"));
   74                   statusLabel.setText(
   75                       UIManager.getString("PrintingDialog.contentAbortingText"));
   76   
   77                   // cancel the PrinterJob
   78                   job.cancel();
   79               }
   80           }
   81       };
   82   
   83       private final WindowAdapter closeListener = new WindowAdapter() {
   84           public void windowClosing(WindowEvent we) {
   85               abortAction.actionPerformed(null);
   86           }
   87       };
   88   
   89       /**
   90        * Creates PrintingStatus instance
   91        *
   92        * @param parent a <code>Component</code> object to be used
   93        *               as parent component for PrintingStatus dialog
   94        * @param job    a <code>PrinterJob</code> object to be cancelled
   95        *               using this <code>PrintingStatus</code> dialog
   96        * @return a <code>PrintingStatus</code> object
   97        */
   98       public static PrintingStatus
   99               createPrintingStatus(Component parent, PrinterJob job) {
  100           return new PrintingStatus(parent, job);
  101       }
  102   
  103       protected PrintingStatus(Component parent, PrinterJob job) {
  104           this.job = job;
  105           this.parent = parent;
  106       }
  107   
  108       private void init() {
  109           // prepare the status JOptionPane
  110           String progressTitle =
  111               UIManager.getString("PrintingDialog.titleProgressText");
  112   
  113           String dialogInitialContent =
  114               UIManager.getString("PrintingDialog.contentInitialText");
  115   
  116           // this one's a MessageFormat since it must include the page
  117           // number in its text
  118           statusFormat = new MessageFormat(
  119               UIManager.getString("PrintingDialog.contentProgressText"));
  120   
  121           String abortText =
  122               UIManager.getString("PrintingDialog.abortButtonText");
  123           String abortTooltip =
  124               UIManager.getString("PrintingDialog.abortButtonToolTipText");
  125           int abortMnemonic =
  126               getInt("PrintingDialog.abortButtonMnemonic", -1);
  127           int abortMnemonicIndex =
  128               getInt("PrintingDialog.abortButtonDisplayedMnemonicIndex", -1);
  129   
  130           abortButton = new JButton(abortText);
  131           abortButton.addActionListener(abortAction);
  132   
  133           abortButton.setToolTipText(abortTooltip);
  134           if (abortMnemonic != -1) {
  135               abortButton.setMnemonic(abortMnemonic);
  136           }
  137           if (abortMnemonicIndex != -1) {
  138               abortButton.setDisplayedMnemonicIndex(abortMnemonicIndex);
  139           }
  140           statusLabel = new JLabel(dialogInitialContent);
  141           JOptionPane abortPane = new JOptionPane(statusLabel,
  142               JOptionPane.INFORMATION_MESSAGE,
  143               JOptionPane.DEFAULT_OPTION,
  144               null, new Object[]{abortButton},
  145               abortButton);
  146           abortPane.getActionMap().put("close", abortAction);
  147   
  148           // The dialog should be centered over the viewport if the table is in one
  149           if (parent != null && parent.getParent() instanceof JViewport) {
  150               abortDialog =
  151                       abortPane.createDialog(parent.getParent(), progressTitle);
  152           } else {
  153               abortDialog = abortPane.createDialog(parent, progressTitle);
  154           }
  155           // clicking the X button should not hide the dialog
  156           abortDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
  157           abortDialog.addWindowListener(closeListener);
  158       }
  159   
  160       /**
  161        * Shows PrintingStatus dialog.
  162        * if dialog is modal this method returns only
  163        * after <code>dispose()</code> was called otherwise returns immediately
  164        *
  165        * @param isModal <code>true</code> this dialog should be modal;
  166        *                <code>false</code> otherwise.
  167        * @see #dispose
  168        */
  169       public void showModal(final boolean isModal) {
  170           if (SwingUtilities.isEventDispatchThread()) {
  171               showModalOnEDT(isModal);
  172           } else {
  173               try {
  174                   SwingUtilities.invokeAndWait(new Runnable() {
  175                       public void run() {
  176                           showModalOnEDT(isModal);
  177                       }
  178                   });
  179               } catch(InterruptedException e) {
  180                   throw new RuntimeException(e);
  181               } catch(InvocationTargetException e) {
  182                   Throwable cause = e.getCause();
  183                   if (cause instanceof RuntimeException) {
  184                      throw (RuntimeException) cause;
  185                   } else if (cause instanceof Error) {
  186                      throw (Error) cause;
  187                   } else {
  188                      throw new RuntimeException(cause);
  189                   }
  190               }
  191           }
  192       }
  193   
  194       /**
  195        * The EDT part of the showModal method.
  196        *
  197        * This method is to be called on the EDT only.
  198        */
  199       private void showModalOnEDT(boolean isModal) {
  200           assert SwingUtilities.isEventDispatchThread();
  201           init();
  202           abortDialog.setModal(isModal);
  203           abortDialog.setVisible(true);
  204       }
  205   
  206       /**
  207        * Disposes modal PrintingStatus dialog
  208        *
  209        * @see #showModal(boolean)
  210        */
  211       public void dispose() {
  212           if (SwingUtilities.isEventDispatchThread()) {
  213               disposeOnEDT();
  214           } else {
  215               SwingUtilities.invokeLater(new Runnable() {
  216                   public void run() {
  217                       disposeOnEDT();
  218                   }
  219               });
  220           }
  221       }
  222   
  223       /**
  224        * The EDT part of the dispose method.
  225        *
  226        * This method is to be called on the EDT only.
  227        */
  228       private void disposeOnEDT() {
  229           assert SwingUtilities.isEventDispatchThread();
  230           if (abortDialog != null) {
  231               abortDialog.removeWindowListener(closeListener);
  232               abortDialog.dispose();
  233               abortDialog = null;
  234           }
  235       }
  236   
  237       /**
  238        * Returns whether the printng was aborted using this PrintingStatus
  239        *
  240        * @return whether the printng was aborted using this PrintingStatus
  241        */
  242       public boolean isAborted() {
  243           return isAborted.get();
  244       }
  245   
  246       /**
  247        * Returns printable which is used to track the current page being
  248        * printed in this PrintingStatus
  249        *
  250        * @param printable to be used to create notification printable
  251        * @return printable which is used to track the current page being
  252        *         printed in this PrintingStatus
  253        * @throws NullPointerException if <code>printable</code> is <code>null</code>
  254        */
  255       public Printable createNotificationPrintable(Printable printable) {
  256           return new NotificationPrintable(printable);
  257       }
  258   
  259       private class NotificationPrintable implements Printable {
  260           private final Printable printDelegatee;
  261   
  262           public NotificationPrintable(Printable delegatee) {
  263               if (delegatee == null) {
  264                   throw new NullPointerException("Printable is null");
  265               }
  266               this.printDelegatee = delegatee;
  267           }
  268   
  269           public int print(final Graphics graphics,
  270                            final PageFormat pageFormat, final int pageIndex)
  271                   throws PrinterException {
  272   
  273               final int retVal =
  274                   printDelegatee.print(graphics, pageFormat, pageIndex);
  275               if (retVal != NO_SUCH_PAGE && !isAborted()) {
  276                   if (SwingUtilities.isEventDispatchThread()) {
  277                       updateStatusOnEDT(pageIndex);
  278                   } else {
  279                       SwingUtilities.invokeLater(new Runnable() {
  280                           public void run() {
  281                               updateStatusOnEDT(pageIndex);
  282                           }
  283                       });
  284                   }
  285               }
  286               return retVal;
  287           }
  288   
  289           /**
  290            * The EDT part of the print method.
  291            *
  292            * This method is to be called on the EDT only.
  293            */
  294           private void updateStatusOnEDT(int pageIndex) {
  295               assert SwingUtilities.isEventDispatchThread();
  296               Object[] pageNumber = new Object[]{
  297                   new Integer(pageIndex + 1)};
  298               statusLabel.setText(statusFormat.format(pageNumber));
  299           }
  300       }
  301   
  302       /**
  303        * Duplicated from UIManager to make it visible
  304        */
  305       static int getInt(Object key, int defaultValue) {
  306           Object value = UIManager.get(key);
  307           if (value instanceof Integer) {
  308               return ((Integer) value).intValue();
  309           }
  310           if (value instanceof String) {
  311               try {
  312                   return Integer.parseInt((String) value);
  313               } catch(NumberFormatException nfe) {
  314               }
  315           }
  316           return defaultValue;
  317       }
  318   }

Home » openjdk-7 » sun » swing » [javadoc | source]