Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-1232273

fp.bugs 2942: Win32 only: Frame.location() always reports 0, 0

XMLWordPrintable

    • 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("");
        }
      }

            egilbertsunw Eric Gilbertson (Inactive)
            kasmithsunw Kevin Smith (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: