J
juventuz2000
I'll start by shortly explaining the rationale for my implementation. I
have a gui form which takes input from the user and starts a lengthy
processing of it. I want to keep the gui responsive so I've put the
processing into a separate thread. There is exactly one thread doing
this.
The processing I mentioned is a rather long method, using a bunch of
libraries, where a lot of things can go wrong. I've wrapped this in a
try block and I'm catching exceptions, which are to be reported to the
gui. I'll post a snippet of the code below.
class CertCreate implements Runnable {
public void run() {
generateRequest();
}
public void generateRequest() {
try {
// processing
} catch (Exception e) {
threadlistener.reportFatalError(e);
}
}
What happens inside the try block is that before the actual "work"
starts, I check to see if the output file(s) (2 of them) exist, like
so:
// Check if certificate file exists
if ((new File(name + userCertFile)).exists())
throw new Exception("Certificate file exists in: " +
name + userCertFile + ", will not overwrite.");
// Check if private key file exists
if ((new File(name + userKeyFile)).exists())
throw new Exception("Private key file exists in: " +
name + userKeyFile + ", will not overwrite.");
The way I intended it, the exception is caught and sent to
ThreadListener, a class I created solely for the purpose of reporting
errors to. Both the gui and the CertCreate class share the same
instance of a ThreadListener object, the former reports to it, the
latter collects errors from it and prints them.
Now, once generateRequest() catches an exception and reports it, it's
supposed to die, its job is over. Meanwhile, what happens is the
following. IF the two output files don't exist, the thread creates them
correctly. IF the files DO exist, the thread stops at the first
exception, again completes correctly. But consider the following
scenario. The user tried to create the files, they already exist, error
reported. Then the user deletes them himself, tries again. In that
case, the thread reports the files already exist (even though it's
incorrect) AND CREATES THEM (I verified that they are created
correctly). In the first place, I don't know why it thinks they exist,
but be that as it may, why does it not stop at the first exception, why
does it continue?
To complicate things a bit, the above description is not 100% complete.
While the processing is running, I wanted the gui to display these
progress indicators, just to show that something is indeed happening.
So I did that very simply by using a TimerTask. This is how it works:
class TimerTaskUpdateStatusBar extends TimerTask {
public void run() {
if (thread.isAlive()) {
statusbar.addProcessIndicator(null);
} else {
timer.cancel();
}
}
}
Lastly, this is how I start the thread in the gui class:
public void startThread(Runnable runnable, String startMsg) {
// Generate certificate
Thread thread = new Thread(runnable);
threadlistener.setThread(thread);
// keep gui responsive
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
// Print status of thread process
statusbar.addMessage("+++++++ " + startMsg + " +++++++\n");
java.util.Timer timer = new java.util.Timer();
timer.scheduleAtFixedRate((new
TimerTaskUpdateStatusBar(timer, thread, this, statusbar)), 0, 500);
}
have a gui form which takes input from the user and starts a lengthy
processing of it. I want to keep the gui responsive so I've put the
processing into a separate thread. There is exactly one thread doing
this.
The processing I mentioned is a rather long method, using a bunch of
libraries, where a lot of things can go wrong. I've wrapped this in a
try block and I'm catching exceptions, which are to be reported to the
gui. I'll post a snippet of the code below.
class CertCreate implements Runnable {
public void run() {
generateRequest();
}
public void generateRequest() {
try {
// processing
} catch (Exception e) {
threadlistener.reportFatalError(e);
}
}
What happens inside the try block is that before the actual "work"
starts, I check to see if the output file(s) (2 of them) exist, like
so:
// Check if certificate file exists
if ((new File(name + userCertFile)).exists())
throw new Exception("Certificate file exists in: " +
name + userCertFile + ", will not overwrite.");
// Check if private key file exists
if ((new File(name + userKeyFile)).exists())
throw new Exception("Private key file exists in: " +
name + userKeyFile + ", will not overwrite.");
The way I intended it, the exception is caught and sent to
ThreadListener, a class I created solely for the purpose of reporting
errors to. Both the gui and the CertCreate class share the same
instance of a ThreadListener object, the former reports to it, the
latter collects errors from it and prints them.
Now, once generateRequest() catches an exception and reports it, it's
supposed to die, its job is over. Meanwhile, what happens is the
following. IF the two output files don't exist, the thread creates them
correctly. IF the files DO exist, the thread stops at the first
exception, again completes correctly. But consider the following
scenario. The user tried to create the files, they already exist, error
reported. Then the user deletes them himself, tries again. In that
case, the thread reports the files already exist (even though it's
incorrect) AND CREATES THEM (I verified that they are created
correctly). In the first place, I don't know why it thinks they exist,
but be that as it may, why does it not stop at the first exception, why
does it continue?
To complicate things a bit, the above description is not 100% complete.
While the processing is running, I wanted the gui to display these
progress indicators, just to show that something is indeed happening.
So I did that very simply by using a TimerTask. This is how it works:
class TimerTaskUpdateStatusBar extends TimerTask {
public void run() {
if (thread.isAlive()) {
statusbar.addProcessIndicator(null);
} else {
timer.cancel();
}
}
}
Lastly, this is how I start the thread in the gui class:
public void startThread(Runnable runnable, String startMsg) {
// Generate certificate
Thread thread = new Thread(runnable);
threadlistener.setThread(thread);
// keep gui responsive
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
// Print status of thread process
statusbar.addMessage("+++++++ " + startMsg + " +++++++\n");
java.util.Timer timer = new java.util.Timer();
timer.scheduleAtFixedRate((new
TimerTaskUpdateStatusBar(timer, thread, this, statusbar)), 0, 500);
}