addNotify : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)

addNotify
Sometimes you will discover that Component initialisation code fails to work when you insert it in the constructor, e.g. Component.createImage. Some initialisation code requires the Component to be realised/displayable before it will work. Realised, sometimes called displayable, means that there exists a corresponding native peer GUI (Graphic User Interface) object created and hooked up to your Component. In other words, your Component is either already visible or all set to be displayed. It does not mean has a parent or is visible.

Unfortunately, in Applets, init is called after addNotify, but when you run your Applet as a hybrid application, init is called before addNotify.

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.

  1. in the constructor.
  2. In the caller, just after the new, but before the setVisible( true ) gets called for the overarching JFrame. The caller can use initialisation methods of the newly created Component.
  3. In the Component’s addNotify method.
  4. In the caller, after he calls setVisible( true ) for the overarching JFrame. addNotify itself should not call setVisible or you get into an endless loop.

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.

windowOpened

Another similar place to tuck late initialisation code is in the WindowListener.windowOpened method.

/**
 * 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 call it addNotify?

addNotify has nothing whatsoever to do with notifying observers.

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.

Related Issues

If you try to write a simple Applet without a layout manager, you might be tempted to write code like this:

Learning More

Oracle’s Javadoc on addNotify class : available:

This page is posted
on the web at:

http://mindprod.com/jgloss/addnotify.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\addnotify.html
logo
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.
no blog for this page
IP:[65.110.21.43]
Your face IP:[54.90.233.153]
You are visitor number