-
Bug
-
Resolution: Fixed
-
P2
-
1.0
-
1.0.2
-
x86, sparc
-
solaris_2.4, windows_nt
-
Verified
Joel Spolsky <###@###.###>
Win32 Only: Frame.location() always reports 0,0 as its location. It should report it's
location with respect to the entire desktop that it is in. Solaris works okay.
Steps to reproduce
Compile and run the attached code
Press <Get Parent>
// Note: the location should be with respect to the desktop.
/* parent test */
import java.awt.*;
import java.applet.Applet;
public class ParentTest extends Applet
{
private TextArea textArea;
private Frame parentFrame;
private final String GET_PARENT = "Get Parent";
public void init()
{
setLayout( new BorderLayout() );
// creat test panel
Panel tempPanel = new Panel();
tempPanel.add( new Button(GET_PARENT) );
add( "North", tempPanel );
add( "Center", textArea = new TextArea() );
resize(400, 400);
}
public boolean action(Event evt, Object obj)
{
// local variables
Container tempContainer;
if (evt.target instanceof Button)
{
tempContainer = getParent();
while (! (tempContainer instanceof Frame) )
{
textArea.appendText( tempContainer.toString() + "\\n");
tempContainer = tempContainer.getParent();
textArea.appendText( "Location: " +
tempContainer.location().toString() +
"\\n" );
}
parentFrame = (Frame) tempContainer;
textArea.appendText( "Parent: " + parentFrame.toString() + "\\n");
textArea.appendText( "Location: " +
parentFrame.location().toString() +
"\\n" );
return true;
}
else
return super.action(evt, obj);
}
public static void main(String argv[])
{
AppletFrame.startApplet("ParentTest", "Parent Test", argv);
}
}
/* Generic Applet to Application Frame
* @(#)AppletFrame.java 1.4 12/02/95 15:28:07
* @author Kevin A. Smith
*/
import java.awt.Frame;
import java.awt.Event;
import java.awt.Dimension;
import java.applet.Applet;
// Applet to Application Frame window
class AppletFrame extends Frame
{
public static void startApplet(String className,
String title,
String args[])
{
// local variables
Applet a;
Dimension appletSize;
try
{
// create an instance of your applet class
a = (Applet) Class.forName(className).newInstance();
}
catch (ClassNotFoundException e) { return; }
catch (InstantiationException e) { return; }
catch (IllegalAccessException e) { return; }
// initialize the applet
a.init();
a.start();
// create new application frame window
AppletFrame f = new AppletFrame(title);
// add applet to frame window
f.add("Center", a);
// resize frame window to fit applet
// assumes that the applet sets its own size
// otherwise, you should set a specific size here.
appletSize = a.size();
f.pack();
f.resize(appletSize);
// show the window
f.show();
} // end startApplet()
// constructor needed to pass window title to class Frame
public AppletFrame(String name)
{
// call java.awt.Frame(String) constructor
super(name);
}
// needed to allow window close
public boolean handleEvent(Event e)
{
// Window Destroy event
if (e.id == Event.WINDOW_DESTROY)
{
// exit the program
System.exit(0);
return true;
}
// it's good form to let the super class look at any
// unhandled events
return super.handleEvent(e);
} // end handleEvent()
} // end class AppletFrame
The description field as copied from bug report 1238427 follows:
From customer: Frames (and probably Windows, I don't
remember) DO NOT update their location() when they are moved. They
*DO* update their location when they are restored from a maximize.
So, for example I create a frame, it appears at desktop coord 0,0. I
move it. It still says it is at 0,0. I move it again, still says
0,0. I maximize the window, now it says something like -4,2 (which I
presume is right). I restore the window and poof! it now has the
right coordinates reflecting the move (100,82) or whatever...
Also, if you manually resize the Frame(Window) it also updates its
location. If you resize() the frame/window, though, it jumps to
desktop location 0,0, no matter where it was. Why? Because resize
is really calling reshape (location().x,location().y,int newWidth,int
newHeight).
______
I'm adding this customer description because it includes good test code and a more detailed investigation of the problem.
Category: AWT
Priority: CRITICAL! (Low/Medium/High/Critical)
JDK version: JDK-1_0-win32-x86.exe
Platforms: Windows 95 [Version 4.00.950]
Windows NT version 3.51
Synopsis
--------
The locations of AWT components are reported incorrectly on Windows.
Description
-----------
This bug occurs on Windows95 and WindowsNT.
The "location" method of the Component class returns the location of
a component relative to its parent. On Windows this location is not
always correct.
I did some experimentation to figure out what was going on. The
"reshape" method takes an x, y, width, and height. I subclassed a
component and overrode reshape to keep track of the current location
of the component. I discovered that the x and y values reported by
the "location" method do not always match the x and y values given in
the most recent call to "reshape"!
Test Case
---------
- Compile and run location.java:
javac location.java
java location
- Resize the window several times.
On Motif, you get the correct output for the x and y values:
LOCATIONS
x=5 y=25 w=274 h=242
x=10 y=10 w=254 h=222
x=10 y=10 w=234 h=202
x=10 y=10 w=214 h=182
x=10 y=10 w=194 h=162
x=10 y=10 w=174 h=142
x=10 y=10 w=154 h=122
x=10 y=10 w=134 h=102
x=10 y=10 w=114 h=82
x=10 y=10 w=94 h=62
x=10 y=10 w=74 h=42
However, on Windows, you get something like this:
LOCATIONS
x=4 y=23 w=268 h=244
x=14 y=33 w=248 h=224
x=24 y=43 w=228 h=204
x=34 y=53 w=208 h=184
x=44 y=63 w=188 h=164
x=54 y=73 w=168 h=144
x=64 y=83 w=148 h=124
x=74 y=93 w=128 h=104
x=84 y=103 w=108 h=84
x=94 y=113 w=88 h=64
x=104 y=123 w=68 h=44
You may also see a mixture of correct and incorrect values:
LOCATIONS
x=4 y=23 w=217 h=392
x=10 y=10 w=197 h=372
x=10 y=10 w=177 h=352
x=10 y=10 w=157 h=332
x=10 y=10 w=137 h=312
x=10 y=10 w=117 h=292
x=64 y=83 w=97 h=272
x=74 y=93 w=77 h=252
x=84 y=103 w=57 h=232
x=10 y=10 w=37 h=212
x=10 y=10 w=17 h=192
Normally, I get a lot more incorrect locations than correct locations.
However, when I redirect the output of the test program to a file, I
get more correct positions than incorrect positions. This indicates a
race condition of some sort.
Workaround
----------
There isn't a complete workaround.
I modified GridBagLayout to keep track of the x and y value of the
component inside the layout constraints. These x and y values are always
correct, since they are the last values passed to "reshape".
However, this workaround is incomplete since the event translation
routines use the location of the component. Therefore, the events
still do not get translated properly using this workaround.
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: location.java
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 106
import java.awt.*;
class BorderPanel extends Panel {
private static final int borderWidth = 10;
public Dimension minimumSize() {
Dimension d;
if (countComponents() > 0) {
Component comp = getComponent(0);
d = comp.minimumSize();
}
else {
d = new Dimension(0, 0);
}
d.width += 2*borderWidth;
d.height += 2*borderWidth;
return d;
}
public Dimension preferredSize() {
return minimumSize();
}
public void layout() {
Dimension d = size();
Component components[] = getComponents();
for (int i=0; i<components.length; i++) {
if (i==0) {
components[i].reshape(borderWidth, borderWidth,
d.width - 2*borderWidth,
d.height - 2*borderWidth);
}
else {
components[i].reshape(-1, -1, 0, 0);
}
}
}
public void paint(Graphics g) {
Dimension d = size();
g.drawRect(0, 0, d.width-1, d.height-1);
g.drawRect(1, 1, d.width-3, d.height-3);
}
}
public class location extends Frame {
private int validateCount;
public static void main(String argv[]) {
new location();
}
public location() {
Button button = new Button("Button");
Panel p = new BorderPanel();
createNestedPanels(button, p, 10);
add("Center", p);
show();
resize(preferredSize());
validate();
}
public void createNestedPanels(Component c, Panel parent, int num) {
if (num == 0)
parent.add(c);
else {
Panel bp = new BorderPanel();
parent.add(bp);
createNestedPanels(c, bp, num-1);
}
}
public synchronized void validate() {
boolean valid = isValid();
super.validate();
System.out.println("validate " + validateCount++);
if (!valid)
printLocations();
}
public void printLocations() {
Point p;
Dimension d;
Panel panel;
Component c = getComponent(0);
System.out.println("LOCATIONS");
while (c instanceof Panel) {
panel = (Panel)c;
p = panel.location();
d = panel.size();
System.out.println("x=" + p.x + "\\ty=" + p.y +
"\\tw=" + d.width + "\\th=" + d.height);
c = panel.getComponent(0);
}
System.out.println("");
}
}
Win32 Only: Frame.location() always reports 0,0 as its location. It should report it's
location with respect to the entire desktop that it is in. Solaris works okay.
Steps to reproduce
Compile and run the attached code
Press <Get Parent>
// Note: the location should be with respect to the desktop.
/* parent test */
import java.awt.*;
import java.applet.Applet;
public class ParentTest extends Applet
{
private TextArea textArea;
private Frame parentFrame;
private final String GET_PARENT = "Get Parent";
public void init()
{
setLayout( new BorderLayout() );
// creat test panel
Panel tempPanel = new Panel();
tempPanel.add( new Button(GET_PARENT) );
add( "North", tempPanel );
add( "Center", textArea = new TextArea() );
resize(400, 400);
}
public boolean action(Event evt, Object obj)
{
// local variables
Container tempContainer;
if (evt.target instanceof Button)
{
tempContainer = getParent();
while (! (tempContainer instanceof Frame) )
{
textArea.appendText( tempContainer.toString() + "\\n");
tempContainer = tempContainer.getParent();
textArea.appendText( "Location: " +
tempContainer.location().toString() +
"\\n" );
}
parentFrame = (Frame) tempContainer;
textArea.appendText( "Parent: " + parentFrame.toString() + "\\n");
textArea.appendText( "Location: " +
parentFrame.location().toString() +
"\\n" );
return true;
}
else
return super.action(evt, obj);
}
public static void main(String argv[])
{
AppletFrame.startApplet("ParentTest", "Parent Test", argv);
}
}
/* Generic Applet to Application Frame
* @(#)AppletFrame.java 1.4 12/02/95 15:28:07
* @author Kevin A. Smith
*/
import java.awt.Frame;
import java.awt.Event;
import java.awt.Dimension;
import java.applet.Applet;
// Applet to Application Frame window
class AppletFrame extends Frame
{
public static void startApplet(String className,
String title,
String args[])
{
// local variables
Applet a;
Dimension appletSize;
try
{
// create an instance of your applet class
a = (Applet) Class.forName(className).newInstance();
}
catch (ClassNotFoundException e) { return; }
catch (InstantiationException e) { return; }
catch (IllegalAccessException e) { return; }
// initialize the applet
a.init();
a.start();
// create new application frame window
AppletFrame f = new AppletFrame(title);
// add applet to frame window
f.add("Center", a);
// resize frame window to fit applet
// assumes that the applet sets its own size
// otherwise, you should set a specific size here.
appletSize = a.size();
f.pack();
f.resize(appletSize);
// show the window
f.show();
} // end startApplet()
// constructor needed to pass window title to class Frame
public AppletFrame(String name)
{
// call java.awt.Frame(String) constructor
super(name);
}
// needed to allow window close
public boolean handleEvent(Event e)
{
// Window Destroy event
if (e.id == Event.WINDOW_DESTROY)
{
// exit the program
System.exit(0);
return true;
}
// it's good form to let the super class look at any
// unhandled events
return super.handleEvent(e);
} // end handleEvent()
} // end class AppletFrame
The description field as copied from bug report 1238427 follows:
From customer: Frames (and probably Windows, I don't
remember) DO NOT update their location() when they are moved. They
*DO* update their location when they are restored from a maximize.
So, for example I create a frame, it appears at desktop coord 0,0. I
move it. It still says it is at 0,0. I move it again, still says
0,0. I maximize the window, now it says something like -4,2 (which I
presume is right). I restore the window and poof! it now has the
right coordinates reflecting the move (100,82) or whatever...
Also, if you manually resize the Frame(Window) it also updates its
location. If you resize() the frame/window, though, it jumps to
desktop location 0,0, no matter where it was. Why? Because resize
is really calling reshape (location().x,location().y,int newWidth,int
newHeight).
______
I'm adding this customer description because it includes good test code and a more detailed investigation of the problem.
Category: AWT
Priority: CRITICAL! (Low/Medium/High/Critical)
JDK version: JDK-1_0-win32-x86.exe
Platforms: Windows 95 [Version 4.00.950]
Windows NT version 3.51
Synopsis
--------
The locations of AWT components are reported incorrectly on Windows.
Description
-----------
This bug occurs on Windows95 and WindowsNT.
The "location" method of the Component class returns the location of
a component relative to its parent. On Windows this location is not
always correct.
I did some experimentation to figure out what was going on. The
"reshape" method takes an x, y, width, and height. I subclassed a
component and overrode reshape to keep track of the current location
of the component. I discovered that the x and y values reported by
the "location" method do not always match the x and y values given in
the most recent call to "reshape"!
Test Case
---------
- Compile and run location.java:
javac location.java
java location
- Resize the window several times.
On Motif, you get the correct output for the x and y values:
LOCATIONS
x=5 y=25 w=274 h=242
x=10 y=10 w=254 h=222
x=10 y=10 w=234 h=202
x=10 y=10 w=214 h=182
x=10 y=10 w=194 h=162
x=10 y=10 w=174 h=142
x=10 y=10 w=154 h=122
x=10 y=10 w=134 h=102
x=10 y=10 w=114 h=82
x=10 y=10 w=94 h=62
x=10 y=10 w=74 h=42
However, on Windows, you get something like this:
LOCATIONS
x=4 y=23 w=268 h=244
x=14 y=33 w=248 h=224
x=24 y=43 w=228 h=204
x=34 y=53 w=208 h=184
x=44 y=63 w=188 h=164
x=54 y=73 w=168 h=144
x=64 y=83 w=148 h=124
x=74 y=93 w=128 h=104
x=84 y=103 w=108 h=84
x=94 y=113 w=88 h=64
x=104 y=123 w=68 h=44
You may also see a mixture of correct and incorrect values:
LOCATIONS
x=4 y=23 w=217 h=392
x=10 y=10 w=197 h=372
x=10 y=10 w=177 h=352
x=10 y=10 w=157 h=332
x=10 y=10 w=137 h=312
x=10 y=10 w=117 h=292
x=64 y=83 w=97 h=272
x=74 y=93 w=77 h=252
x=84 y=103 w=57 h=232
x=10 y=10 w=37 h=212
x=10 y=10 w=17 h=192
Normally, I get a lot more incorrect locations than correct locations.
However, when I redirect the output of the test program to a file, I
get more correct positions than incorrect positions. This indicates a
race condition of some sort.
Workaround
----------
There isn't a complete workaround.
I modified GridBagLayout to keep track of the x and y value of the
component inside the layout constraints. These x and y values are always
correct, since they are the last values passed to "reshape".
However, this workaround is incomplete since the event translation
routines use the location of the component. Therefore, the events
still do not get translated properly using this workaround.
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: location.java
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 106
import java.awt.*;
class BorderPanel extends Panel {
private static final int borderWidth = 10;
public Dimension minimumSize() {
Dimension d;
if (countComponents() > 0) {
Component comp = getComponent(0);
d = comp.minimumSize();
}
else {
d = new Dimension(0, 0);
}
d.width += 2*borderWidth;
d.height += 2*borderWidth;
return d;
}
public Dimension preferredSize() {
return minimumSize();
}
public void layout() {
Dimension d = size();
Component components[] = getComponents();
for (int i=0; i<components.length; i++) {
if (i==0) {
components[i].reshape(borderWidth, borderWidth,
d.width - 2*borderWidth,
d.height - 2*borderWidth);
}
else {
components[i].reshape(-1, -1, 0, 0);
}
}
}
public void paint(Graphics g) {
Dimension d = size();
g.drawRect(0, 0, d.width-1, d.height-1);
g.drawRect(1, 1, d.width-3, d.height-3);
}
}
public class location extends Frame {
private int validateCount;
public static void main(String argv[]) {
new location();
}
public location() {
Button button = new Button("Button");
Panel p = new BorderPanel();
createNestedPanels(button, p, 10);
add("Center", p);
show();
resize(preferredSize());
validate();
}
public void createNestedPanels(Component c, Panel parent, int num) {
if (num == 0)
parent.add(c);
else {
Panel bp = new BorderPanel();
parent.add(bp);
createNestedPanels(c, bp, num-1);
}
}
public synchronized void validate() {
boolean valid = isValid();
super.validate();
System.out.println("validate " + validateCount++);
if (!valid)
printLocations();
}
public void printLocations() {
Point p;
Dimension d;
Panel panel;
Component c = getComponent(0);
System.out.println("LOCATIONS");
while (c instanceof Panel) {
panel = (Panel)c;
p = panel.location();
d = panel.size();
System.out.println("x=" + p.x + "\\ty=" + p.y +
"\\tw=" + d.width + "\\th=" + d.height);
c = panel.getComponent(0);
}
System.out.println("");
}
}
- duplicates
-
JDK-1238427 Frame.location() incorrect after moving frame.
- Closed
- relates to
-
JDK-1239229 fp.bugs 3456 Win32 locations of AWT components are reported incorrectly
- Closed