JDK-4245587 : JPopupMenus are obscured by windows taskbar
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0,1.3.0_02,1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_nt,windows_xp
  • CPU: generic,x86
  • Submitted: 1999-06-10
  • Updated: 2002-06-15
  • Resolved: 2002-04-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.1 hopperFixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description

Name: skT88420			Date: 06/10/99


If a JPopupMenu is invoked near the bottom of the screen so it's
large enough to extend over the task bar, the task bar covers it.
The correct behaviour is that popups are visible over the taskbar.
(Review ID: 84206) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: hopper FIXED IN: hopper INTEGRATED IN: hopper VERIFIED IN: hopper-beta
14-06-2004

WORK AROUND Name: skT88420 Date: 06/10/99 No idea other than using awt menus, which are out because of lack of mneumonics. ======================================================================
11-06-2004

SUGGESTED FIX Name: pzR10082 Date: 11/20/2001 *** /tmp/geta4937 Tue Nov 13 17:28:08 2001 --- JMenu.java Tue Nov 13 17:28:07 2001 *************** *** 18,23 **** --- 18,24 ---- import java.awt.Frame; import java.awt.Graphics; import java.awt.GraphicsConfiguration; + import java.awt.Insets; import java.awt.Point; import java.awt.Polygon; import java.awt.Rectangle; *************** *** 351,357 **** int y = 0; JPopupMenu pm = getPopupMenu(); // Figure out the sizes needed to caclulate the menu position - Dimension screenSize; Dimension s = getSize(); Dimension pmSize = pm.getSize(); // For the first time the menu is popped up, --- 352,357 ---- *************** *** 360,375 **** pmSize = pm.getPreferredSize(); } Point position = getLocationOnScreen(); GraphicsConfiguration gc = getGraphicsConfiguration(); ! if (gc == null) { ! screenSize = Toolkit.getDefaultToolkit().getScreenSize(); ! } ! else { ! Rectangle sBounds = gc.getBounds(); ! screenSize = sBounds.getSize(); ! position.x -= sBounds.x; ! position.y -= sBounds.y; } Container parent = getParent(); --- 360,377 ---- pmSize = pm.getPreferredSize(); } Point position = getLocationOnScreen(); + Toolkit toolkit = Toolkit.getDefaultToolkit(); GraphicsConfiguration gc = getGraphicsConfiguration(); ! Dimension screenSize = toolkit.getScreenSize(); ! if (gc != null) { ! // take screen insets (e.g. taskbar) into account ! Insets screenInsets = toolkit.getScreenInsets(gc); ! ! screenSize.width -= (screenInsets.left + screenInsets.right); ! screenSize.height -= (screenInsets.top + screenInsets.bottom); ! position.x -= screenInsets.left; ! position.y -= screenInsets.top; } Container parent = getParent(); ###@###.### 2001-11-20 ====================================================================== Name: azR10139 Date: 03/25/2002 ------- JPopupMenu.java ------- *** /tmp/sccs.Zla47a Mon Mar 25 19:51:50 2002 --- JPopupMenu.java Mon Mar 25 19:50:45 2002 *************** *** 300,313 **** } // Fix for Bug#4425878 ! boolean adjustPopuLocationToFitScreen(Point p) { if(popupPostionFixEnabled == false) return false; ! int scrWidth = Toolkit.getDefaultToolkit().getScreenSize().width; ! int scrHeight = Toolkit.getDefaultToolkit().getScreenSize().height; int oldX = p.x; int oldY = p.y; Dimension size; --- 300,343 ---- } // Fix for Bug#4425878 ! boolean adjustPopupLocationToFitScreen(Point p) { if(popupPostionFixEnabled == false) return false; ! Toolkit toolkit = Toolkit.getDefaultToolkit(); ! Rectangle screenBounds = new Rectangle(toolkit.getScreenSize()); ! Insets screenInsets = new Insets(0, 0, 0, 0); ! GraphicsConfiguration gc = null; ! // Try to find GraphicsConfiguration, that includes p ! GraphicsEnvironment ge = ! GraphicsEnvironment.getLocalGraphicsEnvironment(); ! GraphicsDevice[] gd = ge.getScreenDevices(); ! for(int i = 0; i < gd.length; i++) { ! if(gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) { ! GraphicsConfiguration dgc = ! gd[i].getDefaultConfiguration(); ! if(dgc.getBounds().contains(p)) { ! gc = dgc; ! break; ! } ! } ! } + if(gc == null && getInvoker() != null) { + gc = getInvoker().getGraphicsConfiguration(); + } + + if(gc != null) { + screenInsets = toolkit.getScreenInsets(gc); + screenBounds = gc.getBounds(); + } + + int scrWidth = screenBounds.width - + Math.abs(screenInsets.left+screenInsets.right); + int scrHeight = screenBounds.height - + Math.abs(screenInsets.top+screenInsets.bottom); + int oldX = p.x; int oldY = p.y; Dimension size; *************** *** 314,332 **** size = JPopupMenu.this.getPreferredSize(); ! if( (p.x + size.width) > scrWidth ) ! p.x = scrWidth - size.width; ! if( (p.y + size.height) > scrHeight) ! p.y = scrHeight - 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 < 0 ) ! p.x = 0 ; //oldX; ! if( p.y < 0 ) ! p.y = 0; //oldY; return true; --- 344,362 ---- size = JPopupMenu.this.getPreferredSize(); ! if( (p.x + size.width) > screenBounds.x + scrWidth ) ! p.x = screenBounds.x + scrWidth - size.width; ! if( (p.y + size.height) > screenBounds.y + scrHeight) ! p.y = screenBounds.y + scrHeight - 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 ; //oldX; ! if( p.y < screenBounds.y ) ! p.y = screenBounds.y; //oldY; return true; *************** *** 750,756 **** // added new Point p = new Point(desiredLocationX,desiredLocationY); ! if( adjustPopuLocationToFitScreen(p) == true ) { this.desiredLocationX = p.x; this.desiredLocationY = p.y; --- 780,786 ---- // added new Point p = new Point(desiredLocationX,desiredLocationY); ! if( adjustPopupLocationToFitScreen(p) == true ) { this.desiredLocationX = p.x; this.desiredLocationY = p.y; ======================================================================
11-06-2004

EVALUATION Name: pzR10082 Date: 11/20/2001 We should use toolkit.getScreenInsets() to calculate 'client area' of the screen. ###@###.### 2001-11-20 ====================================================================== It appears that the bug and test aren't looking at the same thing. Peter fixed the bug in JMenu so that the Popups in JMenu do not go under the Taskbar. I did the same fix to JComboBox in bug 4474813. There is no doubt that the same problem existed in JMenu and Peter fixed that problem. I misread JPopupMenu with JMenu. Perhaps he did the same. I took a look at the problem in JPopupMenu. We can't make the popups appear over the task bar since it appears that the TaskBar has a higher Z-order than the heavyweight popups. So the next best thing is to make the popup appear so that the bottom of the popup is at the top of the taskbar. The solution is to make the pp method JPopupMenu.adjustPopuLocationToFitScreen() take into account the screen insets. Also, the escalated fix for 4425878 will not be activated unless the "javax.swing.adjustPopupLocationToFit" property is true - meaning that it will not be invoked by default. I forced the adjustPopuLocationToFitScreen() to execute and added the insets and it seems to work. ------- JPopupMenu.java ------- 308,309c308,311 < int scrWidth = Toolkit.getDefaultToolkit().getScreenSize().width; < int scrHeight = Toolkit.getDefaultToolkit().getScreenSize().height; --- > Toolkit toolkit = Toolkit.getDefaultToolkit(); > > int scrWidth = toolkit.getScreenSize().width; > int scrHeight = toolkit.getScreenSize().height; 310a313,322 > if (getInvoker() != null) { > GraphicsConfiguration gc = getInvoker().getGraphicsConfiguration(); > if (gc != null) { > Insets screenInsets = toolkit.getScreenInsets(gc); > Rectangle screenBounds = gc.getBounds(); > scrWidth = screenBounds.width - (screenInsets.left + screenInsets.right); > scrHeight = screenBounds.height - (screenInsets.top + screenInsets.bottom); > } > } > java -Djavax.swing.adjustPopupLocationToFit=true -cp classes Main I think this bug should be re-opened since it hasn't been finished. Should write a comprehensive regression test to ensure that the mentioned bugs above do not regress. ###@###.### 2002-02-25 Name: azR10139 Date: 03/25/2002 The idea of suggested fix is to take into account screen insets in the JPopupMenu.adjustPopupLocation() method. Also this diff fixes typo in the method name and makes this method multimonitor configuration aware. ====================================================================== The semantics of -Djavax.swing.adjustPopupLocationToFit has changed. The default behaviour is that the adjustment calculation will *always* be made. This means that the popup menu will always appear on the desktop unobscured by the taskbar. If -Djavax.swing.adjustPopupLocationToFit=false, then the x,y passed into JPopupMenu.show() will be taken as literal. ###@###.### 2002-04-18
18-04-2002