KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > foxtrot > examples > InterruptExample


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.Container JavaDoc;
12 import java.awt.GridBagLayout JavaDoc;
13 import java.awt.Dimension JavaDoc;
14 import java.awt.Toolkit JavaDoc;
15 import java.awt.event.ActionListener JavaDoc;
16 import java.awt.event.ActionEvent JavaDoc;
17 import java.util.ArrayList JavaDoc;
18
19 import javax.swing.JFrame JavaDoc;
20 import javax.swing.JButton JavaDoc;
21
22 import foxtrot.Task;
23 import foxtrot.Worker;
24
25 /**
26  * An example of how to create a Task that is interruptible. <p>
27  * This is not provided by the Foxtrot API, because it is too much application dependent: what are
28  * the correct actions to take when a Task is interrupted ? <br>
29  * This implies that the Task must be collaborative, and check once in a while if it is interrupted
30  * by another thread.
31  *
32  * @version $Revision: 1.3 $
33  */

34 public class InterruptExample extends JFrame JavaDoc
35 {
36    private JButton JavaDoc button;
37    private boolean running;
38    private boolean taskInterrupted;
39
40    public static void main(String JavaDoc[] args)
41    {
42       InterruptExample example = new InterruptExample();
43       example.setVisible(true);
44    }
45
46    public InterruptExample()
47    {
48       super("Foxtrot Example");
49
50       final String JavaDoc label = "Run Task !";
51       button = new JButton JavaDoc(label);
52       button.addActionListener(new ActionListener JavaDoc()
53       {
54          public void actionPerformed(ActionEvent JavaDoc e)
55          {
56             onButtonClick(label);
57          }
58       });
59
60       setDefaultCloseOperation(EXIT_ON_CLOSE);
61
62       Container JavaDoc c = getContentPane();
63       c.setLayout(new GridBagLayout JavaDoc());
64       c.add(button);
65
66       setSize(300, 200);
67
68       Dimension JavaDoc screen = Toolkit.getDefaultToolkit().getScreenSize();
69       Dimension JavaDoc size = getSize();
70       int x = (screen.width - size.width) >> 1;
71       int y = (screen.height - size.height) >> 1;
72       setLocation(x, y);
73    }
74
75    private void onButtonClick(final String JavaDoc label)
76    {
77       if (!running)
78       {
79          running = true;
80
81          // We will execute a long operation, change the text signaling
82
// that the user can interrupt the operation
83
button.setText("Interrupt");
84
85          try
86          {
87             // getData() will block until the heavy operation is finished
88
ArrayList JavaDoc list = getData();
89
90             // getData() finished or was interrupted ?
91
// If was interrupted we get back a null list
92
if (list == null)
93             {
94                // Task was interrupted, return quietly, we already cleaned up
95
return;
96             }
97             else
98             {
99                // Task completed successfully, do whatever useful with the list
100
// For example, populate a JComboBox
101
javax.swing.DefaultComboBoxModel JavaDoc model = new javax.swing.DefaultComboBoxModel JavaDoc(list.toArray());
102                // The reader will finish this part :)
103
}
104          }
105          catch (Exception JavaDoc x)
106          {
107             // Problems during getData(), log this exception and return
108
x.printStackTrace();
109          }
110          finally
111          {
112             // Restore anyway the button's text
113
button.setText(label);
114
115             // Restore anyway the interrupt status for another call
116
setTaskInterrupted(false);
117
118             // We're not running anymore
119
running = false;
120          }
121       }
122       else
123       {
124          // Here if we want to interrupt the Task
125

126          // Restore the button text to the previous value
127
button.setText(label);
128
129          // Interrupt the task
130
setTaskInterrupted(true);
131       }
132    }
133
134    private ArrayList JavaDoc getData() throws Exception JavaDoc
135    {
136       return (ArrayList JavaDoc)Worker.post(new Task()
137       {
138          public Object JavaDoc run() throws Exception JavaDoc
139          {
140             System.out.println("Task started...");
141
142             ArrayList JavaDoc list = new ArrayList JavaDoc();
143
144             // A repetitive operation that checks if it is interrupted.
145
// The heavy task must collaborate !
146
for (int i = 0; i < 100; ++i)
147             {
148                System.out.println("Heavy Operation number " + (i + 1));
149
150                // Simulate a heavy operation to retrieve data
151
Thread.sleep(250);
152
153                // Populate the data structure
154
Object JavaDoc data = new Object JavaDoc();
155                list.add(data);
156
157                System.out.println("Checking if task is interrupted...");
158                if (isTaskInterrupted())
159                {
160                   System.out.println("Task interrupted !");
161                   break;
162                }
163                System.out.println("Task not interrupted, going on");
164             }
165
166             if (isTaskInterrupted())
167             {
168                // Task is interrupted, clean the half-populated data structure
169
// and return from the Task
170
list.clear();
171                return null;
172             }
173
174             return list;
175          }
176       });
177    }
178
179    private synchronized boolean isTaskInterrupted()
180    {
181       // Called from the Foxtrot Worker Thread.
182
// Must be synchronized, since the variable taskInterrupted is accessed from 2 threads.
183
// While it is easier just to change the variable value without synchronizing, it is possible
184
// that the Foxtrot worker thread doesn't see the change (it may cache the value of the variable
185
// in a registry).
186
return taskInterrupted;
187    }
188
189    private synchronized void setTaskInterrupted(boolean value)
190    {
191       // Called from the AWT Event Dispatch Thread.
192
// See comments above on why it must be synchronized.
193
taskInterrupted = value;
194    }
195 }
196
Popular Tags