如果将jpanel实例添加到内容窗格,则会调用paintComponent方法,对吗?
content_pane.add(fDrawingPanel);
那你为什么要在run()
方法的第一行调用“重绘”? (它说“要绘制加载消息,但它应该已经绘制,因为之前调用了paintComponent
,并且一旦fShow
为真,我们就不会将其设置为false,所以这段代码我认为应该被称为一次):
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
由于
答案 0 :(得分:2)
您指的是EDT吗?
是。这个令人尊敬但又有退休金的例子来自于一个早于我们现代理解的时代,即在event dispatch thread上只应构建和操纵Swing GUI对象 。 repaint()
的初始调用具有在Runnable
上发布新EventQueue
的效果,同时允许后台线程在预期后续repaint()
时完成加载图像。另请参阅Memory Consistency Properties以及此相关的example。