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

Clarify that GridBagLayout clones GridBagConstraints object

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.0
    • docs
    • beta
    • generic
    • generic



      Name: krT82822 Date: 12/27/99


      orig synopsis: "GridBagLayout contract clarification"

      E:\JavaDev\ODPT>java -version
      java version "1.2"
      HotSpot VM (1.0fcs, mixed mode, build E)

      It would be a useful feature to have the contract for
      GridBagLayout.addLayoutComponent() and
      GridBagLayout.setConstraints() specify that it will
      make a clone of the constraints object you pass it. Otherwise,
      in the future the JDK could go change the implementation of
      GridBagLayout so that it just keeps the constraints object you
      pass it, and then everybody's programs will stop working.

      ---------------

      follow-up email from user:

      Code from java.awt.GridBagLayout:

        /**
         * Sets the constraints for the specified component in this layout.
         * @param comp the component to be modified.
         * @param constraints the constraints to be applied.
         */
        public void setConstraints(Component comp, GridBagConstraints constraints)
      {
          comptable.put(comp, constraints.clone());
        }

      This is the Java 1.2 source but I don't believe the functionality has every
      substantially changed. As you can see, the constraints are being cloned
      before they are put into the Hashtable but the documentation says nothing
      about this. So, the question is, can I write a piece of code that puts two
      objects into a container with the same constraints object? For example,
      look at the code that is in the class documentation for GridBadLayout:

       * import java.awt.*;
       * import java.util.*;
       * import java.applet.Applet;
       *
       * public class GridBagEx1 extends Applet {
       *
       * protected void makebutton(String name,
       * GridBagLayout gridbag,
       * GridBagConstraints c) {
       * Button button = new Button(name);
       * gridbag.setConstraints(button, c);
       * add(button);
       * }
       *
       * public void init() {
       * GridBagLayout gridbag = new GridBagLayout();
       * GridBagConstraints c = new GridBagConstraints();
       *
       * setFont(new Font("Helvetica", Font.PLAIN, 14));
       * setLayout(gridbag);
       *
       * c.fill = GridBagConstraints.BOTH;
       * c.weightx = 1.0;
       * makebutton("Button1", gridbag, c);
       * makebutton("Button2", gridbag, c);
       * makebutton("Button3", gridbag, c);
       *
       * c.gridwidth = GridBagConstraints.REMAINDER; //end row
       * makebutton("Button4", gridbag, c);
       *
       * c.weightx = 0.0; //reset to the default
       * makebutton("Button5", gridbag, c); //another row
       *
       * c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row
       * makebutton("Button6", gridbag, c);
       *
       * c.gridwidth = GridBagConstraints.REMAINDER; //end row
       * makebutton("Button7", gridbag, c);
       *
       * c.gridwidth = 1; //reset to the default
       * c.gridheight = 2;
       * c.weighty = 1.0;
       * makebutton("Button8", gridbag, c);
       *
       * c.weighty = 0.0; //reset to the default
       * c.gridwidth = GridBagConstraints.REMAINDER; //end row
       * c.gridheight = 1; //reset to the default
       * makebutton("Button9", gridbag, c);
       * makebutton("Button10", gridbag, c);
       *
       * setSize(300, 100);
       * }
       *
       * public static void main(String args[]) {
       * Frame f = new Frame("GridBag Layout Example");
       * GridBagEx1 ex1 = new GridBagEx1();
       *
       * ex1.init();
       *
       * f.add("Center", ex1);
       * f.pack();
       * f.setSize(f.getPreferredSize());
       * f.show();
       * }
       * }

      Notice that in your example, you use the same constraints object for every
      button. This only works because the setConstraints() method keeps a clone
      of the constraints object you pass in. If you were to change the
      setConstraints() method to the following, your example program wouldn't work
      anymore:

        /**
         * Sets the constraints for the specified component in this layout.
         * @param comp the component to be modified.
         * @param constraints the constraints to be applied.
         */
        public void setConstraints(Component comp, GridBagConstraints constraints)
      {
          comptable.put(comp, constraints);
        }

      So, I would propose an addition to the contract for this method similar to
      the contract you have for getConstraints() where it explains that the
      constraints object will be copied so you can use & modify it again later:

        /**
         * Sets the constraints for the specified component in this layout.
         * @param comp the component to be modified.
         * @param constraints the constraints to be applied - a copy of the
      actual
         * constraint object is kept.
         */
      (Review ID: 98192)
      ======================================================================

            sharonz Sharon Zakhour (Inactive)
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: