aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/javax/swing
diff options
context:
space:
mode:
authormlapshin <none@none>2008-05-26 17:58:09 +0400
committermlapshin <none@none>2008-05-26 17:58:09 +0400
commit05fbf2f1739327d9c5f5d191bcb17234024f6eb3 (patch)
tree79f52770074b26500fe7acf239cede0b4c5da569 /src/share/classes/javax/swing
parent92aa8c7fa398af8abfdc6878b968c07bb8a58e93 (diff)
6694823: A popup menu can be partially hidden under the task bar in applets
Summary: In applets popup menu is shifted above the task bar Reviewed-by: peterz
Diffstat (limited to 'src/share/classes/javax/swing')
-rw-r--r--src/share/classes/javax/swing/JPopupMenu.java117
-rw-r--r--src/share/classes/javax/swing/PopupFactory.java65
2 files changed, 109 insertions, 73 deletions
diff --git a/src/share/classes/javax/swing/JPopupMenu.java b/src/share/classes/javax/swing/JPopupMenu.java
index b1cdd7db6..4edf073cd 100644
--- a/src/share/classes/javax/swing/JPopupMenu.java
+++ b/src/share/classes/javax/swing/JPopupMenu.java
@@ -41,6 +41,7 @@ import javax.swing.plaf.PopupMenuUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.event.*;
+import sun.security.util.SecurityConstants;
import java.applet.Applet;
@@ -320,17 +321,67 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement {
* This adustment may be cancelled by invoking the application with
* -Djavax.swing.adjustPopupLocationToFit=false
*/
- Point adjustPopupLocationToFitScreen(int xposition, int yposition) {
- Point p = new Point(xposition, yposition);
+ Point adjustPopupLocationToFitScreen(int xPosition, int yPosition) {
+ Point popupLocation = new Point(xPosition, yPosition);
- if(popupPostionFixDisabled == true || GraphicsEnvironment.isHeadless())
- return p;
+ if(popupPostionFixDisabled == true || GraphicsEnvironment.isHeadless()) {
+ return popupLocation;
+ }
+ // Get screen bounds
+ Rectangle scrBounds;
+ GraphicsConfiguration gc = getCurrentGraphicsConfiguration(popupLocation);
Toolkit toolkit = Toolkit.getDefaultToolkit();
- Rectangle screenBounds;
+ if(gc != null) {
+ // If we have GraphicsConfiguration use it to get screen bounds
+ scrBounds = gc.getBounds();
+ } else {
+ // If we don't have GraphicsConfiguration use primary screen
+ scrBounds = new Rectangle(toolkit.getScreenSize());
+ }
+
+ // Calculate the screen size that popup should fit
+ Dimension popupSize = JPopupMenu.this.getPreferredSize();
+ int popupRightX = popupLocation.x + popupSize.width;
+ int popupBottomY = popupLocation.y + popupSize.height;
+ int scrWidth = scrBounds.width;
+ int scrHeight = scrBounds.height;
+ if (!canPopupOverlapTaskBar()) {
+ // Insets include the task bar. Take them into account.
+ Insets scrInsets = toolkit.getScreenInsets(gc);
+ scrBounds.x += scrInsets.left;
+ scrBounds.y += scrInsets.top;
+ scrWidth -= scrInsets.left + scrInsets.right;
+ scrHeight -= scrInsets.top + scrInsets.bottom;
+ }
+ int scrRightX = scrBounds.x + scrWidth;
+ int scrBottomY = scrBounds.y + scrHeight;
+
+ // Ensure that popup menu fits the screen
+ if (popupRightX > scrRightX) {
+ popupLocation.x = scrRightX - popupSize.width;
+ if( popupLocation.x < scrBounds.x ) {
+ popupLocation.x = scrBounds.x ;
+ }
+ }
+ if (popupBottomY > scrBottomY) {
+ popupLocation.y = scrBottomY - popupSize.height;
+ if( popupLocation.y < scrBounds.y ) {
+ popupLocation.y = scrBounds.y;
+ }
+ }
+
+ return popupLocation;
+ }
+
+ /**
+ * Tries to find GraphicsConfiguration
+ * that contains the mouse cursor position.
+ * Can return null.
+ */
+ private GraphicsConfiguration getCurrentGraphicsConfiguration(
+ Point popupLocation) {
GraphicsConfiguration gc = null;
- // Try to find GraphicsConfiguration, that includes mouse
- // pointer position
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gd = ge.getScreenDevices();
@@ -338,50 +389,36 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement {
if(gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
GraphicsConfiguration dgc =
gd[i].getDefaultConfiguration();
- if(dgc.getBounds().contains(p)) {
+ if(dgc.getBounds().contains(popupLocation)) {
gc = dgc;
break;
}
}
}
-
// If not found and we have invoker, ask invoker about his gc
if(gc == null && getInvoker() != null) {
gc = getInvoker().getGraphicsConfiguration();
}
+ return gc;
+ }
- if(gc != null) {
- // If we have GraphicsConfiguration use it to get
- // screen bounds
- screenBounds = gc.getBounds();
- } else {
- // If we don't have GraphicsConfiguration use primary screen
- screenBounds = new Rectangle(toolkit.getScreenSize());
+ /**
+ * Checks that there are enough security permissions
+ * to make popup "always on top", which allows to show it above the task bar.
+ */
+ static boolean canPopupOverlapTaskBar() {
+ boolean result = true;
+ try {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(
+ SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
+ }
+ } catch (SecurityException se) {
+ // There is no permission to show popups over the task bar
+ result = false;
}
-
- Dimension size;
-
- size = JPopupMenu.this.getPreferredSize();
-
- // Use long variables to prevent overflow
- long pw = (long) p.x + (long) size.width;
- long ph = (long) p.y + (long) size.height;
-
- if( pw > screenBounds.x + screenBounds.width )
- p.x = screenBounds.x + screenBounds.width - size.width;
-
- if( ph > screenBounds.y + screenBounds.height)
- p.y = screenBounds.y + screenBounds.height - size.height;
-
- /* Change is made to the desired (X,Y) values, when the
- PopupMenu is too tall OR too wide for the screen
- */
- if( p.x < screenBounds.x )
- p.x = screenBounds.x ;
- if( p.y < screenBounds.y )
- p.y = screenBounds.y;
-
- return p;
+ return result;
}
diff --git a/src/share/classes/javax/swing/PopupFactory.java b/src/share/classes/javax/swing/PopupFactory.java
index 86b737750..7a934150f 100644
--- a/src/share/classes/javax/swing/PopupFactory.java
+++ b/src/share/classes/javax/swing/PopupFactory.java
@@ -548,47 +548,46 @@ public class PopupFactory {
}
/**
- * Returns true if the Popup can fit on the screen.
+ * Returns true if popup can fit the screen and the owner's top parent.
+ * It determines can popup be lightweight or mediumweight.
*/
boolean fitsOnScreen() {
+ boolean result = false;
Component component = getComponent();
-
if (owner != null && component != null) {
- Container parent;
- int width = component.getWidth();
- int height = component.getHeight();
- for(parent = owner.getParent(); parent != null ;
- parent = parent.getParent()) {
- if (parent instanceof JFrame ||
- parent instanceof JDialog ||
- parent instanceof JWindow) {
-
- Rectangle r = parent.getBounds();
- Insets i = parent.getInsets();
- r.x += i.left;
- r.y += i.top;
- r.width -= (i.left + i.right);
- r.height -= (i.top + i.bottom);
-
- GraphicsConfiguration gc = parent.getGraphicsConfiguration();
+ Container parent = (Container) SwingUtilities.getRoot(owner);
+ int popupWidth = component.getWidth();
+ int popupHeight = component.getHeight();
+ Rectangle parentBounds = parent.getBounds();
+ if (parent instanceof JFrame ||
+ parent instanceof JDialog ||
+ parent instanceof JWindow) {
+
+ Insets i = parent.getInsets();
+ parentBounds.x += i.left;
+ parentBounds.y += i.top;
+ parentBounds.width -= i.left + i.right;
+ parentBounds.height -= i.top + i.bottom;
+
+ if (JPopupMenu.canPopupOverlapTaskBar()) {
+ GraphicsConfiguration gc =
+ parent.getGraphicsConfiguration();
Rectangle popupArea = getContainerPopupArea(gc);
- return r.intersection(popupArea).contains(x, y, width, height);
-
- } else if (parent instanceof JApplet) {
- Rectangle r = parent.getBounds();
- Point p = parent.getLocationOnScreen();
-
- r.x = p.x;
- r.y = p.y;
- return r.contains(x, y, width, height);
- } else if (parent instanceof Window ||
- parent instanceof Applet) {
- // No suitable swing component found
- break;
+ result = parentBounds.intersection(popupArea)
+ .contains(x, y, popupWidth, popupHeight);
+ } else {
+ result = parentBounds
+ .contains(x, y, popupWidth, popupHeight);
}
+ } else if (parent instanceof JApplet) {
+ Point p = parent.getLocationOnScreen();
+ parentBounds.x = p.x;
+ parentBounds.y = p.y;
+ result = parentBounds
+ .contains(x, y, popupWidth, popupHeight);
}
}
- return false;
+ return result;
}
Rectangle getContainerPopupArea(GraphicsConfiguration gc) {