1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * ident        "%Z%%M% %I%     %E% SMI"
  24  *
  25  * Copyright (c) 1999 by Sun Microsystems, Inc.
  26  * All rights reserved.
  27  */
  28 package com.sun.dhcpmgr.client;
  29 
  30 import javax.swing.SwingUtilities;
  31 import javax.swing.JScrollPane;
  32 import javax.swing.JOptionPane;
  33 import java.awt.Frame;
  34 import java.awt.Dimension;
  35 
  36 import com.sun.dhcpmgr.ui.ProgressManager;
  37 
  38 /**
  39  * This abstract class provides a common implementation of the functions
  40  * shared by the dialogs which perform multiple operations such as adding
  41  * and deleting addresses or networks.  It provides a framework within
  42  * which subclasses may execute such operations in a background thread
  43  * and use progress meters and capture and display multiple error messages.
  44  * Nearly all of the methods here are defined as protected because they're
  45  * really implementation details for the dialogs and need not be visible
  46  * outside that context.
  47  */
  48 public abstract class MultipleOperationDialog extends DhcpmgrDialog {
  49     // Progress Manager provides convenient handling of progress dialogs
  50     protected ProgressManager progManager;
  51     // ErrorTable provides a convenient storehouse for sets of errors
  52     protected ErrorTable messageTable;
  53 
  54     public MultipleOperationDialog(Frame f, boolean allowsReset) {
  55         super(f, allowsReset);
  56     }
  57 
  58     /**
  59      * Initiate the action in a background thread when the user presses OK;
  60      * subclasses should not need to override this, instead they provide
  61      * an implementation of getOperationThread() where the actions needed
  62      * are executed.
  63      */
  64     protected void doOk() {
  65         progManager = new ProgressManager(this, getProgressMessage(), "", 0,
  66             getProgressLength());
  67         messageTable = new ErrorTable(getErrorHeading(), getErrorClass());
  68         getOperationThread().start();
  69     }
  70 
  71     /**
  72      * Update progress meter; subclasses should call as each operation is
  73      * completed.  InterruptedException is thrown by the ProgressManager
  74      * if user pressed Cancel in the progress dialog that was popped up.
  75      * Typically the subclass should abort its operation thread when this
  76      * occurs.
  77      */
  78     protected void updateProgress(int progress, String msg)
  79             throws InterruptedException {
  80         progManager.update(progress, msg);
  81     }
  82 
  83     /**
  84      * Get thread which will perform the operation
  85      */
  86     protected abstract Thread getOperationThread();
  87 
  88     /**
  89      * Get message to display in progress dialog
  90      */
  91     protected abstract String getProgressMessage();
  92 
  93     /**
  94      * Get length of operation
  95      */
  96     protected abstract int getProgressLength();
  97 
  98     /**
  99      * Get rid of dialog when we're done
 100      */
 101     public void closeDialog() {
 102         Runnable finisher = new Runnable() {
 103             public void run() {
 104                 fireActionPerformed();
 105                 setVisible(false);
 106                 dispose();
 107             }
 108         };
 109         SwingUtilities.invokeLater(finisher);
 110     }
 111 
 112     /**
 113      * Display the errors
 114      */
 115     protected void displayErrors(final String msg) {
 116         /*
 117          * Use a Runnable and invokeAndWait as we're usually called from
 118          * the operation thread, not the AWT thread.
 119          */
 120         Runnable errorDisplay = new Runnable() {
 121             public void run() {
 122                 JScrollPane scrollPane = new JScrollPane(messageTable);
 123                 Dimension d = messageTable.getPreferredScrollableViewportSize();
 124                 d.height = 80;
 125                 messageTable.setPreferredScrollableViewportSize(d);
 126                 Object [] objs = new Object[] { msg, scrollPane };
 127                 JOptionPane.showMessageDialog(MultipleOperationDialog.this,
 128                     objs, ResourceStrings.getString("server_error_title"),
 129                     JOptionPane.ERROR_MESSAGE);
 130             }
 131         };
 132         try {
 133             SwingUtilities.invokeAndWait(errorDisplay);
 134         } catch (Throwable e) {
 135             // If this failed we're basically in a bailout situation
 136             e.printStackTrace();
 137         }
 138     }
 139 
 140     /**
 141      * Return the heading for the error table
 142      */
 143     protected abstract String getErrorHeading();
 144 
 145     /**
 146      * Return the class for the error data; default to String, subclass can
 147      * override as needed.
 148      */
 149     protected Class getErrorClass() {
 150         return String.class;
 151     }
 152 
 153     /**
 154      * Add an error to the error table; obj must be of the class returned by
 155      * getErrorClass
 156      */
 157     protected void addError(Object obj, String msg) {
 158         messageTable.addError(obj, msg);
 159     }
 160 
 161     /**
 162      * Test for errors occurred
 163      */
 164     protected boolean errorsOccurred() {
 165         return !messageTable.isEmpty();
 166     }
 167 }