使用Thread.Sleep后,Java应用程序没有响应;

问题描述

在运行以下代码时,我目前遇到一些麻烦。如果删除此部分,问题将消失,因此整个代码的这一部分必定是问题。它运行并绘制出我想要的东西,但是几秒钟后(通过用户(毫秒)设置了maxAddedRuntime),应用程序冻结了一段时间(窗口没有响应Windows消息),并在等待大约相同的时间后重新开始绘制窗口被冻结。我做错了什么? 我正在使用SWT和画布进行绘制。谢谢您的帮助

public void drawNetwork(Canvas canvas,GC gc,Network network,Shell shlNetworkVisualizer) {        
    startTime = System.currentTimeMillis();
    endTime = startTime + maxAddedRuntime;
    this.drawNetworkAlg1(canvas,gc,network);
    int canvasHeight = canvas.getBounds().height;
    int canvasWidth = canvas.getBounds().width;
    while (System.currentTimeMillis()<endTime) {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }   
        gc.fillRectangle(0,canvasWidth,canvasHeight); //ClearCanvas basically
        for (Nodek: network.node) {
            //drawSomeStuff
        }
        for (Edge k: network.edges) {
            //alsoDrawSomeStuff
        }       
    }
}   

解决方法

SWT应用程序必须尽快返回主Display.readAndDispatch循环。因此,您不能使用带有Thread.sleep调用的循环-这只会锁定UI,直到循环结束。

相反,您可以在延迟后使用Display.timerExec来运行代码。您可以使用它来执行一个步骤(例如,仅执行一个gc.fillRectange),然后再次调用Display.timerExec来安排下一步。

public void timerExec(int milliseconds,Runnable runnable)

注意:您从绘制事件中收到的GC仅在绘制期间有效。通常,timerExec调用应该只在画布上调用redraw才能引起新的绘制事件的产生。

这是一个简单的类,它执行基本的timerExec调用和绘制:

class Progress
{
  private final Canvas canvas;
  private final long endTime;

  Progress(Canvas c)
  {
    canvas = c;

    endTime = System.currentTimeMillis() + 1_000;

    canvas.addListener(SWT.Paint,this::paint);

    canvas.getDisplay().timerExec(100,this::timer);
  }

  private void paint(Event event)
  {
    GC gc = event.gc;

    int canvasHeight = canvas.getBounds().height;
    int canvasWidth = canvas.getBounds().width;

    gc.fillRectangle(0,canvasWidth,canvasHeight);

    // TODO more painting
  }


  private void timer()
  {
    if (canvas.isDisposed()) {  // Don't continue if control closed
      return;
    }

    canvas.redraw();

    if (System.currentTimeMillis() < endTime) {
      canvas.getDisplay().timerExec(100,this::timer);
    }
  }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...