1
2
3
4 package ca.spaz.task;
5
6 import java.awt.BorderLayout;
7 import java.awt.event.*;
8 import java.util.*;
9
10 import javax.swing.*;
11 import javax.swing.Timer;
12
13 /***
14 * A TaskBar is a Swing component that can safely run a Task in a background
15 * thread, display progress of the task, interact with the task control,
16 * and fire events to report task progress.
17 *
18 * @see Task
19 * @see TaskListener
20 *
21 * @author Aaron Davidson
22 */
23 public class TaskBar extends JPanel {
24
25 private Task curTask;
26 private JProgressBar progressBar;
27 private JButton abortBtn;
28 private Timer timer;
29 private boolean aborting;
30 private ArrayList listeners;
31
32 public TaskBar() {
33 setLayout(new BorderLayout(4,4));
34 add(getProgressBar(), BorderLayout.CENTER);
35 add(getAbortButton(), BorderLayout.EAST);
36 }
37
38 private JProgressBar getProgressBar() {
39 if (progressBar == null) {
40 progressBar = new JProgressBar(JProgressBar.HORIZONTAL);
41 progressBar.setValue(0);
42 progressBar.setMinimum(0);
43 progressBar.setMaximum(100);
44 }
45 return progressBar;
46 }
47
48 public JButton getAbortButton() {
49 if (abortBtn == null) {
50 abortBtn = new JButton("Stop");
51 abortBtn.setEnabled(false);
52 abortBtn.addActionListener(new ActionListener() {
53 public void actionPerformed(ActionEvent e) {
54 abortCurrentTask();
55 }
56 });
57 }
58 return abortBtn;
59 }
60
61 public void abortCurrentTask() {
62 if (curTask != null) {
63 aborting = true;
64 curTask.abortTask();
65 progressBar.setString("Aborting...");
66 }
67 }
68 private Timer getTimer() {
69 if (timer == null) {
70 timer = new Timer(50, new ActionListener() {
71 public void actionPerformed(ActionEvent e) {
72 updateProgressBar();
73 }
74 });
75 timer.setCoalesce(true);
76 timer.setRepeats(true);
77 }
78 return timer;
79 }
80
81 /***
82 * Start the given task.
83 *
84 * @param t a Task to execute
85 */
86 public void executeTask(Task t) {
87 abortCurrentTask();
88 this.curTask = t;
89 fireTaskStarted();
90 getProgressBar().setValue(0);
91 getProgressBar().setStringPainted(true);
92 getAbortButton().setVisible(curTask.canAbortTask());
93 getAbortButton().setEnabled(curTask.canAbortTask());
94 Thread taskThread = new Thread(new Runnable() {
95 public void run() {
96 aborting = false;
97 if (curTask != null) {
98 curTask.run();
99 }
100 SwingUtilities.invokeLater(new Runnable() {
101 public void run() {
102 getTimer().stop();
103 getProgressBar().setStringPainted(false);
104 if (aborting) {
105 fireTaskAborted();
106 } else {
107 fireTaskFinished();
108 }
109
110 if (getProgressBar().getValue() != 100) {
111 getProgressBar().setValue(0);
112 }
113 getAbortButton().setEnabled(false);
114 curTask = null;
115 getProgressBar().setStringPainted(false);
116 }
117 });
118 }
119 }, "TaskBar");
120 taskThread.start();
121 getTimer().start();
122 }
123
124 private void updateProgressBar() {
125 if (curTask != null && !aborting) {
126 getProgressBar().setValue(curTask.getTaskProgress());
127 getProgressBar().setString(curTask.getTaskDescription());
128 }
129 }
130
131 /***
132 * Adds a task listener to this object to receive events on
133 * a task's progress.
134 *
135 * @param tl a task listener
136 */
137 public synchronized void addTaskListener(TaskListener tl) {
138 if (null == listeners) {
139 listeners = new ArrayList();
140 }
141 listeners.add(tl);
142 }
143
144 /***
145 * Remove a task listener from the TaskBar
146 *
147 * @param tl a task listener
148 */
149 public synchronized void removeTaskListener(TaskListener tl) {
150 if (listeners != null) {
151 listeners.remove(tl);
152 }
153 }
154
155 private synchronized void fireTaskStarted() {
156 if (listeners != null) {
157 Iterator iterator = listeners.iterator();
158 while (iterator.hasNext()) {
159 TaskListener tl = (TaskListener)iterator.next();
160 tl.taskStarted(curTask);
161 }
162 }
163 }
164
165 private synchronized void fireTaskAborted() {
166 if (listeners != null) {
167 Iterator iterator = listeners.iterator();
168 while (iterator.hasNext()) {
169 TaskListener tl = (TaskListener)iterator.next();
170 tl.taskAborted(curTask);
171 }
172 }
173 }
174
175 private synchronized void fireTaskFinished() {
176
177 if (getProgressBar().getValue() != 100) {
178 getProgressBar().setValue(100);
179 }
180 if (listeners != null) {
181 Iterator iterator = listeners.iterator();
182 while (iterator.hasNext()) {
183 TaskListener tl = (TaskListener)iterator.next();
184 tl.taskFinished(curTask);
185 }
186 }
187 }
188
189
190 }