A
anthony.jayasekera
I am trying to diagnose some problems with a WaitDialog implementation,
i.e. a dialog which is displayed whilst a long running process (LRP)
runs.
I have pared down the code to a bare minimum for debugging purposes
(this code is attached to the end of this post).
The WaitDialog simply an indeterminate progress bar (one which moves up
and down Night ider style).
The main method of this code simply launches the wait dialog and then
runs a method, doWork(), which runs the LRP in a **NEW THREAD**.
If both the dialog and the method call are launched/invoked in the
EventDispatchThread using invokeLater() the progress bar motion is
sluggish.
This does not make sense to me since the LRP running in doWork() is
launched in a new thread.
Furthermore if the code in the LRP is changed to periodically
relinquish the cpu (using Object.wait(int ms)) the problem goes away.
I cannot rationalise this behaviour since my understanding is that if
the LRP is running in a separate thread it should have no noticeable
affect on work done in other threads.
I have tried running on JRE 1.4.2, 1.5 on Win2K and WinXP.
Any ideas would be greatly appreciated.
Code follows:
import java.awt.*;
import java.util.Date;
import javax.swing.*;
public class WaitDialog extends JDialog {
JProgressBar jProgressBar1 = new JProgressBar();
public WaitDialog(Frame owner, String title) {
super(owner, title, true);
_construct();
}
private void _construct() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
jProgressBar1.setIndeterminate(true);
panel.setBorder(BorderFactory.createEtchedBorder());
panel.add(jProgressBar1, new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0,
GridBagConstraints.SOUTH,GridBagConstraints.BOTH, new Insets(0, 10, 5,
10), 140, 0));
setContentPane(panel);
}
public static void main(String args[]) {
final JFrame frame = new JFrame();
final WaitDialog wd = new WaitDialog(frame, "Waiting...");
wd.pack();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
wd.setVisible(true);
}});
if(args.length>0){
//if we go in here the progress bar moves slowly and irratically
SwingUtilities.invokeLater(new Runnable(){
public void run() {
doWork();
}});
}else{
//if we go in here the progress bar moves smoothly
doWork();
}
}
private static void doWork(){
System.out.println("Calling Thread name is
"+Thread.currentThread().getName());
Thread worker = new Thread(){
public void run() {
//run long running process in a new thread
LRP(5000);
}
};
worker.start();
}
private static void LRP(int ms) {
Date startTime = new Date();
long time = startTime.getTime();
boolean running = true;
Date latest = null;
System.out.println("Delay Thread name is
"+Thread.currentThread().getName());
while (running) {
latest = new Date();
running = ((latest.getTime() - time) < ms);
//Adding the following code fixes the problem
/*
synchronized(startTime){
try{
startTime.wait(100);
}catch(InterruptedException e){
}
}
*/
}
}
}
i.e. a dialog which is displayed whilst a long running process (LRP)
runs.
I have pared down the code to a bare minimum for debugging purposes
(this code is attached to the end of this post).
The WaitDialog simply an indeterminate progress bar (one which moves up
and down Night ider style).
The main method of this code simply launches the wait dialog and then
runs a method, doWork(), which runs the LRP in a **NEW THREAD**.
If both the dialog and the method call are launched/invoked in the
EventDispatchThread using invokeLater() the progress bar motion is
sluggish.
This does not make sense to me since the LRP running in doWork() is
launched in a new thread.
Furthermore if the code in the LRP is changed to periodically
relinquish the cpu (using Object.wait(int ms)) the problem goes away.
I cannot rationalise this behaviour since my understanding is that if
the LRP is running in a separate thread it should have no noticeable
affect on work done in other threads.
I have tried running on JRE 1.4.2, 1.5 on Win2K and WinXP.
Any ideas would be greatly appreciated.
Code follows:
import java.awt.*;
import java.util.Date;
import javax.swing.*;
public class WaitDialog extends JDialog {
JProgressBar jProgressBar1 = new JProgressBar();
public WaitDialog(Frame owner, String title) {
super(owner, title, true);
_construct();
}
private void _construct() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
jProgressBar1.setIndeterminate(true);
panel.setBorder(BorderFactory.createEtchedBorder());
panel.add(jProgressBar1, new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0,
GridBagConstraints.SOUTH,GridBagConstraints.BOTH, new Insets(0, 10, 5,
10), 140, 0));
setContentPane(panel);
}
public static void main(String args[]) {
final JFrame frame = new JFrame();
final WaitDialog wd = new WaitDialog(frame, "Waiting...");
wd.pack();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
wd.setVisible(true);
}});
if(args.length>0){
//if we go in here the progress bar moves slowly and irratically
SwingUtilities.invokeLater(new Runnable(){
public void run() {
doWork();
}});
}else{
//if we go in here the progress bar moves smoothly
doWork();
}
}
private static void doWork(){
System.out.println("Calling Thread name is
"+Thread.currentThread().getName());
Thread worker = new Thread(){
public void run() {
//run long running process in a new thread
LRP(5000);
}
};
worker.start();
}
private static void LRP(int ms) {
Date startTime = new Date();
long time = startTime.getTime();
boolean running = true;
Date latest = null;
System.out.println("Delay Thread name is
"+Thread.currentThread().getName());
while (running) {
latest = new Date();
running = ((latest.getTime() - time) < ms);
//Adding the following code fixes the problem
/*
synchronized(startTime){
try{
startTime.wait(100);
}catch(InterruptedException e){
}
}
*/
}
}
}