JDK-6211719 : Window.setLocationRelativeTo() does not work properly for multi-monitor virtual screen configs
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-12-22
  • Updated: 2011-01-19
  • Resolved: 2005-03-06
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.
JDK 6
6 b27Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Window.setLocationRelativeTo() does not work properly for virtual screen setups. This method calculates incorrect locations for a vertical virtual screen setup where the Y value of one of the screen bounds is non-zero. When comparing whether the newly calcuated Y location + window.height exceeds the max screen height, it does not take into account the Y value of the screen. On a vertical virtual screen setup, this Y value will be non-zero and location of any window is with respect to the entire virtual space. It must add the 'Y' value of the screen to the height of the screen as given in the suggested fix column.

This is noticed on Win32 as well as unix + xinerama with a virtual screen having 2 screens placed vertically. Reproducible since 1.4. (More detailed config details are given under comments)

I have attached a sample test. Execute the sample test on a vertical virtual screen setup. Move the frame to the bottom of the bottommost screen and click the button. You will see a window appearing on the primary monitor.
###@###.### 2004-12-22 13:36:27 GMT

Comments
EVALUATION According to Window.setLocationRelativeTo() specification, the bottom of the screen is treated separately. In vertical virtual screen setup there are more than one bottoms, but currently only one is taken into consideration. We should handle all of them. ###@###.### 2005-2-10 08:06:52 GMT
10-02-2005

SUGGESTED FIX Existing code: At line no: 2127 Rectangle ss = root.getGraphicsConfiguration().getBounds(); Calculate the virtual bounds and assign it to 'ss'. New Code: Rectangle ss = new Rectangle(); GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); for (int j = 0; j < gd.length; j++) { GraphicsConfiguration[] gc = gd[j].getConfigurations(); for (int i=0; i < gc.length; i++) { ss = ss.union(gc[i].getBounds()); } } I tried this fix in my local copy and this seems to work fine in single monitor, vertical as well as horizontal multimonitor virtual screen configs. ###@###.### 2004-12-22 18:26:08 GMT The fix above treats all the screens as one large virtual screen. If a window is placed a bit below the bottom of the upper screen, it will be splitted between different screens. Currently, setLocationRelativeTo() always positions the window to be entirely on one screen. So we need to handle bottoms of all screens, not only the lowest one. Below is the new fix: // Adjust for bottom edge being offscreen ! if (dy+windowBounds.height>ss.y+ss.height) { ! dy = ss.y + ss.height-windowBounds.height; if (invokerScreenLocation.x - ss.x + invokerSize.width / 2 < ss.width / 2) { dx = invokerScreenLocation.x+invokerSize.width; } else { dx = invokerScreenLocation.x-windowBounds.width; } } // Avoid being placed off the edge of the screen if (dx+windowBounds.width > ss.x + ss.width) { dx = ss.x + ss.width - windowBounds.width; } ! if (dx < ss.x) dx = ss.x; ! if (dy < ss.y) dy = ss.y; ###@###.### 2005-2-10 08:06:51 GMT
22-12-2004