Re: using threads
Daniel Pitts wrote:
Brandon McCombs wrote:
hello,
I have an LDAP program that uses threads to perform LDAP searches.
After actually getting the threads to properly start [I was calling
run() instead of "new Thread(p).start()"] my application responds really
fast and keeps chugging while the query in the background completes. The
problem is that I don't know how to actually retrieve the results from
the Vector that they were placed in so that I can display them in the
JList that I created. Since my program continued on, the code goes past
the point where the Vector normally would have data (without threads)
and would get loaded into the Jlist. So what's the proper way to
backtrack to get my Vector only after the thread has finished so the
data can be viewed? Do I have to end up employing another thread to
monitor the first one and then the code I have that loads the Vector
into my JList would get put into the second thread to be executed when
it detects the first thread completed?
thanks
something like this:
public class MyWorker implements Runnable {
// fields and constructor
public void run() {
final Result result = doWork();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
addResultToList(result);
}
});
}
}
You may have to move some things around in your program, Since you are
using threads, you need some sort of callback mechanism (such as the
addResultToList method, as I called it here). Its important to use
invokeLater, so that any GUI manipulation happens on the Event Dispatch
Thread. (google Swing and Threads)
Also look up SwingWorker. It wasn't a part of the standard Java
distribution, but you can find a copy of it easily online.
That direction of flow (bottom up the way I view it) is the opposite of
how I would prefer it because it makes the callback more difficult. I
have 3 classes involved in passing the data that results from the thread
executing. I have the JList/listmodel that will display the data and
a jbutton is really calling a local method from actionPerformed() that
will call my LDAP class's search() method. The LDAP class contains all
operations that would be done with the directory server, like searching.
The search() method ends up spawning another class that implements
Runnable to do the real work of (only) searching my directory server
(the search method uses the generic JNDI search method for an ldap
directory context so its the lowest level of my design). So somehow I
now have to make the lowest level worker object be responsible for
bypassing my stack of classes to update the GUI? That seems convoluted
to me. Or am I thinking totally the opposite of what I should be?
I seem to think I now have to tell my worker object that uses a thread
about my listmodel so that when it gets the data from its search
operation it has to be the one to update the listmodel. That means I
have to pass a reference of my listmodel through 3 classes so that the
worker object knows about it.
I also wanted the worker object to be generic so that it could also do
searches to update a JTree/treemodel (although it wasn't supposed to
have to know where the data would eventually end up) which means I'd
also have to tell the same class about my treemodel and I'll have to
tell it which to update (tree or list model) depending on what called
it. Not to mention I have JLabel in the GUI that gets updated with the #
of results that came back. Do I also have to pass in to the worker
object a reference to that label so it can update it?
There has to be a better way.
thanks
Brandon