【问题标题】:"Reload Image 10 sec after successful loading" in Java with AWT使用 AWT 在 Java 中“成功加载后 10 秒重新加载图像”
【发布时间】:2011-03-23 23:12:47
【问题描述】:

按以下步骤加载图像一次(代码见帖子末尾):

  1. 加载 URI
  2. 使用 Toolkit 从 URI 加载图像
  3. 使用 MediaTracker 检查加载(waitForAll())
  4. 根据图像更改视口大小
  5. (repaint() 在这里尝试过,没有改变任何东西)

调整大小将“立即”完成,然后需要一两秒钟才能实际显示图像(可能是因为我的计算机速度慢)。 如果我在不让他等待一段时间的情况下放一段时间(真的),他会像疯了一样加载,可能永远不会花时间展示任何东西(在所有计算机上,而不仅仅是我的)。所以我想让他等。网络摄像头没有发生太多事情,因此每 10 秒可能是一个不错的间隔。

我的问题的两个部分是:

  1. 如何让循环以一种智能的方式等待在它自己的线程中?只需将Thread.wait(10000); 放在循环底部也会停止显示图片。

  2. 如何检查图片是否显示,而不是像 MediaTracker 那样加载

我知道我实际上不是问如何解决问题,而是问如何实施解决方案,这可能一开始就错了。对于这种情况,我也添加了上下文:我想显示来自网络摄像头的图像,我可以通过 URL 以 JPG 格式获取这些图像,该 JPG 格式将以未知的时间间隔在服务器上重写。这种与网络摄像头的连接可能是聪明的或愚蠢的,但无论如何我都无法改变它。不是我的服务器。我只是想写一个客户端来显示图片。

参考代码和大正义(在 actionPerformed() 中):

...
    // now use an URI even if Toolkit.getImage() uses URL, as
// recommended here:
// http://download.oracle.com/javase/6/docs/api/java/net/URL.html
URI adress = null;
try {
    adress = new URI("http://194.95.48.67/record/current.jpg");
} catch (URISyntaxException e1) {
    throw new Error(e1);
}
displaystate = STATE_LOADING;
repaint();
System.out.println("load image from: " + adress);
try {
    image = getToolkit().getImage(adress.toURL());
} catch (MalformedURLException e1) {
    throw new Error(e1);
}
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 0);
try {
    mt.waitForAll();
} catch (InterruptedException e) {
    // nothing
}
filename = adress.toString();
imagesize.width = image.getWidth(null);
imagesize.height = image.getHeight(null);
if (imagesize.width == -1 || imagesize.height == -1) {
    displaystate = STATE_LOADERROR;
} else {
    viewport.x = 0;
    viewport.y = 0;
    viewport.width = imagesize.width;
    viewport.height = imagesize.height;
    setSize(viewport.width, viewport.height);
    displaystate = STATE_DISPLAYING;
}

【问题讨论】:

    标签: java awt wait


    【解决方案1】:

    如果你调用Thread.sleep,当前线程同时不能做任何事情。因此,如果您从主线程执行此操作(正如我假设的那样,您质疑是否应该使用第二个线程),则 GUI 无法更新,因此无法重新绘制图像。这就是为什么如果你把 sleep 放在循环结束时它会挂起。

    第二件事是repaint 不会立即重新绘制。它只是在 AWT 事件循环中发布一个最终将被处理的事件,然后才重新绘制组件。

    最简单的方法是这样的:
    创建第二个线程来加载图像,然后存储在成员变量中。之后它调用repaint,然后休眠。
    在绘画方法中,您拍摄图像并将其绘制在屏幕上。这将发生在主 GUI 线程中,因此其他线程的睡眠不会受到伤害。

    【讨论】:

      【解决方案2】:

      我尝试回答第一个问题:

      尝试使用计时器,当计时器到期时,您可以刷新显示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-02
        • 1970-01-01
        • 2011-08-17
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        • 1970-01-01
        相关资源
        最近更新 更多