GUI swing多线程应用程序中的代码结构

时间:2012-09-27 22:36:49

标签: java multithreading swing runnable invokeandwait

我是Java和线程的新手,我在java中有以下GUI应用程序:

  1. 在一个框架中,用户点击任意位置的鼠标并显示图像。

  2. 图像出现后,实时计时器开始运行,在jLabel中自行更新 根据用户在gui上选择的值,该计时器最长可达5秒。

  3. 同时播放声音片段。如果图像和声音匹配,用户点击并停止 计时器。更新几个jLabel值以反映匹配或未命中。 如果不是,则用户处于空闲状态,并在计时器用完后等待图像/声音剪辑对改变。 如果任一用户停止计时器或计时器用完,应用程序将等待图像间时间段的预选值并转到 下一个图像/声音值。

  4. 我有以下结构:

    我打电话

    while(true)
    {
    SwingUtilities.invokeAndWait(displayTimer);
    }
    

    在我的run()方法中。

    我的Runnable

    private final Runnable displayTimer= new Runnable()
    {
    public void run()
    {
     displayElapsed(System.currentTimeMillis() - startTime);
    }
    

    };

    稍后初始化startTime并开始任务开始的参考点。

    我的displayElapsed()方法很麻烦,检查计时器是通过用户输入还是不活动来停止。如果不, 然后它更新负责计时器的jLabel。 如果是,则调用startInteraction()方法。

    startInteraction()准备新的图像和声音,分别显示和播放每一个,创建一个新的线程updater并启动它。

    我还有一个mouseListener来监听用户输入。它会在用户点击时调用updater.interrupt()

    现在,问题。我知道,挥杆是线程不安全的。行为中肯定存在小问题,因为有时候它不会回答用户 鼠标立即点击,有时会通过两个图像/声音对没有适当的等待量。标签也不会立即更新。

    一般来说,结构看起来像一团糟,我无法在逻辑上解释。

    我所知道的是我为每个displayElapsed启动一个新线程,每次有用户或空闲停止时我都会中断它。所以从技术上讲,每个线程都应该是顺序的。

    必须有一个更好的方法来做到这一点,我想看看重写这个是一个好的开始。

1 个答案:

答案 0 :(得分:2)

查看有关SwingWorker的这篇文章。程序遇到的问题是事件调度线程(用于呈现用户界面的唯一线程)被无限循环阻塞,因为runnable在EDT中同步执行。

您想要的是在另一个线程中运行您的计时器代码,并在此线程中发布定期任务以更新EDT中的标签。 SwingWorker类将帮助您完成此任务。要做到这一点,你

  1. 子类(或创建匿名)SwingWorker
  2. 实施doInBackground以使您的计时循环
  3. 在计时循环中,调用publish传递时间戳(或任何您想要放入标签的内容)
  4. 实施process更新标签
  5. 实例化工作人员并致电run