下面这段代码是简单模拟我遇到的问题, 
分两个线程 
线程A显示一个进度条 
线程B循环输出数字 点击“开始”以后,我要的效果是进度条在那边滚,同时循环输出,输出结束后再显示一个新框。 
而现在的现象是等输出结束后,显示新框,这时候进度条才开始滚。 
请教怎么解决这个问题
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;public class ProgressSample
{
static class BarThread extends Thread
{
private static int DELAY = 500;
JProgressBar progressBar; public BarThread(JProgressBar bar)
{
progressBar = bar;
} public void run()
{
int minimum = progressBar.getMinimum();
int maximum = progressBar.getMaximum();
Runnable runner = new Runnable()
{
public void run()
{
int value = progressBar.getValue();
progressBar.setValue(value + 1);
}
};
for (int i = minimum; i < maximum; i++)
{
try
{
SwingUtilities.invokeAndWait(runner);
// Our task for each step is to just sleep
Thread.sleep(DELAY);
} catch (InterruptedException ignoredException)
{
} catch (InvocationTargetException ignoredException)
{
}
}
}
} public static void main(String args[])
{
// Initialize
final JProgressBar aJProgressBar = new JProgressBar(0, 100);
final JButton aJButton = new JButton("Start");
ActionListener actionListener = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
aJButton.setEnabled(false);
Thread stepper = new BarThread(aJProgressBar);
stepper.start();

whileThread wt = new whileThread();
wt.start();
try
{
wt.join();
} catch (InterruptedException e1)
{
// TODO 自动生成 catch 块
e1.printStackTrace();
}
JFrame newFrame = new JFrame("&&&&&&&&&&&&&&&&&&&&&&");
newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newFrame.setLocation(500, 400);
newFrame.setSize(300, 100);
newFrame.show();
}
};
aJButton.addActionListener(actionListener);
JFrame theFrame = new JFrame("Progress Bars");
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = theFrame.getContentPane();
contentPane.add(aJProgressBar, BorderLayout.NORTH);
contentPane.add(aJButton, BorderLayout.SOUTH);
theFrame.setLocation(500, 200);
theFrame.setSize(300, 100);
theFrame.show();
}


}
class whileThread extends Thread
{
public void run()
{
int i =0;
while(i < 1000000)
{
System.out.println(i++);
}
}
}

解决方案 »

  1.   

    public final void join()
                    throws InterruptedException等待该线程终止。
    把你的wt.join()去掉就可以了
      

  2.   

    恩,楼上说的没错,问题应该是出现在jion上
      

  3.   

    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.lang.reflect.InvocationTargetException;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;

    public class ProgressSample
    {
    static class BarThread extends Thread
    {
    private static int DELAY = 200;
    public JProgressBar progressBar;

    public BarThread(JProgressBar bar)
    {
    progressBar = bar;
    }

    public void run()
    {
    int minimum = progressBar.getMinimum();
    int maximum = progressBar.getMaximum();
    Runnable runner = new Runnable()
    {
    public void run()
    {
    int value = progressBar.getValue();
    progressBar.setValue(value + 1);
    }
    };
    for (int i = minimum; i  < maximum; i++)
    {
    try
    {
    SwingUtilities.invokeAndWait(runner);
    // Our task for each step is to just sleep
    Thread.sleep(DELAY);
    } catch (InterruptedException ignoredException)
    {
    } catch (InvocationTargetException ignoredException)
    {
    } }
    }
    }

    public static void main(String args[])
    {
    // Initialize
    final JProgressBar aJProgressBar = new JProgressBar(0, 100);
    final JButton aJButton = new JButton("Start");
    final JFrame newFrame= new JFrame("&&&&&&&&&&&&&&&&&&&&&&");;
    final Thread stepper = new BarThread(aJProgressBar);;

    ActionListener actionListener = new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    aJButton.setEnabled(false);
        
    stepper.start();

    whileThread wt = new whileThread();
    wt.start();
    // try
    // {
    // //wt.join();
    // } catch (InterruptedException e1)
    // {
    // // TODO 自?生成 catch ?
    // e1.printStackTrace();
    // }

    newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    newFrame.setLocation(500, 400);
    newFrame.setSize(300, 100);

    }
    };
    aJButton.addActionListener(actionListener);
    JFrame theFrame = new JFrame("Progress Bars");
    theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = theFrame.getContentPane();
    contentPane.add(aJProgressBar, BorderLayout.NORTH);
    contentPane.add(aJButton, BorderLayout.SOUTH);
    theFrame.setLocation(500, 200);
    theFrame.setSize(300, 100);
    theFrame.show();
    try {
        Thread.sleep(((BarThread)stepper).progressBar.getMaximum()*200-((BarThread)stepper).progressBar.getMinimum()*200+1800);//控制显示newFrame
    }
    catch (Exception ex) {
    }

    newFrame.show();

    }


    }
    class whileThread extends Thread
    {
    public void run()
    {
    int i =0;
    while(i  < 1000)
    {
    try {
         Thread.sleep(25);
    }
    catch (Exception ex) {
    } System.out.println(i++);
    }
    }
    }
      

  4.   

    你可以用一个单独的线程控制最后newFrame的显示
    建议你把newFrame传给BarThread,让他在run()方法的最后位置调运newFrame.show()方法
    这样控制的最精确了如下
    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.lang.reflect.InvocationTargetException;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;

    public class ProgressSample
    {
    static class BarThread extends Thread
    {
    private static int DELAY = 200;
    public JProgressBar progressBar;
    public JFrame com;
    public BarThread(JProgressBar bar,JFrame com)
    {
    this.com=com;
    progressBar = bar;
    }

    public void run()
    {
    int minimum = progressBar.getMinimum();
    int maximum = progressBar.getMaximum();
    Runnable runner = new Runnable()
    {
    public void run()
    {
    int value = progressBar.getValue();
    progressBar.setValue(value + 1);
    }
    };
    for (int i = minimum; i  < maximum; i++)
    {
    try
    {
    SwingUtilities.invokeAndWait(runner);
    // Our task for each step is to just sleep
    Thread.sleep(DELAY);
    } catch (InterruptedException ignoredException)
    {
    } catch (InvocationTargetException ignoredException)
    {
    } }     com.show();
    }
    }

    public static void main(String args[])
    {
    // Initialize
    final JProgressBar aJProgressBar = new JProgressBar(0, 100);
    final JButton aJButton = new JButton("Start");
    final JFrame newFrame= new JFrame("&&&&&&&&&&&&&&&&&&&&&&");;
    final Thread stepper = new BarThread(aJProgressBar,newFrame);;
    ActionListener actionListener = new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    aJButton.setEnabled(false);
        
    stepper.start();

    whileThread wt = new whileThread();
    wt.start();
    // try
    // {
    // //wt.join();
    // } catch (InterruptedException e1)
    // {
    // // TODO 自?生成 catch ?
    // e1.printStackTrace();
    // }

    newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    newFrame.setLocation(500, 400);
    newFrame.setSize(300, 100);

    }
    };
    aJButton.addActionListener(actionListener);
    JFrame theFrame = new JFrame("Progress Bars");
    theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = theFrame.getContentPane();
    contentPane.add(aJProgressBar, BorderLayout.NORTH);
    contentPane.add(aJButton, BorderLayout.SOUTH);
    theFrame.setLocation(500, 200);
    theFrame.setSize(300, 100);
    theFrame.show();
    // try {
    //    Thread.sleep(((BarThread)stepper).progressBar.getMaximum()*200-((BarThread)stepper).progressBar.getMinimum()*200+1800);//控制显示newFrame
    //}
    //catch (Exception ex) {
    //}
    //
    // newFrame.show();
    }


    }
    class whileThread extends Thread
    {
    public void run()
    {
    int i =0;
    while(i  < 1000)
    {
    try {
         Thread.sleep(25);
    }
    catch (Exception ex) {
    } System.out.println(i++);
    }
    }
    }
      

  5.   

    这个现象为什么会这么出现呢?原因是什么?
    try { 
        Thread.sleep(((BarThread)stepper).progressBar.getMaximum()*200-((BarThread)stepper).progressBar.getMinimum()*200+1800);//控制显示newFrame 

    catch (Exception ex) { 

    newFrame.show(); 

    为什么放在这里?放在actionPerformed里面为什么就不行了?
      

  6.   

    再请问:
    不用join()的话我怎么判断whileThread 子线程运行结束了?
    传变量的方式吗?
      

  7.   

    是为了能让main线程再执行完Thread.sleep()后再执行
    newFarme.shwo();
    当执行完sleep后进度条也就执行完了,此时弹出Frame就符合你的要求了
      

  8.   

    如果只是为了实现功能
    你可以在whileThead中增加一个public的标志成员变量
    在其run方法中使用它,如果执行完就设为false
    在主程序中判断这个标志就可以了