SwingWorker可能的错误

时间:2014-05-12 10:55:29

标签: java linux multithreading jlabel swingworker

在使用SwingWorker按顺序更新我的前端时,我想我可能发现了一个错误。

我创建了一个侦听连接的服务器。连接可能只在几分钟内启动,因此我创建了一个小的连接动画,在服务器等待新的传入连接时播放。

SwingWorker<T,T>用于每0.5秒用一个字符更新一个JLabel,最后会创建一个角色,从面板的一端跳到下一个,连接后,动画已删除,JLabel将使用其他文字进行更新。

这一直都很好用,但我最近意识到动画有时会冻结,但是,每次运行动画时,它都会停止并且JLabel正确更新。

然后我意识到当我在不同的工作区时,JLabel文本不会更新。
(编辑:工作区指的是在Linux中切换桌面(工作区)的能力(我在Linux Mint 15上)。请参阅:http://linux.about.com/library/gnome/blgnome2n4a.htm

我测试并重新测试:

测试A:

  1. 开始侦听连接
  2. 应用程序动画启动(由SwingWorker提供)
  3. 在当前工作区中保持app打开
  4. 客户端连接和动画正确消失
  5. Jlabel正确更新新文字。
  6. 测试B:

    1. 开始侦听连接
    2. 动画启动(由SwingWorker提供)
    3. Ctrl+Alt, (arrow key)移至不同的工作区,并将应用保留在之前的工作区中。
    4. 等到客户端连接并移回包含app的工作区。
    5. Jlabel冻结,不得更新为新文字。
    6. 这就是它变得奇怪的地方: 如果我选择一个JMenuItem,它将与动画重叠,文本的重叠部分将会然后部分更新到正确的文本。
    7. 我没有在另一个Linux发行版上测试过这个问题,但是在得到反馈后我的代码不是导致这个问题的原因时我会这样做。

      CODE:

      ConnectingAnimation将一直运行,但仅在服务器未连接时更新动画。

      public class ConnectingAnimation extends SwingWorker<Void, String> {
      
          @Override
          protected Void doInBackground() throws Exception {
              StringBuilder sb = new StringBuilder();
              while (true) {
                  while (!connected) {
                      try {
                          ...
                          //Append text to StringBuilder
                          ...
                          //publish updated text to be displayed next
                          publish(sb.toString());
                          //Sleep
                          Thread.sleep(100);
                      } catch (InterruptedException e) {
                          return null;
                      }
                  }
                  //Waits until clientConnected() is called
                  try {
                      synchronized (clientConnection) {
                          clientConnected.wait();
                      }
                  } catch (InterruptedException e) {
                      logger.logException(e);
                  }
              }
          }
      
          @Override
          protected void process(final List<String> chunks) {
              for (final String update : chunks) {
                  if (connected) {
                      connectionStatusLabel.setText("Client Connected");
                      break;
                  }
                  connectionStatusLabel.setText(update);
              }
          }
      }
      

      clientConnected()将由外部模块调用,通知动画停止

      public static void clientConnected() {
          ...
          synchronized (clientConnection) {
              connected = true;
              clientConnection.notify();
          }
      }
      

0 个答案:

没有答案