Java Swing don'中的线程;行不通
我有一些带有Java Swing don'中的线程;行不通,java,multithreading,swing,event-dispatch-thread,jprogressbar,Java,Multithreading,Swing,Event Dispatch Thread,Jprogressbar,我有一些带有for循环的简单代码。在循环的每个过程中,我必须增加JProgressBar;然而,这是行不通的。见下文: public void atualizarBarraDeProgresso(final int valorGeral, final int valorAtual) { Thread threadProgressoCarregamento = new Thread() { @Override public void run() {
for
循环的简单代码。在循环的每个过程中,我必须增加JProgressBar;然而,这是行不通的。见下文:
public void atualizarBarraDeProgresso(final int valorGeral, final int valorAtual) {
Thread threadProgressoCarregamento = new Thread() {
@Override
public void run() {
jProgressBarPersistindo.setValue(valorAtual);
}
};
threadProgressoCarregamento.start();
}
我在下面的循环中调用方法“atuanizarbaradeprogresso”:
progressBar.setMinimum(0);
progressBar.setMaximum(qtd);
for(int i = 0; i < qtd; i++) {
atualizarBarraDeProgresso(qtd, i + 1);
doSomething();
}
progressBar.setMinimum(0);
进度条设置最大值(qtd);
对于(inti=0;i
但是我的progressBar没有发生任何变化。尝试在for语句之前添加一个线程。我希望它能起作用
progressBar.setMinimum(0);
progressBar.setMaximum(qtd);
new Thread(){
@Override
public void run() {
for(int i = 0; i < qtd; i++) {
atualizarBarraDeProgresso(qtd, i + 1);
doSomething();
}
}
}.start();
progressBar.setMinimum(0);
进度条设置最大值(qtd);
新线程(){
@凌驾
公开募捐{
对于(inti=0;i
这应该可以通过实现轻松管理<代码>SwingWorkers在您需要“做某事”但不想在执行时阻塞GUI时非常有用。该类还为您提供了一个有用的API,用于在通过publish()/process()
方法执行其他工作时需要更新GUI组件时与EDT通信
下面的实现处理工作线程上的循环,以便它不会阻塞EDT(GUI线程)。对publish(Integer…
的调用作为对process(List)
的调用中继到EDT,您要在这里更新您的JProgressBar,因为与所有Swing组件一样,您应该只更新EDT上的JProgressBar
public class MySwingWorker extends SwingWorker<Void, Integer> {
private final int qtd;
private final JProgressBar progressBar;
public MySwingWorker(JProgressBar progressBar, int qtd){
this.qtd = qtd;
this.progressBar = progressBar;
}
/* This method is called off the EDT so it doesn't block the GUI. */
@Override
protected Void doInBackground() throws Exception {
for(int i = 0; i < qtd; i++) {
/* This sends the arguments to the process(List) method
* so they can be handled on the EDT. */
publish(i + 1);
/* Do your stuff. */
doSomething();
}
return null;
}
/* This method is called on the EDT in response to a
* call to publish(Integer...) */
@Override
protected void process(List<Integer> chunks) {
progressBar.setValue(chunks.get(chunks.size() - 1));
}
}
公共类MyWingWorker扩展SwingWorker{
私人最终int qtd;
私人最终JProgressBar progressBar;
公共MySwingWorker(JProgressBar progressBar,int qtd){
this.qtd=qtd;
this.progressBar=progressBar;
}
/*此方法在EDT中被取消,因此不会阻塞GUI*/
@凌驾
受保护的Void doInBackground()引发异常{
对于(inti=0;i
你可以这样开始
int qtd = ...;
progressBar.setMinimum(0);
progressBar.setMaximum(qtd);
SwingWorker<? ,?> worker = new MySwingWorker(progressBar, qtd);
worker.execute();
intqtd=。。。;
progressBar.setMinimum(0);
进度条设置最大值(qtd);
SwingWorker工人=新的MySwingWorker(progressBar,qtd);
worker.execute();
您真的需要那么多线程吗?在任何情况下,我怀疑问题在于循环本身发生在ADT上(即在“单击处理程序”中),并阻止Swing UI交互和更新,直到它完成。考虑使用A-使用这样正确可能会消除所有问题。另外,请确保只更新ADT上的Swing对象。在任意点设置值后,是否在包含的JPanel上调用repaint()?这可能是缺少的全部内容。调用repaint()方法,顺便说一句,解决方案非常糟糕。@user2246674(礼貌咳嗽)by'ADT'DYM'EDT'?对于OP,一个一般提示。不要阻止EDT(事件调度线程)-发生这种情况时,GUI将“冻结”。不要调用Thread.sleep(n)
为重复任务执行Swing计时器,或为长时间运行的任务执行SwingWorker
。有关更多详细信息,请参阅。这是对所需逻辑的有趣反转:不是确保Swing组件的修改发生在EDT内部,而是确保修改是EDT之外的唯一操作。