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

Frame.location() incorrect after moving frame.

    XMLWordPrintable

Details

    • sparc
    • solaris_2.4

    Description

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


      Attachments

        Issue Links

          Activity

            People

              egilbertsunw Eric Gilbertson (Inactive)
              tballsunw Tom Ball (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: