src/share/classes/javax/swing/PopupFactory.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 


  28 import java.applet.Applet;
  29 import java.awt.*;
  30 import java.awt.event.WindowAdapter;
  31 import java.awt.event.WindowEvent;
  32 import java.util.ArrayList;
  33 import java.util.HashMap;
  34 import java.util.List;
  35 import java.util.Map;
  36 import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
  37 
  38 /**
  39  * <code>PopupFactory</code>, as the name implies, is used to obtain
  40  * instances of <code>Popup</code>s. <code>Popup</code>s are used to
  41  * display a <code>Component</code> above all other <code>Component</code>s
  42  * in a particular containment hierarchy. The general contract is that
  43  * once you have obtained a <code>Popup</code> from a
  44  * <code>PopupFactory</code>, you must invoke <code>hide</code> on the
  45  * <code>Popup</code>. The typical usage is:
  46  * <pre>
  47  *   PopupFactory factory = PopupFactory.getSharedInstance();


 277         if (i != null) {
 278             Container parent;
 279             for(parent = i.getParent() ; parent != null ; parent =
 280                     parent.getParent()) {
 281                 if (parent instanceof Popup.HeavyWeightWindow) {
 282                     return true;
 283                 }
 284             }
 285         }
 286         return false;
 287     }
 288 
 289 
 290     /**
 291      * Popup implementation that uses a Window as the popup.
 292      */
 293     private static class HeavyWeightPopup extends Popup {
 294         private static final Object heavyWeightPopupCacheKey =
 295                  new StringBuffer("PopupFactory.heavyWeightPopupCache");
 296 


 297         /**
 298          * Returns either a new or recycled <code>Popup</code> containing
 299          * the specified children.
 300          */
 301         static Popup getHeavyWeightPopup(Component owner, Component contents,
 302                                          int ownerX, int ownerY) {
 303             Window window = (owner != null) ? SwingUtilities.
 304                               getWindowAncestor(owner) : null;
 305             HeavyWeightPopup popup = null;
 306 
 307             if (window != null) {
 308                 popup = getRecycledHeavyWeightPopup(window);
 309             }
 310 
 311             boolean focusPopup = false;
 312             if(contents != null && contents.isFocusable()) {
 313                 if(contents instanceof JPopupMenu) {
 314                     JPopupMenu jpm = (JPopupMenu) contents;
 315                     Component popComps[] = jpm.getComponents();
 316                     for (Component popComp : popComps) {


 431                                 popups = heavyPopupCache2.remove(w);
 432                             }
 433                             if (popups != null) {
 434                                 for (int counter = popups.size() - 1;
 435                                                    counter >= 0; counter--) {
 436                                     popups.get(counter)._dispose();
 437                                 }
 438                             }
 439                         }
 440                     });
 441                 }
 442 
 443                 if(cache.size() < MAX_CACHE_SIZE) {
 444                     cache.add(popup);
 445                 } else {
 446                     popup._dispose();
 447                 }
 448             }
 449         }
 450 







 451         //
 452         // Popup methods
 453         //
 454         public void hide() {
 455             super.hide();

 456             recycleHeavyWeightPopup(this);



 457         }
 458 
 459         /**
 460          * As we recycle the <code>Window</code>, we don't want to dispose it,
 461          * thus this method does nothing, instead use <code>_dipose</code>
 462          * which will handle the disposing.
 463          */
 464         void dispose() {
 465         }
 466 
 467         void _dispose() {
 468             super.dispose();
 469         }
 470     }
 471 
 472 
 473 
 474     /**
 475      * ContainerPopup consolidates the common code used in the light/medium
 476      * weight implementations of <code>Popup</code>.


 932             Component component = getComponent();
 933 
 934             component.setLocation(ownerX, ownerY);
 935             rootPane.getContentPane().add(contents, BorderLayout.CENTER);
 936             contents.invalidate();
 937             component.validate();
 938             pack();
 939         }
 940 
 941 
 942         // This implements SwingHeavyWeight so that repaints on it
 943         // are processed by the RepaintManager and SwingPaintEventDispatcher.
 944         @SuppressWarnings("serial") // JDK-implementation class
 945         private static class MediumWeightComponent extends Panel implements
 946                                                            SwingHeavyWeight {
 947             MediumWeightComponent() {
 948                 super(new BorderLayout());
 949             }
 950         }
 951     }










 952 }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 
  28 import sun.swing.SwingAccessor;
  29 
  30 import java.applet.Applet;
  31 import java.awt.*;
  32 import java.awt.event.WindowAdapter;
  33 import java.awt.event.WindowEvent;
  34 import java.util.ArrayList;
  35 import java.util.HashMap;
  36 import java.util.List;
  37 import java.util.Map;
  38 import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
  39 
  40 /**
  41  * <code>PopupFactory</code>, as the name implies, is used to obtain
  42  * instances of <code>Popup</code>s. <code>Popup</code>s are used to
  43  * display a <code>Component</code> above all other <code>Component</code>s
  44  * in a particular containment hierarchy. The general contract is that
  45  * once you have obtained a <code>Popup</code> from a
  46  * <code>PopupFactory</code>, you must invoke <code>hide</code> on the
  47  * <code>Popup</code>. The typical usage is:
  48  * <pre>
  49  *   PopupFactory factory = PopupFactory.getSharedInstance();


 279         if (i != null) {
 280             Container parent;
 281             for(parent = i.getParent() ; parent != null ; parent =
 282                     parent.getParent()) {
 283                 if (parent instanceof Popup.HeavyWeightWindow) {
 284                     return true;
 285                 }
 286             }
 287         }
 288         return false;
 289     }
 290 
 291 
 292     /**
 293      * Popup implementation that uses a Window as the popup.
 294      */
 295     private static class HeavyWeightPopup extends Popup {
 296         private static final Object heavyWeightPopupCacheKey =
 297                  new StringBuffer("PopupFactory.heavyWeightPopupCache");
 298 
 299         private volatile boolean isCacheEnabled = true;
 300 
 301         /**
 302          * Returns either a new or recycled <code>Popup</code> containing
 303          * the specified children.
 304          */
 305         static Popup getHeavyWeightPopup(Component owner, Component contents,
 306                                          int ownerX, int ownerY) {
 307             Window window = (owner != null) ? SwingUtilities.
 308                               getWindowAncestor(owner) : null;
 309             HeavyWeightPopup popup = null;
 310 
 311             if (window != null) {
 312                 popup = getRecycledHeavyWeightPopup(window);
 313             }
 314 
 315             boolean focusPopup = false;
 316             if(contents != null && contents.isFocusable()) {
 317                 if(contents instanceof JPopupMenu) {
 318                     JPopupMenu jpm = (JPopupMenu) contents;
 319                     Component popComps[] = jpm.getComponents();
 320                     for (Component popComp : popComps) {


 435                                 popups = heavyPopupCache2.remove(w);
 436                             }
 437                             if (popups != null) {
 438                                 for (int counter = popups.size() - 1;
 439                                                    counter >= 0; counter--) {
 440                                     popups.get(counter)._dispose();
 441                                 }
 442                             }
 443                         }
 444                     });
 445                 }
 446 
 447                 if(cache.size() < MAX_CACHE_SIZE) {
 448                     cache.add(popup);
 449                 } else {
 450                     popup._dispose();
 451                 }
 452             }
 453         }
 454 
 455         /**
 456          * Enables or disables cache for current object.
 457          */
 458         void setCacheEnabled(boolean enable) {
 459             isCacheEnabled = enable;
 460         }
 461 
 462         //
 463         // Popup methods
 464         //
 465         public void hide() {
 466             super.hide();
 467             if (isCacheEnabled) {
 468                 recycleHeavyWeightPopup(this);
 469             } else {
 470                 this._dispose();
 471             }
 472         }
 473 
 474         /**
 475          * As we recycle the <code>Window</code>, we don't want to dispose it,
 476          * thus this method does nothing, instead use <code>_dipose</code>
 477          * which will handle the disposing.
 478          */
 479         void dispose() {
 480         }
 481 
 482         void _dispose() {
 483             super.dispose();
 484         }
 485     }
 486 
 487 
 488 
 489     /**
 490      * ContainerPopup consolidates the common code used in the light/medium
 491      * weight implementations of <code>Popup</code>.


 947             Component component = getComponent();
 948 
 949             component.setLocation(ownerX, ownerY);
 950             rootPane.getContentPane().add(contents, BorderLayout.CENTER);
 951             contents.invalidate();
 952             component.validate();
 953             pack();
 954         }
 955 
 956 
 957         // This implements SwingHeavyWeight so that repaints on it
 958         // are processed by the RepaintManager and SwingPaintEventDispatcher.
 959         @SuppressWarnings("serial") // JDK-implementation class
 960         private static class MediumWeightComponent extends Panel implements
 961                                                            SwingHeavyWeight {
 962             MediumWeightComponent() {
 963                 super(new BorderLayout());
 964             }
 965         }
 966     }
 967 
 968     static {
 969         SwingAccessor.setPopupFactoryAccessor(new SwingAccessor.PopupFactoryAccessor() {
 970             public void setHeavyWeightPopupCacheEnabled(Popup popup, boolean enable) {
 971                 if (popup instanceof HeavyWeightPopup) {
 972                     ((HeavyWeightPopup)popup).setCacheEnabled(enable);
 973                 }
 974             }
 975         });
 976     }
 977 }