title: SwingWorker ends, PropertyChangeListener listens, but how do I get back to EDT?
body: <p>I've already browsed many threads on this topic, but nothing seems to fit my specific situation. </p>
  
  <p>I have a swing application which analyzes QR-Codes, extracts the found loginNames and makes DB calls to fetch data for that user. To make sure the capture of the QR-Codes can be canceled and my application is still accessible while capturing, I used a SwingWorker for this purpose. Everything works fine so far, I've included a PropertyChangeListener so the application knows when my SwingWorker successfully read a code. But since I don't want to have the PropertyChangeListener as a nested class within my mainClass (to keep it well structured), I've created a new class for it outside. Now I want to return to my main class from this PropertyChangeListener class to switch to the appropriate panel which displays the fetched data. I have different codes which can be read, so depending on the code I have different panels to switch to (so I can't do a static switch to the same panel over and over again). So how can I delegate the PropertyChangeListener to give the control back to my EDT ?
  I've tried using wait() and notify() to let my EDT know the SwingWorker finished. But obviously wait() blocks my EDT and the use of SwingWorker is pointless. </p>
  
  <p>I hope I could explain my problem in enough detail, and some of you have a good idea to deal with this. 
  For any code snippets please ask, I'll then add the necessary ones. But since my project is a bit more complex I'll just post what is asked for. </p>
  
  <p>Thanks in advance for any help :)</p>
  
  <p>EDIT: Here is a code excerpt to illustrate what my SwingWorker is doing.</p>
  
  <p><strong>SwingWorker class:</strong></p>
  
  <pre><code>public class CodeDetector extends SwingWorker&lt;byte[], String&gt; {
  
  String s;                     // read String
  byte[] completeCode;          // byte[] which is returned by doInBackground()
  BufferedImage resizedImg;
  IplImage img;
  JLabel labelForStream;
  JLabel result;
  FrameGrabber grabber = new VideoInputFrameGrabber();     // using JavaCV.
  
  
  public CodeDetector(JLabel labelForStream, JLabel result) {
      this.labelForStream = labelForStream;
      this.resultLabel = result;
  }
  
  @Override
  protected byte[] doInBackground() throws Exception {
      try {
          grabber.start();         // 
          while (true) {
              // End if current thread was canceled.
              if (Thread.currentThread().isInterrupted()) {
                  return null;
              }
  
              // Grab each image, save it, scan for code and display it.  
              img = grabber.grab();
              resizedImg = //  resizing image to fit labelForStream.
                              // save resizedImg to file
              // read barcode from saved file
                      if (isBadgeCode(tmp) || isDeviceCode(tmp)) {
                          s = tmp;
                      } else {
                          continue;
                      }
                      break;
                  } catch (NotFoundException e) {
                      // Code could not be encoded yet.
                  }
                  ...
  
                      // end worker after timeout
  
          // show image on window
                  if (img != null) {
                      labelForStream.setIcon(new ImageIcon(resizedImg));
                  }
              }
          }
      } catch (Exception e) { 
          System.err.println("Error: " + e.getMessage() + " - " + e.getStackTrace() + " - " +  e.getClass());
      }
      return s != null ? s.getBytes() : null;
  }
  
  @Override
  protected void done() {
      try {
          completeCode = get();
          if (completeCode != null) {
              String code = new String(completeCode);
              if (isOtherCode(code)) {
                  resultLabel.setText(code);
              } else if (isUsernameCode(code)) {
                  // Cut userName from read code (if previously verified) and set label text.
                  resultLabel.setText(verify(code, true) ? code.split(":")[0] : null);
              }
          } else {
              resultLabel.setText(null);
          }
          resultLabel.setVisible(true);
          resultLabel.updateUI();
      } catch (IOException e) {
          e.printStackTrace();
      } catch (InterruptedException e) {
          e.printStackTrace();
      } catch (ExecutionException e) {
          e.printStackTrace();
      } catch (CancellationException e) {
          return;
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  </code></pre>
  
  <p>As this SwingWorker doesn't have references to any panels, even though the done()-method is done in EDT, I need to somehow notify my mainClass that a code has been read successfully and that it can change the panl now according to the specific code. </p>
  
  <p>Hope this clears things up a bit.</p>