Paul
Paul

Reputation: 6176

why calling repaint in this code?

if you add a jpanel instance to the content pane, the paintComponent method is called, right?

content_pane.add (fDrawingPanel);

so why would you call "repaint" at the first line in the run() method? (it says "to paint the loading message, but it should already be painted, because paintComponent was called before, and once fShow is true, we don't set it back to false, so this code is, i think, supposed to be called once ) :

public class MediaTrackApplet extends JApplet
                       implements Runnable
{
  // Need a reference to the panel for the
  // thread loop.
  DrawingPanel fDrawingPanel;

  // Parameters to track the image
  MediaTracker fTracker;
  Image fImg;
  int fImageNum = 0;
  boolean fShow = false;
  String fMessage ="Loading...";

  /** Use a MediaTracker to load an image.**/
  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of DrawingPanel
    fDrawingPanel = new DrawingPanel (this);

    // Add the DrawingPanel to the contentPane.
    content_pane.add (fDrawingPanel);

    // Get image and monitor its loading.
    fImg = getImage (getCodeBase (), "m20.gif.jpg" );
    fTracker = new MediaTracker (this);

    // Pass the image reference and an ID number.
    fTracker.addImage (fImg, fImageNum);
  } // init

  /** If the image not yet loaded, run the thread
    * so the run() will monitor the image loading.
   **/
  public void start () {
    if (!fTracker.checkID (fImageNum) ) {
        Thread thread = new Thread (this);
        thread.start ();
    } else
        // Unloading/reloading web page can will leave
        // checkID true but fShow will be false.
        fShow = true;
  } // start

  /** Use a thread to wait for the image to load 
    * before painting it.
   **/
  public void run ()  {
    // Paint the loading message
    repaint ();
    // The wait for the image to finish loading
    try {
      fTracker.waitForID (fImageNum );
    } catch (InterruptedException e) {}

    // Check if there was a loading error
    if (fTracker.isErrorID (fImageNum ))
        fMessage= "Error";
    else
        fShow = true;
    // Repaint with the image now if it loaded OK
    repaint ();
  } // run

}// class MediaTrackApplet


/** This JPanel subclass draws an image on the panel if
  * the image is loaded. Otherwise, it draws a text message.
 **/
class DrawingPanel extends JPanel {
  MediaTrackApplet parent = null;

  DrawingPanel (MediaTrackApplet parent) {
    this.parent = parent;
  }// ctor

  public void paintComponent (Graphics g) {
    super.paintComponent (g);

    // Add your drawing instructions here
    if (parent.fShow)
        g.drawImage (parent.fImg,10,10,this);
    else
        g.drawString (parent.fMessage, 10,10);
  } // paintComponent

} // class DrawingPanel

Thanks

Upvotes: 2

Views: 133

Answers (1)

trashgod
trashgod

Reputation: 205835

Are you referring to the EDT?

Yes. This venerable, but superannuated, example hails from an era that predates our modern understanding that Swing GUI objects should be constructed and manipulated only on the event dispatch thread. The initial invocation of repaint() has the effect of posting a new Runnable on the EventQueue, while allowing the background thread to finish loading images in anticipation of the subsequent repaint(). See also Memory Consistency Properties and this related example.

Upvotes: 2

Related Questions