KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > commons > cbutil > CBpbar


1 package com.ca.commons.cbutil;
2
3 import javax.swing.*;
4 import java.awt.*;
5
6 /**
7  * A component so cunning you could stick a tail on it
8  * and call it a weasel.<p>
9  * <p/>
10  * The basic idea is to create an easy interface to a
11  * progress bar, while navigating a tree. An object of
12  * CBpbar class handles the pbar, expecting calls from
13  * a separate thread, and enables
14  * the programmer to update the pbar with a minimum of
15  * fuss. The class is heavily optimised towards tree
16  * navigation; it will guess completion depending on what
17  * part of a (partially navigated) tree it is in, as well
18  * as keeping track of total objects written for label
19  * display.<p>
20  */

21
22 // Programmer note: written with a ProgressMonitor object,
23
// rather than extending ProgressMonitor, 'cause it
24
// seemed easier to do the SwingUtility.invokeLater()
25
// magic that way...
26

27 public class CBpbar
28 {
29     /**
30      * Constructor creates progress bar, and starts it up
31      * in a separate thread...
32      */

33
34     ProgressMonitor pbar;
35
36     int count; // number of nodes operated on
37

38     int pcntg; // (estimated) percentage complete
39

40     int level; // current depth in tree
41

42     static int MAXLEVEL = 6; // not interested in estimating percentage complete
43
// below this level in the tree (percentage pts are integral)
44
int fanout[] = new int[MAXLEVEL]; // total branches at each level - initialised to zero
45

46     int visited[] = new int[MAXLEVEL]; // branches visited at each level - initialised to zero
47

48     String JavaDoc notePrefix; // text prefixing the count number in the display
49

50     /**
51      * Constructor for progress bar.
52      *
53      * @param C a graphical 'hook' so the Progress Monitior knows where to
54      * display itself - usually a Swing Component of some sort...
55      * @param uberTitle a general desciption that appears in the box
56      * @param notePrefix the active description, that prefixes the changing
57      * 'count' value that the progress bar reports.
58      */

59
60     public CBpbar(Component C, String JavaDoc uberTitle, String JavaDoc notePrefix)
61     {
62         this.notePrefix = notePrefix;
63
64
65         pbar = new ProgressMonitor(C, uberTitle, notePrefix + " 0", 0, 100);
66         level = 0;
67         fanout[level] = 1; // the root node is unitary.
68
}
69
70     /**
71      * increments the displayed count by one,
72      * and (depending on the depth we're at, and
73      * the fanout set by @push) changes the percentage fill
74      * of the bar. Note that while every call of this makes
75      * a request to SwingUtilities.invokeLater(), not every call
76      * actually results in a visible update (Swing queues these
77      * request in order to avoid starving worker threads).
78      */

79
80     public void inc()
81     {
82         count++;
83         int oldpcntg = pcntg;
84         if (level < MAXLEVEL && level >= 0)
85         {
86
87 // moderate mathematical cunning here. Attempting (fairly brutaly)
88
// to establish what proportion of the tree has been visited, by
89
// assuming a perfectly 'balanced' tree, and toting up the bits
90
// that have been visited. This is computationally inefficient,
91
// but we have CPU cycles to spare, right?
92

93             visited[level]++;
94             pcntg = 0;
95             int spread = 100;
96             for (int i = 0; i < level; i++)
97             {
98                 pcntg += (spread * visited[i]) / fanout[i];
99                 spread = spread / fanout[i];
100             }
101
102             if (pcntg != oldpcntg)
103             {
104                 SwingUtilities.invokeLater(new Runnable JavaDoc()
105                 {
106                     public void run()
107                     {
108                         pbar.setProgress(pcntg);
109                         pbar.setNote(notePrefix + " " + count);
110                     }
111                 });
112             }
113         }
114     }
115
116     /**
117      * pop tells the progress bar that the tree process we are
118      * tracking has gone up a level.
119      */

120
121     public void pop()
122     {
123         level--;
124     }
125
126     /**
127      * push tells the progress bar that the process we are
128      * tracking has gone down a level, and that this level
129      * has a certain number of entries (i.e. branches). The
130      * progress bar uses this info for estimating (based on
131      * the assumption of a balanced tree) the proportion of
132      * the tree processed.
133      *
134      * @param fanout the number of branches at this level.
135      */

136     public void push(int fanout)
137     {
138         level++;
139         if (level < MAXLEVEL) this.fanout[level] = fanout;
140     }
141
142     /**
143      * Closes the progress bar.
144      */

145
146     public void close()
147     {
148         pbar.close();
149     }
150
151     /**
152      * returns whether the user has hit the 'cancel' button on the
153      * progress bar.
154      *
155      * @return the canceled status of the bar.
156      */

157
158     public boolean isCanceled()
159     {
160         return pbar.isCanceled();
161     }
162
163 }
Popular Tags