Threads and Swing
Multithreading
Contents
I.Simulation
on Inserting and Removing
Items in a Combo Box
II.Event Dispatch Thread
III.Rules for Running Time-Consuming
Tasks
IV.The Reading Text File Problem
I. Simulation on Inserting and
Removing Items in a Combo
Develop a GUI program to
Box
insert/remove an item (a positive
integer) to/from a combo box
continuously and randomly in a
separate thread
A sample GUI is below
As long as the button is clicked, the
simulation runs
Solution
1.Developing
a Non-Thread-Safe
Solution
2.Observing the Problem
3.Correcting the Problem
1. Developing a Non-Thread-Safe
Solution
1.1. The Main Class
1.2. Developing the View
1.3. Adding Listener to the Button
1.1. The Main Class
1.2. Developing the View
1.3. Adding Listener to the Button
2. Observing the Problem
Click
the Remove/Insert button > Click the combo
box a few times > Move the scrollbar > Move the
window > Click the Remove/Insert button again >
Keep clicking the combo box > Eventually, you
should see an exception report
What is going on?
When an element is inserted into the combo box, the
combo box fires an event to update the display
Then, the display code springs into action, reading the
current size of the combo box and preparing to display
the values
But the worker thread keeps going - occasionally
resulting in a reduction of the count of the values in
the combo box. The display code then thinks that there
are more values in the model than there actually are,
asks for nonexistent values, and triggers an
3. Correcting the Problem: Put the
Updating GUI Code to the Event
Dispatch Thread
II. Event Dispatch Thread
The
thread of control that passes
events such as mouse clicks and
keystrokes to the user interface
components
Every Java application starts with a main
method that runs in the main thread
In a Swing program, the main thread is shortlived. It schedules the construction of the user
interface in the event dispatch thread and then
exits
The event dispatch thread keeps the program
alive until it is terminated, either by closing the
III. Rules for Running TimeConsuming Tasks
If
an action takes a long time, do it in a separate
worker thread and never in the event dispatch
thread.
Do not touch Swing components in any thread
other than the event dispatch thread by using
EventQueue.invokeLater() or
EventQueue.invokeAndWait()
The invokeLater method returns immediately when
the event is posted to the event queue
The invokeAndWait method waits until the run
method has actually been executed
IV. The Reading Text File
Problem
Develop a program for loading a text file
and for canceling the file loading process
Since we want to be able to load big files, a
separate thread should be used for loading
While the file is read, the Open menu item
is disabled and the Cancel item is enabled
(see the next slide)
After each line is read, a line counter in the
status bar is updated
After the reading process is complete, the
Open menu item is reenabled, the Cancel
item is disabled, and the status line text is
set to Done
Solution
1.Developing
the View
2.Adding Listeners to the Menu Items
1. Developing the View
2. Adding Listeners to the
Menu Items
2.1. Adding Listener to the Open Menu
Item
2.2. Adding Listener to the Cancel
Menu Item
2.1 Adding Listener to the Open
2.1.1.Item
Getting the Selected File
Menu
2.1.2. Showing Content in the Selected
File
2.1.1 Getting the Selected File
2.1.2 Showing Content in the Selected
File
2.1.2.1. A Single-Threading Version
2.1.2.2. A Multiple-Threading Version
2.1.2.1. A Single-Threading Version
2.1.2.2. A Multiple-Threading Version
Using
SwingWorker
Defining Result Type and Progress Data Type
Developing the Text Reading Thread
Using SwingWorker
The
typical UI activities of a background task:
After each work unit, update the UI to show
progress.
After the work is finished, make a final change
to the UI.
The SwingWorker class makes it easy to
implement such a task.
Using SwingWorker
Since
the reading process can take a long time,
we use the SwingWorker class to fire up a new
thread to do the work
SwingWorker(T, V)
T: Final result of type T
V: Intermediate progress data of type V
Using SwingWorker
Override
the doInBackground method to do the
time-consuming work
The doInBackground method is executed in a
worker thread.
In the doInBackground method, occasionally call
publish method to communicate work progress.
The publish method causes a process method to
execute in the event dispatch thread to deal with
the progress data.
When
the work is complete, the done method
is called in the event dispatch thread so that we
can finish updating the UI.
To cancel the work in progress, use the cancel
method.
When the work is canceled, the get method
throws a CancellationException.
Event Dispatch Thread
swObj.execute()
Worker Thread
swObj.doInBackground()
Do the job
swObj.process()
swObj.done()
The get() does not throw
a CancellationException
swObj.publish()
Defining Final Result Type and Progress Data
Type
Final Result Type
String, but StringBuilder would be more efficient for
big files
Progress
Data Type: The Current Line
Developing the Text Reading Thread
Developing doInBackground() for Carrying out the Task
Developing process() for Processing Progress Data
in the Event Dispatch Thread
Developing done()
2.2. Adding Listener to the Cancel
Menu Item
Run
the program and try to click Cancel
Ignore
the exception message
References
1.Core
Java, Volume I - Fundamentals,
Eighth Edition, Chapter 14.
CayS.Horstmann and Gary
Cornell.Prentice Hall, 2008