Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/virtuosotechnologies/lib/swing/ModalProgressTracker.java


1   /*
2   ================================================================================
3   
4     FILE:  ModalProgressTracker.java
5     
6     PROJECT:
7     
8       Virtuoso Utilities
9     
10    CONTENTS:
11    
12      An object that spawns a modal progress tracker dialog for AsyncJobs
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.lib.swing;
43  
44  
45  import java.awt.Container;
46  import java.awt.Dialog;
47  import java.awt.Frame;
48  import java.awt.Rectangle;
49  import java.awt.GridBagLayout;
50  import java.awt.GridBagConstraints;
51  import java.awt.event.ActionListener;
52  import java.awt.event.ActionEvent;
53  import java.util.Map;
54  import java.util.HashMap;
55  import java.util.Iterator;
56  import javax.swing.Timer;
57  import javax.swing.JComponent;
58  import javax.swing.JDialog;
59  import javax.swing.JPanel;
60  import javax.swing.JScrollPane;
61  import javax.swing.SwingUtilities;
62  
63  import com.virtuosotechnologies.lib.asyncjob.AsyncJobListener;
64  import com.virtuosotechnologies.lib.asyncjob.AsyncJobProgressEvent;
65  import com.virtuosotechnologies.lib.asyncjob.AsyncJobStartedEvent;
66  import com.virtuosotechnologies.lib.asyncjob.AsyncJobEvent;
67  import com.virtuosotechnologies.lib.asyncjob.AsyncJobCompletedEvent;
68  import com.virtuosotechnologies.lib.asyncjob.AsyncJobFailedEvent;
69  import com.virtuosotechnologies.lib.asyncjob.AsyncJob;
70  
71  
72  /**
73   * An object that spawns a modal progress tracker dialog for AsyncJobs.
74   *
75   * @author Daniel Azuma
76   */
77  public class ModalProgressTracker
78  implements AsyncJobListener
79  {
80    private static class JobInfo
81    {
82      ProgressTrackingPane pane;
83      AsyncJobProgressEvent lastProgress;
84      
85      private JobInfo()
86      {
87        pane = null;
88        lastProgress = null;
89      }
90    }
91    
92    
93    private static final int INITIAL_DIALOG_WIDTH = 300;
94    private static final int INITIAL_DIALOG_HEIGHT = 150;
95    private static final int DEFAULT_UPDATE_INTERVAL = 100;
96    
97    
98    private JDialog dialog_;
99    private int dialogWidth_;
100   private int dialogHeight_;
101   private JComponent dialogContent_;
102   private JComponent dialogParent_;
103   
104   private Map jobInfoMap_;
105   private JPanel innerPanel_;
106   private GridBagConstraints paneConstraints_;
107   private Timer timer_;
108   
109   
110   /**
111    * Constructor
112    */
113   public ModalProgressTracker(
114     JComponent parent)
115     {
116     this(parent, DEFAULT_UPDATE_INTERVAL, INITIAL_DIALOG_WIDTH, INITIAL_DIALOG_HEIGHT);
117   }
118   
119   
120   /**
121    * Constructor
122    */
123   public ModalProgressTracker(
124     JComponent parent,
125     int updateIntervalMillis)
126     {
127     this(parent, updateIntervalMillis, INITIAL_DIALOG_WIDTH, INITIAL_DIALOG_HEIGHT);
128   }
129   
130   
131   /**
132    * Constructor
133    */
134   public ModalProgressTracker(
135     JComponent parent,
136     int updateIntervalMillis,
137     int initialDialogWidth,
138     int initialDialogHeight)
139     {
140     dialogParent_ = parent;
141     dialogWidth_ = initialDialogWidth;
142     dialogHeight_ = initialDialogHeight;
143     
144     jobInfoMap_ = new HashMap();
145     timer_ = new Timer(updateIntervalMillis,
146       new ActionListener()
147       {
148         public void actionPerformed(
149           ActionEvent ev)
150         {
151           doTimer();
152         }
153       });
154     
155     innerPanel_ = new JPanel(new GridBagLayout());
156     paneConstraints_ = new GridBagConstraints();
157     paneConstraints_.gridx = 0;
158     paneConstraints_.weightx = 1.0;
159     paneConstraints_.weighty = 0.0;
160     paneConstraints_.fill = GridBagConstraints.HORIZONTAL;
161     
162     JPanel outerPanel = new JPanel(new GridBagLayout());
163     GridBagConstraints gbc = new GridBagConstraints();
164     gbc.anchor = GridBagConstraints.NORTH;
165     gbc.fill = GridBagConstraints.HORIZONTAL;
166     gbc.weightx = 1.0;
167     gbc.weighty = 1.0;
168     outerPanel.add(innerPanel_, gbc);
169     
170     dialogContent_ = new JScrollPane(outerPanel);
171   }
172   
173   
174   private void openDialog()
175   {
176     Container toplevel = dialogParent_.getTopLevelAncestor();
177     if (toplevel instanceof Dialog)
178     {
179       dialog_ = new JDialog((Dialog)toplevel, ResourceAccess.Strings.buildString(
180         "ProgressTracker_DialogName"), true);
181     }
182     else if (toplevel instanceof Frame)
183     {
184       dialog_ = new JDialog((Frame)toplevel, ResourceAccess.Strings.buildString(
185         "ProgressTracker_DialogName"), true);
186     }
187     else
188     {
189       // Bail
190       return;
191     }
192     
193     dialog_.setContentPane(dialogContent_);
194     dialog_.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
195     dialog_.setSize(dialogWidth_, dialogHeight_);
196     dialog_.setLocationRelativeTo(dialogParent_);
197     dialog_.show();
198   }
199   
200   
201   private void closeDialog()
202   {
203     if (dialog_.getWidth() > 100)
204     {
205       dialogWidth_ = dialog_.getWidth();
206     }
207     if (dialog_.getHeight() > 50)
208     {
209       dialogHeight_ = dialog_.getHeight();
210     }
211     dialog_.dispose();
212     dialog_ = null;
213   }
214   
215   
216   /**
217    * A job has started
218    *
219    * @param event AsyncJobStartedEvent
220    */
221   public void jobStarted(
222     AsyncJobStartedEvent event)
223   {
224     final AsyncJob job = event.getAsyncJob();
225     final JobInfo info = new JobInfo();
226     synchronized(this)
227     {
228       jobInfoMap_.put(job, info);
229     }
230     
231     SwingUtilities.invokeLater(
232       new Runnable()
233       {
234         public void run()
235         {
236           synchronized(ModalProgressTracker.this)
237           {
238             info.pane = new ProgressTrackingPane(job);
239           }
240           innerPanel_.add(info.pane, paneConstraints_);
241           if (innerPanel_.getComponentCount() == 1)
242           {
243             timer_.start();
244             openDialog();
245           }
246         }
247       });
248   }
249   
250   
251   /**
252    * Receive a progress update
253    *
254    * @param event AsyncJobProgressEvent
255    */
256   public synchronized void jobProgressed(
257     final AsyncJobProgressEvent event)
258   {
259     final JobInfo info = (JobInfo)jobInfoMap_.get(event.getAsyncJob());
260     if (info != null)
261     {
262       info.lastProgress = event;
263     }
264   }
265   
266   
267   /**
268    * A job has completed
269    *
270    * @param event AsyncJobCompletedEvent
271    */
272   public void jobCompleted(
273     AsyncJobCompletedEvent event)
274   {
275     closePane(event);
276   }
277   
278   
279   /**
280    * A job has failed
281    *
282    * @param event AsyncJobFailedEvent
283    */
284   public void jobFailed(
285     AsyncJobFailedEvent event)
286   {
287     closePane(event);
288   }
289   
290   
291   private synchronized void closePane(
292     AsyncJobEvent event)
293   {
294     final JobInfo info = (JobInfo)jobInfoMap_.remove(event.getAsyncJob());
295     SwingUtilities.invokeLater(
296       new Runnable()
297       {
298         public void run()
299         {
300           innerPanel_.remove(info.pane);
301           if (innerPanel_.getComponentCount() == 0)
302           {
303             timer_.stop();
304             closeDialog();
305           }
306         }
307       });
308   }
309   
310   
311   private synchronized void doTimer()
312   {
313     for (Iterator iter = jobInfoMap_.entrySet().iterator(); iter.hasNext(); )
314     {
315       Map.Entry entry = (Map.Entry)iter.next();
316       AsyncJob job = (AsyncJob)entry.getKey();
317       JobInfo info = (JobInfo)entry.getValue();
318       if (info.pane != null && info.lastProgress != null)
319       {
320         info.pane.jobProgressed(info.lastProgress);
321       }
322     }
323   }
324 }