0

我试图实现自动滚动进度条。问题是,我无法阻止它开始。但是在逐步调试期间,并且仅在调试期间,它工作正常。运行期间无法停止线程,但正在调试

这是我的代码片段。任何帮助将不胜感激。

package test; 

import javax.swing.*; 

public final class MyTest{ 
private boolean isvisible = false; 
private JProgressBar progressbar = new JProgressBar(); 
/** 
* thread of automatic rolling progress-bar 
*/ 
private Thread proT = new Thread(new Runnable(){ 
    @Override 
    public void run(){ 
    isvisible = true; 
    progressbar.setVisible(true); 
    while(true){ 
     progressBar.setValue((progressBar.getValue() + 20)%100); 
     System.out.println(progressBar.getValue()); 
     try{ 
     Thread.sleep(500); 
     }catch(InterruptedException e){ 
     e.printStackTrace(); 
     } 
     if(!isvisible){ 
     progressbar.setVisible(false); 
     break; 
     } 
    } 
    } 
}); 
/** 
* constructor 
*/ 
public MyTest(){ 
    //initiate GUI 
} 
/** 
* show an automatic rolling progress-bar 
*/ 
public void showProgressBar(){ 
    proT.start(); 
} 

/** 
* stop/veil the progress-bar 
*/ 
public void veilProgressBar(){ 
    isvisible = false; 
} 
} 
+0

为了尽快获得更好的帮助,请发布[MCTaRE](http://stackoverflow.com/help/mcve)(最小完整测试和可读示例)。 –

+0

注意:GUI更新应在EDT上执行,而我们绝不应导致EDT休眠。有关更多详细信息,请参见[Swing中的并发](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 –

+0

你是如何阻止它的? –

回答

3

有问题的整体筏这里:

  1. 你从没有在美国东部时间线程进行Swing GUI更新。

  2. 您的隐形变量不是易变的,因此从一个线程创建的更改可能无法从另一个线程看到。

  3. 虽然(真)睡在一个线程通常是不好的设计。

您应该在这里使用一个SwingTimer来调度每个X来执行更新。当您需要停止更新时,只需取消SwingTimer并隐藏控件。隐藏需要从EDT完成,尽管您可能需要执行SwingUtilities.invokeLater

可能还有更多,但这就是我迄今为止所看到的。

0

AFAIK可见性变量应该是其他线程至少volatile能够注意到它已经改变了。你不做任何同步,所以价值不会得到更新。