JDK-6699851 : setMaximizedbounds not working properly on dual screen environment
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6,6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-05-09
  • Updated: 2011-03-07
  • Resolved: 2011-03-07
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 7
7 b121Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
dual screen

A DESCRIPTION OF THE PROBLEM :
I have two monitors connected to two different graphic cards.
For some reason i need to change the default behaviour of window. The second monitor has to be treated as the primary one.
(property page of the display and then check the box on the second monitor: Use this as primary monitor)

Next, i want to set the maximumBounds of a Frame I'm going to create.
I calulated the correct values, but somehow the presentation of the Frame is wrong. The width and height is more then I set as maximumBounds.

First Screen: 1600x1200 (positioned at -1600,0)
Second Screen: 1024*768 (positioned at 0,0)

setMaximumBound(new Rectangle(0,0,1600,1200))
Size of Frame is 2176*1598

Something must be caluclated wrong in the LookAndFeel
1600-1024 = 576
1600+576 = 2176

-->If i deactive the LookAndFeel everything works fine

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Frame should be 1600*1200
ACTUAL -
Frame is 2176*1598

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.JFrame;

public class TestFrame extends JFrame{
    
    public TestFrame(GraphicsConfiguration gc) {
        super(gc);
    }
    @Override
    public synchronized void setExtendedState(int state) {
        if((state & MAXIMIZED_BOTH) !=0){
            Insets insets = getToolkit().getScreenInsets(getGraphicsConfiguration());

            Rectangle bounds = getGraphicsConfiguration().getBounds();
            System.out.println("--------------");
            System.out.println(getGraphicsConfiguration());
            System.out.println(bounds);
            bounds.x = insets.left;
            bounds.y = insets.top;
            bounds.width  -= Math.abs(insets.left - insets.right);
            bounds.height -= Math.abs(insets.top  - insets.bottom);
            System.out.println(bounds);
            setMaximizedBounds(bounds);
        }
        super.setExtendedState(state);
    }
    public static void main(String args[]){
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd[] = ge.getScreenDevices();
        TestFrame.setDefaultLookAndFeelDecorated(true);

        for (int i = 0; i < gd.length; i++) {
            TestFrame frame = new TestFrame(gd[i].getDefaultConfiguration());
            Rectangle bounds = frame.getGraphicsConfiguration().getBounds();
            frame.setBounds(bounds.x+bounds.width/4, bounds.y+bounds.height/4, bounds.width/2, bounds.height / 2);
            frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    }
}

---------- END SOURCE ----------

Comments
SUGGESTED FIX http://sa.sfbay.sun.com/projects/awt_data/7/6699851/
26-11-2010

EVALUATION Seems like the problem is in AWT's handler for the WM_GETMINMAXINFO messages. Here's the quote from MSDN for MINMAXINFO structure: "For systems with multiple monitors, the ptMaxSize and ptMaxPosition members describe the maximized size and position of the window on the primary monitor, even if the window ultimately maximizes onto a secondary monitor. In that case, the window manager adjusts these values to compensate for differences between the primary monitor and the monitor that displays the window." In fact, the maximized size of the AWT window (in the AWT's test) is based on the monitor that displays the window (secondary monitor, actually). Thus, if the secondary monitor is larger than the primary one (this is what happens in the test), then the maximized size will be additionally extended by WM. To fix the problem, we need to convert the maximized size (based on the secondary monitor) to the maximized size (based on the primary monitor) so that AWT will correctly override the maximized size in multiple monitor environment.
05-10-2010

EVALUATION Same issue reported by a CAP member: We have a problem with setMaximizedBounds on 2 screens with different size. Problem: - setExtendedState ignores the screen insets by default(i.e. the windows task bar) -> Workaround would be to use setMaximizedBounds - setMaximizedBounds works well on single screen or dual screen, if both screens have the same size - if the secondary screen is wider than the primary, setMaximizedBounds and setExtendedState( Frame.MAXIMIZED_BOTH ) on the secondary screen result in a frame which is wider than the screen size allows Steps to reproduce the error: - two screens, the wider screen has the same height like the first one and is to the right of the first one - start the program, move the frame to the secondary screen, click on the button Analysis: - if we set the maximized bounds on the secondary screen to the width of of the primary screen, the frame gets the correct size( even though the size we've set was to small!) - any wider size ( the real width of the secondary for instance) result in a too wide maximized frame - any smaller size than the width of the primary screen will maximize to exactly this width in pixels on the secondary. Test program: MaximizeTest.java
26-03-2009

WORK AROUND If setMaximizedBounds is not overridden it works correctly.
13-05-2008

EVALUATION The bug is not specific to Swing apps, the same problem is reproducible with the test converted to AWT, and the frame made undecorated. I can reproduce it on 1.4.2 (didn't try earlier releases). It's not clear what's going on - the frame is positioned and resized correctly on the correct screen, but reports incorrect dimensions. The dimensions (width,height fields in Component) are set in response to WM_SIZE event from the native code. This is an AWT issue, reassigning to the AWT team.
13-05-2008