线程写入状态更新鼠标下任何组件的文本

时间:2017-08-07 01:58:24

标签: java multithreading swing

这是一个相当奇怪的问题。我正在使用Swing按钮启动扫描文件列表。因为我希望它在状态栏上显示更新,我使用的是Thread。由于Swing在按钮的代码完成之前不会让任何东西抽出,我也使用Tread来允许我更改“开始扫描”#39;按钮到'停止扫描'按钮。

问题在于,如果将等待光标放在任何其他组件上,则在扫描期间,状态消息也会被写入这些组件,例如按钮(请参阅代码下方的示例按钮),复选框等;这搞砸了界面。这是一个主要的错误还是做我正在做的事情不是一个好主意?有办法吗?

      private void jButton47ActionPerformed(java.awt.event.ActionEvent evt)                                          
      {                                              
          // Scan folders button.
          //
          this.getFrame().setCursor(new Cursor(Cursor.WAIT_CURSOR));

          // If button is in stop mode then...
          if (collection.isScanContinue())
          {
              collection.setScanContinue(false);
              jButton47.setText(" Scan Folders For Files ");
              jButton47.setBackground(view.getDefaultButtonCol());
          }
          else // in scan mode...
          {

              Thread t = new Thread(new Runnable()
              {
                  @Override
                  public void run()
                  {
                      // Setup the stop scan process button (changes the scan button to a stop button).
                      //
                      collection.setScanContinue(true);
                      jButton47.setText(" Stop Scanning Folders  ");

                        jButton47.setBackground(collection.getPrefs().getDeleteCol());

                      collection.scanSourceAndTargetFolders();

                      if(collection.isScanContinue())
                      {
                          // do scan
                      }

                      // Reset the stop scan button and flag.
                      //
                      collection.setScanContinue(false);
                      jButton47.setText(" Scan Folders For Files ");
                      jButton47.setToolTipText("Scans Source and, if required, Target folders.");
                      jButton47.setBackground(view.getDefaultButtonCol());

                      view.getFrame().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                  }            
              });
              t.start();            
          }

      } 

如果我重新验证主框架,它会很好地清理,但在文件扫描期间看起来很糟糕。

enter image description here

1 个答案:

答案 0 :(得分:1)

任何涉及swing的操作,例如更改按钮文本等,都应该使用SwingUtilities.invokeLater在事件派发线程上执行。否则,你会遇到像你在这里看到的并发问题。有关事件线程如何工作的更多详细信息,请参阅此问题:Java Event-Dispatching Thread explanation

此外,为了完成这样的后台任务,Swing提供了一个名为SwingWorker的方便实用程序:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html