【发布时间】:2012-02-02 23:47:34
【问题描述】:
如果你在内容窗格中添加一个 jpanel 实例,paintComponent 方法就会被调用,对吧?
content_pane.add (fDrawingPanel);
那么为什么要在run() 方法的第一行调用“repaint”呢? (它说“绘制加载消息,但它应该已经绘制,因为之前调用了paintComponent,并且一旦fShow 为真,我们不会将其设置回假,所以我认为这段代码是,应该被调用一次):
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
谢谢
【问题讨论】:
-
为什么不尝试评论重绘行并尝试运行它并查看结果而不是在这里提问?
-
或者,如果您使用的是 IDE,您可以在绘制代码中设置断点并在调试模式下运行它
-
自从引入
ImageIO类以来,大部分代码都变得多余了。它在加载图像时会阻塞,因此不需要MediaTracker。 -
Applet.getImage(URL)方法是异步的(不是阻塞),因此需要MediaTracker来检查图像的加载。ImageIO.read(File/URL/InputStream)确实 阻止。当方法完成时,它要么返回一个有效的、完整的图像,要么抛出一个Exception。因此ImageIO加载的图像不需要跟踪器。我相信ImageIcon有自己的媒体跟踪器,但如果您不需要ImageIcon,请不要创建一个 - 只需改用ImageIO。
标签: java swing applet repaint jcomponent