EVALUATION
What needs to be done to enable this functionality is to widen a few methods in JPopupMenu, DefaultPopupFactory, Popup, and PopupFactory:
JPopupMenu.java
static void setPopupFactory(PopupFactory pf) {
public static void setPopupFactory(PopupFactory pf) {
=============
DefaultPopupFactory.java
class DefaultPopupFactory implements PopupFactory {
public class DefaultPopupFactory implements PopupFactory {
=============
Popup.java
interface Popup {
public interface Popup {
=============
PopupFactory.java
interface PopupFactory.java {
public interface PopupFactory.java {
jeff.dinkins@eng 2000-07-11
We have decided upon the following API to enable this:
javax.swing.Popup:
/**
* Popups are used to display a <code>Component</code> to the user, typically
* on top of all the other <code>Component</code>s in a particular containment
* hierarchy. <code>Popup</code>s have a very small life cycle. Once you
* have obtained a <code>Popup</code>, and hidden it (invoked the
* <code>hide</code> method), you should no longer
* invoke any methods on it. This allows the <code>PopupFactory</code> to cache
* <code>Popup</code>s for later use.
* <p>
* The general contract is that if you need to change the size of the
* <code>Component</code>, or location of the <code>Popup</code>, you should
* obtain a new <code>Popup</code>.
* <p>
* <code>Popup</code> does not descend from <code>Component</code>, rather
* implementations of <code>Popup</code> are responsible for creating
* and maintaining their own <code>Component</code>s to render the
* requested <code>Component</code> to the user.
* <p>
* You typically do not explicitly create an instance of <code>Popup</code>,
* instead obtain one from a <code>PopupFactory</code>.
*
* @see PopupFactory
*
* @version %I% %G%
* @since 1.4
*/
public class Popup
/**
* Creates a <code>Popup</code> for the Component <code>owner</code>
* containing the Component <code>contents</code>. <code>owner</code>
* is used to determine which <code>Window</code> the new
* <code>Popup</code> will parent the <code>Component</code> the
* <code>Popup</code> creates to.
* A null <code>owner</code> implies there is no valid parent.
* <code>x</code> and
* <code>y</code> specify the preferred initial location to place
* the <code>Popup</code> at. Based on screen size, or other paramaters,
* the <code>Popup</code> may not display at <code>x</code> and
* <code>y</code>.
*
* @param owner Component mouse coordinates are relative to, may be null
* @param contents Contents of the Popup
* @param x Initial x screen coordinate
* @param y Initial y screen coordinate
* @exception IllegalArgumentException if contents is null
* @return Popup containing Contents
*/
protected Popup(Component owner, Component contents, int x, int y);
/**
* Creates a <code>Popup</code>. This is provided for subclasses.
*/
protected Popup();
/**
* Makes the <code>Popup</code> visible. If the <code>Popup</code> is
* currently visible, this has no effect.
*/
public void show();
/**
* Hides and disposes of the <code>Popup</code>. Once a <code>Popup</code>
* has been disposed you should no longer invoke methods on it. A
* <code>dispose</code>d <code>Popup</code> may be reclaimed and later used
* based on the <code>PopupFactory</code>. As such, if you invoke methods
* on a <code>disposed</code> <code>Popup</code>, indeterminate
* behavior will result.
*/
public void hide();
}
/**
* <code>PopupFactory</code>, as the name implies, is used to obtain
* instances of <code>Popup</code>s. <code>Popup</code>s are used to
* display a <code>Component</code> above all other <code>Component</code>s
* in a particular containment hierarchy. The general contract is that
* once you have obtained a <code>Popup</code> from a
* <code>PopupFactory</code>, you must invoke <code>hide</code> on the
* <code>Popup</code>. The typical usage is:
* <pre>
* PopupFactory factory = PopupFactory.getSharedInstance();
* Popup popup = factory.getPopup(owner, contents, x, y);
* popup.show();
* ...
* popup.hide();
* </pre>
*
* @see Popup
*
* @version %I% %G%
* @since 1.4
*/
public class PopupFactory {
/**
* Sets the <code>AppContext</code> specific <code>PopupFactory</code>.
* This will throw an <code>IllegalArgumentException</code> if
* <code>factory</code> is null.
*
* @param factory Shared PopupFactory
* @exception IllegalArgumentException if <code>factory</code> is null
*/
public static void setSharedInstance(PopupFactory factory);
/**
* Returns the shared <code>PopupFactory</code> which can be used
* to obtain <code>Popup</code>s.
*
* @return Shared PopupFactory
*/
public static PopupFactory getSharedInstance();
/**
* Creates a <code>Popup</code> for the Component <code>owner</code>
* containing the Component <code>contents</code>. <code>owner</code>
* is used to determine which <code>Window</code> the new
* <code>Popup</code> will parent the <code>Component</code> the
* <code>Popup</code> creates to. A null <code>owner</code> implies there
* is no valid parent. <code>x</code> and
* <code>y</code> specify the preferred initial location to place
* the <code>Popup</code> at. Based on screen size, or other paramaters,
* the <code>Popup</code> may not display at <code>x</code> and
* <code>y</code>.
*
* @param owner Component mouse coordinates are relative to, may be null
* @param contents Contents of the Popup
* @param x Initial x screen coordinate
* @param y Initial y screen coordinate
* @exception IllegalArgumentException if contents is null
* @return Popup containing Contents
*/
public Popup getPopup(Component owner, Component contents,
int x, int y) throws IllegalArgumentException
}
And add the following to PopupMenuUI:
/**
* Returns the <code>Popup</code> that will be responsible for
* displaying the <code>JPopupMenu</code>.
*
* @param popup JPopupMenu requesting Popup
* @param x Screen x location Popup is to be shown at
* @param y Screen y location Popup is to be shown at.
* @return Popup that will show the JPopupMenu
* @since 1.4
*/
public Popup getPopup(JPopupMenu popup, int x, int y)
scott.violet@eng 2000-09-20
|