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

anomalous behaviour with insets and nested Panels


    • Subcomponent:
    • Resolved In Build:
    • CPU:
    • OS:
    • Verification:
      Not verified


      This bug occurs with nested Panels, in which the outer Panel has
      non-zero insets, and the inner panel has zero-insets.

      In this situation, items placed at x=0 or y=0 in the inner container
      get placed at the corresponing x=0 or y=0 on the outer container.

      I know, it's confusing ... I have a test applet to demo it very graphically.

      The applet uses a very simple subtype of Panel that allows the insets
      to be specified. It also tries to draw boxes to indicate its bounding box
      and its insets. These boxes are in a specified color.

      It also defines and uses a very simple canvas that draws its bounding
      box and diagonals in a specified color.

      At the top level of the applet, a Panel is created called "pair".
      It has an inset of 20,20,20,20 and uses a GridLayout to lay out
      2 children, one above the other. The bounding box and insets
      are drawn in magenta.

      The lower child of "pair" is a simple DemoCanvas, drawn in white.

      The upper child of "pair" is a nested Panel with an inset of 0,0,0,0
      and a nominated color of orange, although with a zero inset, you
      shouldn't be able to see any highlighting!

      The nested panel has a 2x2 grid of canvases, in red, green, yellow
      and blue.

      Now for the fun stuff. Run the demo. the red, green and blue
      boxes are not correctly nested. They overflow out of the container
      they're supposed to be in. The yellow canvas is placed correctly.

      Now try editing the test program and setting the inset argument
      to test panel to 1or any other number, in the first line of Main.init.
          Panel quad = new TestPanel(0, Color.orange);

      Run the test program again, and the red, green, and blue boxes have
      jumped by much more than one pixel ... they're now correctly nested
      in their container.

      Even more dramatic ... set that argument to the TestPanel constructor
      to a negative number. It works, and the boxes become bigger the way
      you'd expect but clipped to the container also like you'd expect.

      In short, the only problem value is zero, which is a real bummer, because
      that is the default value of a normal Panel's inset.

      Go figure!

      It has taken a while to narrow the bug down this far. Experiment shows that
      it is not GridLayout that is at fault .... I have seen the same problem with
      other LayoutManagers ... I first found this effect in a custom layout manager
      of mine, and it took a while to convince myself it was not that at fault.

      I have also tried chasing paint and reshape calls all the way down to Motif
      to no avail; I do not see anything blatantly wrong.


      import java.applet.Applet;
      import java.awt.Canvas;
      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.Graphics;
      import java.awt.GridLayout;
      import java.awt.Insets;
      import java.awt.Panel;

      public class Main extends Applet
        //----- Applet methods

        public void init() {

          Panel quad = new TestPanel(0, Color.orange);
          quad.setLayout(new GridLayout(2, 2));

          quad.add(new DemoCanvas(10, 30, Color.red));
          quad.add(new DemoCanvas(30, 20, Color.green));
          quad.add(new DemoCanvas(10, 30, Color.blue));
          quad.add(new DemoCanvas(30, 20, Color.yellow));

          Panel pair = new TestPanel(20, Color.magenta);
          pair.setLayout(new GridLayout(2, 1));
          pair.add(new DemoCanvas(100, 100, Color.white));




      class TestPanel extends Panel

        TestPanel(int border, Color c) {
          this.border = border;
          this.color = c;

        public Insets insets() {
          return new Insets(border, border, border, border);

        public void paint(Graphics g) {
          Dimension s = size();
          Insets i = insets();

          g.drawRect(0, 0, s.width - 1, s.height - 1);

          g.drawRect(i.left - 1, i.top - 1,
              s.width - i.left - i.right + 2, s.height - i.top - i.bottom + 2);

        Color color;
        int border;

      class DemoCanvas extends Canvas
        DemoCanvas(int w, int h, Color c) {
          this.c = c;
          d = new Dimension(w, h);

        public void paint(Graphics g) {
          Dimension s = size();
          g.drawLine(0, 0, s.width, s.height);
          g.drawLine(s.width, 0, 0, s.height);
          g.drawRect(0, 0, s.width-1, s.height-1);

        public Dimension minimumSize() { return d; }
        public Dimension preferredSize() { return d; }

        Color c;
        Dimension d;

      ----- test doc --------------------------------------------------
      <TITLE>Compiler test demo</TITLE>
      <param name=testsuite value=/home/jjg/javatest/tests/testsuite.html>




            • Assignee:
              sshaiosunw Sami Shaio (Inactive)
              jjg Jonathan Gibbons
            • Votes:
              0 Vote for this issue
              0 Start watching this issue


              • Created: