KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > foxtrot > examples > ProgressExample


1 /**
2  * Copyright (c) 2002-2005, Simone Bordet
3  * All rights reserved.
4  *
5  * This software is distributable under the BSD license.
6  * See the terms of the BSD license in the documentation provided with this software.
7  */

8
9 package foxtrot.examples;
10
11 import java.awt.BorderLayout JavaDoc;
12 import java.awt.Container JavaDoc;
13 import java.awt.Dimension JavaDoc;
14 import java.awt.Toolkit JavaDoc;
15 import java.awt.event.ActionEvent JavaDoc;
16 import java.awt.event.ActionListener JavaDoc;
17 import java.util.ArrayList JavaDoc;
18
19 import javax.swing.DefaultComboBoxModel JavaDoc;
20 import javax.swing.JButton JavaDoc;
21 import javax.swing.JFrame JavaDoc;
22 import javax.swing.JPanel JavaDoc;
23 import javax.swing.JProgressBar JavaDoc;
24 import javax.swing.SwingUtilities JavaDoc;
25 import javax.swing.border.EmptyBorder JavaDoc;
26
27 import foxtrot.Job;
28 import foxtrot.Worker;
29
30 /**
31  * An example of how to use progress indication with Foxtrot.
32  * The main advantage is that there is no more need to create a separate thread
33  * for the progressive operation, but just use the Foxtrot API.
34  * And, of course, with Foxtrot the GUI can be interrupted in any moment.
35  *
36  * @version $Revision: 1.6 $
37  */

38 public class ProgressExample extends JFrame JavaDoc
39 {
40    private JButton JavaDoc button;
41    private JProgressBar JavaDoc bar;
42    private boolean running;
43    private boolean taskInterrupted;
44
45    public static void main(String JavaDoc[] args)
46    {
47       ProgressExample example = new ProgressExample();
48       example.setVisible(true);
49    }
50
51    public ProgressExample()
52    {
53       super("Foxtrot Example");
54
55       button = new JButton JavaDoc("Run Task !");
56       button.addActionListener(new ActionListener JavaDoc()
57       {
58          public void actionPerformed(ActionEvent JavaDoc e)
59          {
60             if (running)
61                onCancelClicked();
62             else
63                onRunClicked();
64          }
65       });
66
67       bar = new JProgressBar JavaDoc();
68       bar.setStringPainted(true);
69
70       setDefaultCloseOperation(EXIT_ON_CLOSE);
71
72       Container JavaDoc c = getContentPane();
73       c.setLayout(new BorderLayout JavaDoc(0, 0));
74
75       JPanel JavaDoc main = new JPanel JavaDoc(new BorderLayout JavaDoc(0, 0));
76       main.setBorder(new EmptyBorder JavaDoc(35, 35, 35, 35));
77       c.add(main, BorderLayout.CENTER);
78
79       JPanel JavaDoc p = new JPanel JavaDoc(new BorderLayout JavaDoc(20, 20));
80       p.add(bar, BorderLayout.NORTH);
81       p.add(button, BorderLayout.SOUTH);
82
83       main.add(p);
84
85       setSize(300, 200);
86
87       Dimension JavaDoc screen = Toolkit.getDefaultToolkit().getScreenSize();
88       Dimension JavaDoc size = getSize();
89       int x = (screen.width - size.width) >> 1;
90       int y = (screen.height - size.height) >> 1;
91       setLocation(x, y);
92    }
93
94    private void onRunClicked()
95    {
96       // We are running
97
running = true;
98
99       // We just started, set the task as not interrupted, to
100
// clear any eventual previous status
101
setTaskInterrupted(false);
102
103       // We will execute a long operation, change the text signaling
104
// that the user can interrupt the operation
105
button.setText("Cancel");
106
107       // getData() will block until the heavy operation is finished
108
// and the AWT-Swing events will be dequeued and processed
109
ArrayList JavaDoc list = getData();
110
111       // Restore the button's text
112
button.setText("Run Task !");
113
114       // We're not running anymore
115
running = false;
116
117       // getData() finished or was interrupted ?
118
// If was interrupted we get back a null list
119
if (list != null)
120       {
121          // Task completed successfully, do whatever useful with the list
122
// For example, populate a JComboBox
123
// The reader will finish this part :)
124
DefaultComboBoxModel JavaDoc model = new DefaultComboBoxModel JavaDoc(list.toArray());
125       }
126    }
127
128    private void onCancelClicked()
129    {
130       // Here if we want to interrupt the Task
131

132       setTaskInterrupted(true);
133    }
134
135    private ArrayList JavaDoc getData()
136    {
137       return (ArrayList JavaDoc)Worker.post(new Job()
138       {
139          public Object JavaDoc run()
140          {
141             ArrayList JavaDoc list = new ArrayList JavaDoc();
142             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
143
144             // A repetitive operation that updates a progress bar.
145
int max = 20;
146             for (int i = 1; i <= max; ++i)
147             {
148                // Simulate a heavy operation to retrieve data
149
try
150                {
151                   Thread.sleep(250);
152                }
153                catch (InterruptedException JavaDoc ignored)
154                {
155                }
156
157                // Populate the data structure
158
Object JavaDoc data = new Object JavaDoc();
159                list.add(data);
160
161                // Prepare the progress bar string
162
buffer.setLength(0);
163                buffer.append("Step ").append(i).append(" of ").append(max);
164
165                if (isTaskInterrupted())
166                {
167                   buffer.append(" - Interrupted !");
168                   update(i, max, buffer.toString());
169                   break;
170                }
171                else
172                {
173                   // Update the progress bar
174
update(i, max, buffer.toString());
175                }
176             }
177
178             if (isTaskInterrupted())
179             {
180                // Task is interrupted, clean the half-populated data structure
181
// and return from the Task
182
list.clear();
183                return null;
184             }
185             else
186             {
187                return list;
188             }
189          }
190       });
191    }
192
193    private void update(final int index, final int max, final String JavaDoc string)
194    {
195       // This method is called by the Foxtrot Worker thread, but I want to
196
// update the GUI, so I use SwingUtilities.invokeLater, as the Task
197
// is not finished yet.
198

199       SwingUtilities.invokeLater(new Runnable JavaDoc()
200       {
201          public void run()
202          {
203             bar.setMaximum(max);
204             bar.setValue(index);
205             bar.setString(string);
206          }
207       });
208    }
209
210    private synchronized boolean isTaskInterrupted()
211    {
212       // Called from the Foxtrot Worker Thread.
213
// Must be synchronized, since the variable taskInterrupted is accessed from 2 threads.
214
// While it is easier just to change the variable value without synchronizing, it is possible
215
// that the Foxtrot worker thread doesn't see the change (it may cache the value of the variable
216
// in a registry).
217
return taskInterrupted;
218    }
219
220    private synchronized void setTaskInterrupted(boolean value)
221    {
222       // Called from the AWT Event Dispatch Thread.
223
// See comments above on why it must be synchronized.
224
taskInterrupted = value;
225    }
226 }
227
Popular Tags