The AWT/Swing toolkit calls addNotify to create/hook up the peer object. You can thus override the addNotify method, so that when super. addNotify returns, you know your peer is ready to go. AWT/Swing calls addNotify for you the first time the component’s setVisible( true ) or pack() method is called. You should not call addNotify directly yourself. The toolkit calls addNotify only once, even if you setVisible( true ); setVisible( false ); setVisible( true );
You piggyback your initialisation code on addNotify like this:
public void addNotify() { super.addNotify(); offScreenImage = createImage( width, height ); }If you put your Component.createImage code in the constructor, it would sometimes work and sometimes not.
What is going on here? createImage wants to create an image in the native screen format. The only thing that knows which screen and which screen device driver you are using is the peer object in the native GUI. However, the peer does not exist until super.addNotify() returns. If you write an addNotify method that calls super.addNotify, when it returns from super.addNotify, you can rest assured the peer object has been created, and it is now safe to call createImage. So you might as well just tuck you code right after the call to super.addNotify, and it will automatically be called immediately after the peer object has been created.
One disadvantage to putting initialisation code in addNotify, is that you can’t mark the instance variable that you are initialising final. Java does not know that addNotify will be called only once.
To get an understanding of how this all works, I suggest peppering your code with debugging messages saying things like constructor X started, constructor X ended, addNotify X started, addNotify X ended etc, to understand the very complex flows of control that can happen, especially when you have overridden methods.
Some rules of thumb: addNotify will not be called until after you constructor completes. It will be called as a side effect of a setVisible( true ); This gives you four places you can put initialisation code that will be executed in this guaranteed order.
I was under the delusion that addNotify might be called unpredictably at any time the underlying GUI asynchronously felt ready to display. I did not know if there would be a race between it and method calls just after the constructor. It is all happily predictable.
This inialisation technique only works if super.addNotify exists or the toolkit will never think to call your addNotify method.
Fortunately, your JPanel addNotify method will be called after the addNotify methods of all the Components in your JPanel.
/** * Invoked when a window has been opened. */ public void windowOpened ( WindowEvent e ) { // Normally no super.windowOpened call is needed. // This is pure notification. // windowOpened has no duties. getMyInfo(); }
Why is it called addNotify instead of createPeer. Perhaps the hook it creates notifies both Java and the native GUI of interesting events.
Despite its name, addNotify does not get called when the Component is added to a Container. Perhaps it did in the deep past, hence the misleading name.
![]() |
and suggestions to improve this page to Roedy Green : | ||
| Canadian Mind Products | |||
| mindprod.com IP:[65.110.21.43] | |||
| Your face IP:[38.103.63.16] | The information on this page is for non-military use only. | ||
| You are visitor number 14,256. | Military use includes use by defence contractors. | ||
| You can get a fresh copy of this page from: | or possibly from your local J: drive (Java virtual drive/Mindprod website mirror) | ||
| http://mindprod.com/jgloss/addnotify.html | J:\mindprod\jgloss\addnotify.html | ||