JDK-6721088 : Bad window size calculation after using pack()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2008-07-01
  • Updated: 2011-05-17
  • Resolved: 2011-05-17
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 Other
7 b48Fixed OpenJDK6Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
openjdk version "1.6.0-internal"
OpenJDK Runtime Environment (build 1.6.0-internal-langel_02_jun_2008_10_58-b00)
OpenJDK Server VM (build 10.0-b19, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux towel.yyz.redhat.com 2.6.25-14.fc9.i686 #1 SMP Thu May 1 06:28:41 EDT 2008 i686 i686 i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :

The pack() method of the Window class allow to resize the window based on the
contents preferred sizes, when using OpenJDK on the following example, the
window always have a empty area below (that does not happens of the Sun Java
binaries)

import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class TestFrame {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new FlowLayout());
        panel.add(new JButton("Testing..."));
        frame.setContentPane(panel);
        
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the test case

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Window should be framed around the center button
ACTUAL -
Window is longer than it should be. size calculated wrong

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class TestFrame {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new FlowLayout());
        panel.add(new JButton("Testing..."));
        frame.setContentPane(panel);
        
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
---------- END SOURCE ----------

Comments
EVALUATION The bug seems to be in XDecoratedPeer.reshape(WindowDimensions, int, boolean) method. When userReshape is true (that is, this is a programmatic reshape request), the following code is executed: Rectangle reqBounds = newDimensions.getBounds(); Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height); newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet()); reqBounds is always the whole window bounds including insets. newBounds is only not equal to reqBounds for constrained windows (shown by untrusted applets) because of security warning banner - not for the given test. And the third line is incorrect: indeed, if newDimensions.isClientSet is true (e.g. when pack() is called) the constructed WindowDimensions object has newBounds equal to its client bounds, which is wrong as newBounds is always a full bounds including insets. That's why it would be correct to pass 'false' instead of newDimensions.isClientSizeSet() or handle the client size separately (subtract current insets from newBounds). The second approach is listed in Suggested Fix.
19-01-2009

SUGGESTED FIX --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Jan 13 20:04:05 2009 +0100 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Mon Jan 19 13:52:20 2009 +0300 @@ -492,7 +492,14 @@ abstract class XDecoratedPeer extends XW // do nothing but accept it. Rectangle reqBounds = newDimensions.getBounds(); Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height); - newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet()); + Insets insets = newDimensions.getInsets(); + // Inherit isClientSizeSet from newDimensions + if (newDimensions.isClientSizeSet()) { + newBounds = new Rectangle(newBounds.x, newBounds.y, + newBounds.width - insets.left - insets.right, + newBounds.height - insets.top - insets.bottom); + } + newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet()); } XToolkit.awtLock(); try {
19-01-2009

EVALUATION The described problem is really a bug in AWT, so CR is reopened.
19-01-2009

EVALUATION In Windows it is impossible to make an application window smaller then a certain size, so for this case, pack() sets the smallest possible width of the window (you can't make it smaller with the mouse) closed as not a but
14-07-2008