Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java-SwingWorker doens';在EDT线程中调用Thread.sleep()时,无法运行_Java_Multithreading_Swing_Swingworker - Fatal编程技术网

java-SwingWorker doens';在EDT线程中调用Thread.sleep()时,无法运行

java-SwingWorker doens';在EDT线程中调用Thread.sleep()时,无法运行,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我试图创建一个程序来解决二次方程和计算解决时间。我有一个按钮,当我点击它时,计算将开始。我的SwingWorker用于计时,它将每1秒更新一次时间。由于计算速度很快,我在JButton actionPerformed中调用Thread.sleep(),这样我就可以看到SwingWorker正在计算时间,但当我在EDT Thread中调用Thread.sleep(3000)时,SwingWorker不工作,而是在方程求解完成后等待打印出运行时间=3秒。我如何解决这个问题,使SwingWorker每

我试图创建一个程序来解决二次方程和计算解决时间。我有一个按钮,当我点击它时,计算将开始。我的SwingWorker用于计时,它将每1秒更新一次时间。由于计算速度很快,我在JButton actionPerformed中调用Thread.sleep(),这样我就可以看到SwingWorker正在计算时间,但当我在EDT Thread中调用Thread.sleep(3000)时,SwingWorker不工作,而是在方程求解完成后等待打印出运行时间=3秒。我如何解决这个问题,使SwingWorker每1秒更新一次时间,而不是只打印3秒

//SwingWorker for counting time
public class Worker extends SwingWorker<Integer, Long> {

   private JLabel label;

   public Worker(JLabel label) {
      this.label = label;
   }

   @Override
   protected Integer doInBackground() throws Exception {
      long i = System.currentTimeMillis();

      Timer SimpleTimer = new Timer(10, new ActionListener(){
         @Override
         public void actionPerformed(ActionEvent e) {

            publish(System.currentTimeMillis() - i);
         }
      });
      SimpleTimer.start();

      return  1; 
   }

    protected void process(List<Long> chunks) {

       for(long i : chunks) {
          label.setText("" + i);
       }
    }
}


//Solving quadratic function in JButton actionPerformed
private void solveActionPerformed(java.awt.event.ActionEvent evt) {                                      

    int a, b, c;
    double x1, x2;
    int i = 0;
    try {
        a = Integer.parseInt(inputA.getText());
        b = Integer.parseInt(inputB.getText());
        c = Integer.parseInt(inputC.getText());
    } catch (Exception e) {
        JOptionPane.showMessageDialog(this, "Re-enter.");
        return;
    }
    Worker worker = new Worker(clock);
    worker.execute();

            try {
    Thread.sleep(3000);
    } catch (Exception e) {

    }
    double delta = b * b - 4 * a * c;

    if(delta < 0) {
        result.setText(".");
    } else if(delta == 0) {
        result.setText("x1 = x2 = " + -b / 2 * a);
    } else {
        x1 = (-b + Math.sqrt(delta)) / (2 * a);
        x2 = (-b - Math.sqrt(delta)) / (2 * a);

        result.setText("<html>x1 = " + x1 +  "<br>x2 = " + x2 + "</html>");
    }
}                                  
//计算时间的SwingWorker
公共类Worker扩展SwingWorker{
私人标签;
公共工作者(JLabel标签){
this.label=标签;
}
@凌驾
受保护的整数doInBackground()引发异常{
长i=System.currentTimeMillis();
计时器SimpleTimer=新计时器(10,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
发布(System.currentTimeMillis()-i);
}
});
SimpleTimer.start();
返回1;
}
受保护的无效进程(列表块){
用于(长i:块){
label.setText(“+i”);
}
}
}
//JButton中二次函数的求解
private void solveActionPerformed(java.awt.event.ActionEvent evt){
INTA、b、c;
双x1,x2;
int i=0;
试一试{
a=Integer.parseInt(inputA.getText());
b=Integer.parseInt(inputB.getText());
c=Integer.parseInt(inputC.getText());
}捕获(例外e){
showMessageDialog(这是“重新输入”);
回来
}
工人=新工人(时钟);
worker.execute();
试一试{
睡眠(3000);
}捕获(例外e){
}
双三角=b*b-4*a*c;
if(δ<0){
result.setText(“.”);
}else if(delta==0){
result.setText(“x1=x2=“+-b/2*a”);
}否则{
x1=(-b+数学sqrt(δ))/(2*a);
x2=(-b-数学sqrt(delta))/(2*a);
result.setText(“x1=“+x1+”
x2=“+x2+”); } }
现在我找到了一个解决方案,我将计时器和计算代码放在同一个线程类中:

public class NewThread implements Runnable {

   private JLabel label, result;
   private int a, b, c;

   public NewThread(JLabel label, int a, int b, int c, JLabel result) {
      this.label = label;
      this.a = a;
      this.b = b;
      this.c = c;
      this.result = result;
   }
   @Override
   public void run() {
      double x1, x2;  

      long i = System.currentTimeMillis();
      Timer timer = new Timer(10, new ActionListener(){
          @Override
          public void actionPerformed(ActionEvent e) {
             label.setText("Thoi gian tinh toan: " + (Math.round(System.currentTimeMillis() - i) / 1000) + " giay");
          }
      });

      timer.start();
      try {
         Thread.sleep(3000);
      } catch (Exception e) {

   }

    double delta = b * b - 4 * a * c;

    if(delta < 0) {
        result.setText("Phuong trinh vo nghiem.");
    } else if(delta == 0) {
        result.setText("Phuong trinh co nghiem kep x1 = x2 = " + -b / 2 * a);
    } else {
        x1 = (-b + Math.sqrt(delta)) / (2 * a);
        x2 = (-b - Math.sqrt(delta)) / (2 * a);

        result.setText("<html>Phuong co 2 nghiem.<br>x1 = " + x1 +  "<br>x2 = " + x2 + "</html>");
    }

    timer.stop();

}
public类NewThread实现可运行{
专用JLabel标签、结果;
私人int a、b、c;
公共新线程(JLabel标签、int a、int b、int c、JLabel结果){
this.label=标签;
这个a=a;
这个.b=b;
这个.c=c;
this.result=结果;
}
@凌驾
公开募捐{
双x1,x2;
长i=System.currentTimeMillis();
计时器计时器=新计时器(10,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
label.setText(“Thoi gian tinh toan:”+(Math.round(System.currentTimeMillis()-i)/1000)+“giay”);
}
});
timer.start();
试一试{
睡眠(3000);
}捕获(例外e){
}
双三角=b*b-4*a*c;
if(δ<0){
结果.setText(“Phuong trinh vo nghiem”);
}else if(delta==0){
结果.setText(“Phuong trinh co nghiem kep x1=x2=“+-b/2*a”);
}否则{
x1=(-b+数学sqrt(δ))/(2*a);
x2=(-b-数学sqrt(delta))/(2*a);
result.setText(“Phuong co 2 nghiem.
x1=“+x1+”
x2=“+x2+”); } timer.stop(); }
我的SwingWorker用于计时,它将每1秒更新一次时间

如果此工作人员的唯一责任是使用经过的时间更新标签,那么a是更好的选择。让SwingWorker
doInBackground()
实现执行繁重的计算,最后,
done()
实现可能会停止计时器并显示最终结果

不要在EDT中调用
Thread.sleep()
,因为它将冻结整个GUI事件处理,并且您可能只会看到最终结果,而不会看到预期的定期更新

使现代化 仅添加一个简单的代码段作为开始:

public void startCalculation() {

    Timer timer = new Timer(1000, new ActionListener() {

        AtomicInteger elapsedSeconds = new AtomicInteger();

        @Override
        public void actionPerformed(ActionEvent evt) {
            label.setText(String.format("Elapsed time: %d seconds", elapsedSeconds.incrementAndGet()));
       }
    });

    SwingWorker<Integer, Void> worker = new SwingWorker<Integer, Void>() {

        @Override
        protected Integer doInBackground() throws Exception {
            // do heavy stuff
            Thread.sleep(3000); // it is safe to "sleep" here because it's not executed in the EDT
            return 1;
        }

        @Override
        protected void done() {
            timer.stop();
            // update the GUI with the results here if it's required
        }
    };

    timer.start();
    worker.execute();
}
public void startCalculation(){
计时器计时器=新计时器(1000,新ActionListener(){
AtomicInteger elapsedSeconds=新的AtomicInteger();
@凌驾
已执行的公共无效操作(操作事件evt){
label.setText(String.format(“运行时间:%d秒”,elapsedSeconds.incrementAndGet());
}
});
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的整数doInBackground()引发异常{
//做重活
Thread.sleep(3000);//在这里“sleep”是安全的,因为它不是在EDT中执行的
返回1;
}
@凌驾
受保护的void done(){
timer.stop();
//如果需要,在此处使用结果更新GUI
}
};
timer.start();
worker.execute();
}

@AndrewThompson我对此很失望。如果你能帮我,然后关闭这个。如果你在EDT中使用
sleep
或任何其他耗时的操作,GUI将不会更新,因为它们都在EDT中运行(被阻止)。这正是让一个
SwingWorker
-将长时间运行的任务与GUI任务分开的原因。在其他工作中,
睡眠和计算应该在一(秒)
SwingWorker
(或只是一个简单的线程)“我对此感到失望。”我无法向你表达其他人有多在乎你。这是你需要解决的问题,或者让你感到沮丧,对其他人来说,这纯粹是学术问题。如果你想要快速的答案,请仔细倾听说明并遵循提供的建议。我决定不只是关闭