/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.openide.awt;
import javax.swing.*;
import java.awt.*;
/** A subclass of JMenu which provides workaround for pre-JDK 1.2.2 JMenu positioning problem.
* It assures, that the popup menu gets placed inside visible screen area.
* It also improves placement of popups in the case the subclass lazily changes
* the content from getPopupMenu().
*/
public class JMenuPlus extends JMenu {
static final long serialVersionUID =-7700146216422707913L;
public JMenuPlus() {
this (""); // NOI18N
}
public JMenuPlus(String label) {
super(label);
enableInputMethods(false);
getAccessibleContext().setAccessibleDescription(label);
}
/** Overriden to provide better strategy for placing the JMenu on the screen.
* @param b a boolean value -- true to make the menu visible, false to hide it
*/
public void setPopupMenuVisible(boolean b) {
boolean isVisible = isPopupMenuVisible();
if (b != isVisible) {
if ((b==true) && isShowing()) {
// The order of calls is a provision for subclassers that
// change the content of the menu during getPopupMenu()
// We compute the origin later with properly filled popup
JPopupMenu popup = getPopupMenu();
// HACK[pnejedly]: Notify all the items in the menu we're going to show
JInlineMenu.prepareItemsInContainer(popup);
// End of HACK
Point p = getPopupMenuOrigin();
popup.show(this, p.x, p.y);
} else {
getPopupMenu().setVisible(false);
}
}
}
/** Overriden to provide better strategy for placing the JMenu on the screen.
*
* @return a Point in the coordinate space of the menu instance
* which should be used as the origin of the JMenu's popup menu.
*/
protected Point getPopupMenuOrigin() {
int x = 0;
int y = 0;
JPopupMenu pm = getPopupMenu();
Rectangle screenRect = JPopupMenuUtils.getScreenRect();
Dimension s = getSize();
Dimension pmSize = pm.getSize();
int screenRight = screenRect.x + screenRect.width;
int screenBottom = screenRect.y + screenRect.height;
// For the first time the menu is popped up,
// the size has not yet been initiated
if (pmSize.width==0) {
pmSize = pm.getPreferredSize();
}
Point position = getLocationOnScreen();
Container parent = getParent();
if (parent instanceof JPopupMenu) {
// We are a submenu (pull-right)
// First determine x:
if (position.x+s.width + pmSize.width < screenRight) {
x = s.width; // Prefer placement to the right
} else {
x = 0-pmSize.width; // Otherwise place to the left
}
// Then the y:
if (position.y+pmSize.height < screenBottom) {
y = 0; // Prefer dropping down
} else {
y = s.height-pmSize.height; // Otherwise drop 'up'
}
} else {
// We are a toplevel menu (pull-down)
// First determine the x:
if (position.x+pmSize.width < screenRight) {
x = 0; // Prefer extending to right
} else {
x = s.width-pmSize.width; // Otherwise extend to left
}
// Then the y:
if (position.y+s.height+pmSize.height < screenBottom) {
y = s.height; // Prefer dropping down
} else {
y = 0-pmSize.height; // Otherwise drop 'up'
}
}
if (y < -position.y) y = -position.y;
if (x < -position.x) x = -position.x;
return new Point(x,y);
}
}