0

This is a rather odd one. I am using a Swing button to launch a scan of a list of files. Because I want it to display updates on the status bar, I am using a Thread. Since Swing won't let anything draw until the button's code has finished, I am also using a Tread to allow me to change the 'Start Scan' button to a 'Stop Scan' button.

The problem is that if the wait cursor is placed over any other components, during the scan, the status messages are also being written onto those components, such as buttons (see sample button below code), check boxes, etc; which messes up the interface. Is this a major bug or is it not a good idea to do what I am doing? Is there a way around it?

      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();            
          }

      } 

It cleans up fine if I re-validate the main frame, but it looks terrible during the file scan.

enter image description here

Robbie62
  • 221
  • 3
  • 14

1 Answers1

1

Any action involving swing, such as changing button text etc, should be performed on event dispatch thread using SwingUtilities.invokeLater. Otherwise, you'll run into concurrency issues like you see here. See this question for more details about how event thread works: Java Event-Dispatching Thread explanation

Also, for doing background tasks like this, Swing provides a handy utility called SwingWorker: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Denis Tulskiy
  • 19,012
  • 6
  • 50
  • 68