【问题标题】:Java Swing: Event-Dispatching Thread VS StopwatchJava Swing:事件调度线程 VS 秒表
【发布时间】:2011-03-22 20:53:14
【问题描述】:

我有一个基于 Swing 的带有 GUI 的 java 程序。在主类中,有一些计算被分组在一个单独的线程中。我的问题是:我需要在这些计算开始时启动秒表,在它们进行时显示计时器,在它们完成时停止。 如果我只需要计算剩下的时间,我会在单独的线程中启动秒表,在主线程中进行所有计算,当它们完成时停止秒表线程并显示计时器。 据我所知,java swing 是单线程的。这样我就可以在主摆动中重新绘制秒表的数字

【问题讨论】:

    标签: java swing


    【解决方案1】:

    最简单的方法是使用 javax.swing.Timer。让 Timer 发送定期更新事件来更新 GUI 很容易,并且可以根据需要轻松停止或重置计时器。

    【讨论】:

    • 感谢您的回答,但我需要在所有计算完成后停止计时器,这不是定期操作。有没有办法提供通知?
    • 秒表的计时器滴答声周期性动作,是的,只需在 Timer 实例上调用 stop() 即可轻松停止计时器。
    • 但我的计时器工作正常 =) 我需要从计算到计时器的通知,它们都已完成。当计时器捕获此通知时,它必须停止。计时器的 GUI 是 3 个 JLabel:jlbl_min:jlbl_seconds:jlbl_millis。所以我应该每毫秒重新绘制一个或几个标签,计时器在事件调度程序线程中工作......
    • 我读过关于 SwingWorker 的文章,这似乎是我需要的。我说的对吗?
    • 听起来你可以简单地拥有一个默认为 true 的布尔值。虽然这是真的,但请继续更新计时器标签。然后当计算完成后,将其设置为 false,计时器本质上将被“停止”。
    【解决方案2】:

    我读到SwingWorker 似乎是我需要的。

    我会支持@Ernest Friedman-Hill 的javax.swing.Timer 建议,但这个SwingWorker example 值得探索。它可以帮助您利用现有的线程代码。

    【讨论】:

      【解决方案3】:

      首先,我想对大家说声谢谢。

      使用 SwingWorker 以这样的方式解决了这个问题:我作为 SwingWorker 的孩子开发的主摆动窗口。所有的计算都在 doInBackground 方法中。当他们继续进行时,在 SwingUtilities.invokeLater 中调用了一个计时器(它在一个单独的线程中)。在 done 方法中,当所有计算完成时,计时器停止。

      【讨论】:

        【解决方案4】:

        Swing 计时器或多或少可以完成这项工作,但它可能有些不准确。事实上,这种不准确是显而易见的。例如,如果您使用 Swing Timer 制作计时器,然后观察数字的滴答声,您可能会注意到滴答声之间并不总是精确到一秒。换句话说,计时器的分辨率并不是那么好。

        摆动计时器的替代品是System.nanoTime()。我总是用这个。它有更好的分辨率。它以纳秒为单位返回当前系统时间。

        下面是一个快速示例,说明如何使用它来计算秒数:

        long previousTime = 0L;
        int seconds = 0;
        while(true)
        {
            long currTime = System.nanoTime();
        
            if((currTime - previousTime) / 1000000000L >= 1L)
            {
                previousTime = currTime;
                seconds++;
                System.out.println("Seconds: " seconds)
            }
        }
        

        【讨论】:

        • 确实,“定时器”用词不当。您不使用它们来计时;你用它们来给你定期通知。你醒来,检查时间——可能使用 System.nanoTime()——并做出相应的反应。无论如何,如果我使用 Time 来更新时钟的秒针,我会进行 250 毫秒的唤醒,其中大部分将被忽略。
        • 感谢您的回答!我自己写了一个计时器,它真的很好用。问题是它是基于 Swing 的,并且因为 Swing 是单线程的,所以我无法从计算(来自单独的线程)向该计时器提供停止通知。
        • while 循环仅用于概念验证,如果您将 while 循环的内容移动到代码中更新 GUI 界面的循环中,它应该可以很好地满足您的目的。跨度>
        猜你喜欢
        • 2015-11-06
        • 1970-01-01
        • 2014-08-11
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-01
        • 2014-01-03
        相关资源
        最近更新 更多