United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6721088 Bad window size calculation after using pack()
JDK-6721088 : Bad window size calculation after using pack()

Details
Type:
Bug
Submit Date:
2008-07-01
Status:
Closed
Updated Date:
2011-05-17
Project Name:
JDK
Resolved Date:
2011-05-17
Component:
client-libs
OS:
linux
Sub-Component:
java.awt
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:
Relates:

Sub Tasks

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

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
                                     
2008-07-14
EVALUATION

The described problem is really a bug in AWT, so CR is reopened.
                                     
2009-01-19
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.
                                     
2009-01-19
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 {
                                     
2009-01-19



Hardware and Software, Engineered to Work Together