Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: openfuture/util/layout/XmFormLayout.java


1   package openfuture.util.layout;
2   
3   /**
4    *  XmFormLayout.java (a Java layout manager which was
5    *  inspired by the Motif XmForm widget)
6    *  Copyright (C) 1996 Softbear Inc.  (info@softbear.com)
7    *  Latest version at http://www.softbear.com/java/xmformlm
8    *
9    *  This library is free software; you can redistribute it and/or
10   *  modify it under the terms of the GNU Library General Public
11   *  License as published by the Free Software Foundation; either
12   *  version 2 of the License, or (at your option) any later version.
13   *
14   *  This library is distributed in the hope that it will be useful,
15   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   *  Library General Public License for more details.
18   *
19   *  You should have received a copy of the GNU Library General Public
20   *  License along with this library; if not, write to the Free
21   *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22   */
23  // Configuration Management Information:
24  // -------------------------------------
25  // $Id: XmFormLayout.java,v 1.1.1.1 2001/07/08 18:29:31 wreissen Exp $
26  //
27  // Version History:
28  // ----------------
29  // $Log: XmFormLayout.java,v $
30  // Revision 1.1.1.1  2001/07/08 18:29:31  wreissen
31  // initial version registered ad SourceForge
32  //
33  // Revision 1.1  2000/09/27 15:53:24  wreissen
34  // moved to openfuture.
35  //
36  // Revision 1.1  2000/02/14 06:49:51  wreissen
37  // initial version.
38  //
39  // Revision 1.1  1999/11/15 12:44:56  zv332
40  // class copied from Jawa package
41  //
42  // Revision 1.9  1999/05/18 16:06:32  zv152
43  // - updated errorhandling: missing or invalid constraints will generate a
44  //   message but will not prevent other components from being displayed
45  //
46  // Revision 1.8  1999/05/03 12:08:08  zv152
47  // - added support to read constraints from URLs and local files (CVS copy)
48  //
49  // Revision 1.7  1999/03/19 09:24:57  zv152
50  // - repackage
51  //
52  // Revision 1.6  1998/07/24 15:28:04  s.balz
53  // - removed System.out.println from removeBlanks
54  //
55  // Revision 1.5  1998/07/24 15:24:06  s.balz
56  // - methode removeBlanks hinzugefügt, so daß Constraints nun auch
57  //   Blanks enthalten dürfen.
58  //
59  // Revision 1.4  1998/05/18 09:06:06  s.balz
60  // - patch for Supercede
61  //
62  // Revision 1.3  1997/04/24 14:02:22  balz
63  // - wow! added % handling and it seems to work!
64  //
65  // Revision 1.2  1997/04/24 13:30:20  balz
66  // - added some comments
67  //
68  //
69  /**
70   *
71   *  XmFormLayout is a Java layout manager which arranges display
72   *  components according to constraints (it was inspired by
73   *  Motif's XmForm widget).  Here is an example of how it is used:
74   *
75   *    public class TestXFL extends java.applet.Applet {
76   *    
77   *      public void init() {
78   *      String constraints[] = {
79   *        "Humpty.bottom=form.bottom-23",
80   *        "Humpty.left=form.left+21",
81   *        "Humpty.right=Tweedle.right",
82   *        "Tweedle.left=Humpty.left",
83   *        "Tweedle.top=form.top+24",
84   *        "Tweedle.bottom=Humpty.top-10",
85   *        "Dumpty.bottom=Humpty.bottom",
86   *        "Dumpty.left=Humpty.right+30",
87   *        "Dumpty.right=form.right-22",
88   *        "Dumpty.top=Humpty.top",
89   *        "Dee.bottom=Tweedle.bottom",
90   *        "Dee.top=Tweedle.top",
91   *        "Dee.left=Dumpty.left",
92   *        "Dee.right=Dumpty.right",
93   *      };
94   *  
95   *      this.setLayout(new XmFormLayout(constraints));
96   *      this.add("Humpty", new java.awt.Button("Humpty"));
97   *      java.awt.TextArea tweedle = new java.awt.TextArea(15,15);
98   *      tweedle.appendText("Tweedle");
99   *      this.add("Tweedle", tweedle);
100  *      this.add("Dumpty", new java.awt.Button("Dumpty"));
101  *      java.awt.TextArea dee = new java.awt.TextArea();
102  *      dee.appendText("Dee");
103  *      this.add("Dee", dee);
104  *    }
105  *  }
106  *
107  */
108 import java.util.Vector;
109 import java.util.Hashtable;
110 import java.net.URL;
111 import java.awt.*;
112 import java.io.*;
113 import openfuture.util.misc.Trace;
114 
115 public class XmFormLayout implements LayoutManager
116 {
117   
118   /**
119    *  Component tuple constants, these must range from 0...6.
120    *  Attribute numbers must range from BOTTOM...TOP.
121    */
122   final static int  COMPONENT = 0;
123   final static int  BOTTOM = 1;
124   final static int  LEFT = 2;
125   final static int  RIGHT = 3;
126   final static int  TOP = 4;
127   final static int  BITSET = 5;
128   final static int  NAME = 6;
129   
130   /**
131    *  Other constants.
132    */
133   final static int  FORM = -32765;
134   final static int  INVALID = -32766;
135   final static int  UNBOUND = -32767;
136   final static boolean  debug = false;
137   final static boolean  bigDebug = false;
138   
139   /**
140    *  The constraints and the results of the
141    *  last reshape() computations.
142    */
143   String myName;
144   Dimension formDimensions;  // (as of last reconstrain)
145   Point formLocation;  // (as of last reconstrain)
146   Vector tuples;    // (4 attrs, component, bitset)
147   Hashtable nameToIndex;
148   String[] constraints;
149   boolean changedFlag;
150   
151 /**
152  *  The constructor.
153  */
154 public XmFormLayout(String newConstraints[]) {
155   this.myName = (((Object) this).getClass()).getName();
156   processConstraints(newConstraints);
157 }
158 /**
159  *  The constructor for reading constraints from file or URL
160  */
161 public XmFormLayout(String constraintsURLOrFile) {
162   this.myName = (((Object) this).getClass()).getName();
163 
164   // decide if the constraintsURLOrFile is a File or a URL
165   if (0 < constraintsURLOrFile.indexOf("://")) {
166     processConstraints(readConstraintsFromURL(constraintsURLOrFile));
167   } else {
168     processConstraints(readConstraintsFromFile(constraintsURLOrFile));
169   }
170 }
171   /**
172    *  Add a component.
173    */
174   public void addLayoutComponent(String name, java.awt.Component component) {
175   Object tuple[]                = new Object[7];
176   tuple[XmFormLayout.COMPONENT] = component;
177   tuple[XmFormLayout.BITSET]    = new java.util.BitSet();
178   tuple[XmFormLayout.NAME]      = name;
179   int componentNr               = this.tuples.size();
180   this.tuples.addElement(tuple);
181   this.nameToIndex.put(name, new Integer(componentNr));
182   this.changedFlag              = true;
183   }  
184 /**
185  *  Parses an expression 'a.b+c' (or 'a.b-c' or 'a.b' or
186  *  '+c' or '-c') into an rvalue 'a.b' and a signed
187  *  number 'c'.  If the rvalue is unbound then return
188  *  XmFormLayout.UNBOUND, otherwise return the value of
189  *  the expression.
190  */
191 private final int evaluate(String expression) throws Exception {
192   int i, s = 1, v = 0;
193   Trace.message(this, "evaluate" + " expr: " + expression);
194 
195   // search for +
196   i = expression.indexOf('+');
197   if (i == -1) {  // no + found, search for -
198     i = expression.indexOf('-');
199     s = -1;
200   }
201   if (i == -1)  {  // no + and no -
202     v = this.getAttr(expression);
203   } else
204     if (i > 1) {
205       String rvalue = expression.substring(0, i);
206       v = this.getAttr(rvalue);
207     }
208   if (i != -1 && v != XmFormLayout.UNBOUND) {
209     if (expression.substring(expression.length() - 1).equals("%")) {
210       String unicodeNumber = expression.substring(i + 1, expression.length() - 1);
211       int number = Integer.parseInt(unicodeNumber, 10);
212       if ((-1 != expression.lastIndexOf("left")) || (-1 != expression.lastIndexOf("right"))) {
213         number = this.formDimensions.width * number / 100;
214         Trace.user(this, "evaluate" + ": Percentage: " + unicodeNumber + " of WIDTH : " + this.formDimensions.width + " equals: " + number);
215       } else {
216         number = this.formDimensions.height * number / 100;
217         Trace.user(this, "evaluate" + " Percentage: " + unicodeNumber + " of HEIGHT: " + this.formDimensions.height + " equals: " + number);
218       }
219       v += (s * number); // s=1 if + found s=-1 if - found
220     } else {
221       String unicodeNumber = expression.substring(i + 1);
222       int number = Integer.parseInt(unicodeNumber, 10);
223       v += (s * number); // s=1 if + found s=-1 if - found
224     }
225   }
226   return v;
227 }
228 /**
229  *  Enforce explicit constraints by binding lvalues and
230  *  also marking those lvalues which can't be bound.
231  *  Parses an explicit constraint 'a.b=c.d+e' into
232  *  an lvalue 'a.b' and an expression 'c.d+e'.
233  *  Returns true if all possible explicit lvalues are bound.
234  */
235 private final boolean explicit(java.util.BitSet constraintBitset) throws Exception {
236   boolean deferFlag = false;
237   if (this.constraints == null || this.constraints.length == 0) {
238     throw new Exception(this.myName + "'explicit() no constraints");
239   }
240   for (int i = 0; i < this.constraints.length; ++i) {
241     if (constraintBitset.get(i)) {
242       continue;
243     }
244     String constraint = this.constraints[i];
245     Trace.message(this, "explicit" + " constraint: " + constraint);
246     int j = constraint.indexOf('=');
247     if (j < 3) {
248       throw new Exception(this.myName + "'explicit() invalid constraint: " + constraint);
249     }
250     String lvalue = constraint.substring(0, j);
251     String expression = constraint.substring(j + 1);
252     if (this.setAttr(lvalue, this.evaluate(expression))) {
253       constraintBitset.set(i);
254     } else {
255       deferFlag = true;
256     }
257   } // end FOR
258   return !deferFlag;
259 }
260 /**
261  *  If the attribute is bound then return its'
262  *  value, otherwise return XmFormLayout.UNBOUND.
263  */
264 private final int getAttr(int componentNr, int attrNr) {
265   Trace.user(this, "getAttr" + " c=" + componentNr + ", a=" + attrNr);
266   int v = XmFormLayout.UNBOUND;
267   if (componentNr == XmFormLayout.FORM) {
268     if (attrNr == XmFormLayout.BOTTOM) {
269       v = this.formLocation.y + this.formDimensions.height;
270     } else if (attrNr == XmFormLayout.LEFT) {
271       v = this.formLocation.x;
272     } else if (attrNr == XmFormLayout.RIGHT) {
273       v = this.formLocation.x + this.formDimensions.width;
274     } else if (attrNr == XmFormLayout.TOP) {
275       v = this.formLocation.y;
276     }
277   } else if (isBound(componentNr, attrNr)) {
278     Object tuple[] = (Object[]) this.tuples.elementAt(componentNr);
279     v = ((Integer) tuple[attrNr]).intValue();
280   }
281   return v;
282 }
283 /**
284  *  If the attribute is bound then return its'
285  *  value, otherwise return XmFormLayout.UNBOUND.
286  */
287 private final int getAttr(String fqAttrName) throws Exception {
288   int tuple[] = this.parseAttr(fqAttrName);
289   // parseAttr parses a.b into comp index of a in tuple[0] 
290   // and attribute in tuple[1]
291   int value = this.getAttr(tuple[0], tuple[1]);
292   Trace.user(this, "getAttr" + " fqAttr=" + fqAttrName + ", value=" + value);
293   return value;
294 }
295 private final int getAttrNr(String attrName) {
296   Trace.user(this, "getAttrNr" + " attr: " + attrName);
297   int attrNr = XmFormLayout.INVALID; // invalid attr # (never happens)
298   if (attrName.equals("bottom")) {
299     attrNr = XmFormLayout.BOTTOM;
300   } else
301     if (attrName.equals("left") || attrName.equals("x")) {
302       attrNr = XmFormLayout.LEFT;
303     } else if (attrName.equals("right")) {
304       attrNr = XmFormLayout.RIGHT;
305     } else if (attrName.equals("top") || attrName.equals("y")) {
306       attrNr = XmFormLayout.TOP;
307     }
308   return attrNr;
309 }
310 private final java.util.BitSet getBitset(int componentNr) {
311   Object tuple[] = (Object[]) this.tuples.elementAt(componentNr);
312   return (java.util.BitSet) tuple[XmFormLayout.BITSET];
313 }
314 private final java.awt.Component getComponent(int componentNr) {
315   Object tuple[] = (Object[]) this.tuples.elementAt(componentNr);
316   return (java.awt.Component) tuple[XmFormLayout.COMPONENT];
317 }
318 private final String getComponentName(int componentNr) {
319   Object tuple[] = (Object[]) this.tuples.elementAt(componentNr);
320   return (String) tuple[XmFormLayout.NAME];
321 }
322 private final int getComponentNr(String componentName) throws Exception {
323   Trace.user(this, "getComponentNr" + " attr: " + componentName);
324   Object n = this.nameToIndex.get(componentName);
325   if (n == null) {
326     throw new Exception(this.myName + "'getComponentNr() not found: " + componentName);
327   }
328   return ((Integer) n).intValue();
329 }
330 /**
331  *  Returns the preferred offset (width or height)
332  *  between the specified attribute and its' opposite.
333  */
334 private final int getOffset(int componentNr, int attrNr) {
335   int offset = XmFormLayout.INVALID; // invalid offset (never happens)
336   java.awt.Component component = this.getComponent(componentNr);
337   if (attrNr == XmFormLayout.BOTTOM) {
338     offset = -component.getPreferredSize().height;
339   } else
340     if (attrNr == XmFormLayout.LEFT) {
341       offset = component.getPreferredSize().width;
342     } else if (attrNr == XmFormLayout.RIGHT) {
343       offset = -component.getPreferredSize().width;
344     } else if (attrNr == XmFormLayout.TOP) {
345       offset = component.getPreferredSize().height;
346     }
347   return offset;
348 }
349 /**
350  *  Enforces implicit constraints by binding component
351  *  attributes which haven't an lvalue in ANY explicit
352  *  constraint and whose opposite attribute is already
353  *  bound, e.g. if foo.top isn't an lvalue in any explicit
354  *  constraint, and foo.bottom is bound, and foo has a
355  *  preferred height of 123, then enforce this implicit
356  *  constraint:
357  *     "foo.top=foo.bottom-123"
358  *  Returns true if all possible implicit constraints are bound.
359  */
360 private final boolean implicit() throws Exception {
361   boolean deferFlag = false;
362   for (int c = 0; c < this.tuples.size(); ++c) {
363     for (int a = XmFormLayout.BOTTOM; a <= XmFormLayout.TOP; ++a) {
364       if (this.isMarked(c, a) == false) {
365         Trace.user(this, "implicit" + " c=" + c + ", a=" + a);
366         int o = this.opposite(a);
367         if (this.isBound(c, o) == true) {
368           // this also marks the attr
369           this.setAttr(c, a, this.getAttr(c, o) + this.getOffset(c, o));
370         } else {
371           deferFlag = true;
372         }
373       }
374     }
375   }
376   return !deferFlag;
377 }
378 /**
379  *  Returns true if this component's attribute was
380  *  bound; that is, if this.setAttr() was called.
381  */
382 private final boolean isBound(int componentNr, int attributeNr) {
383   java.util.BitSet bitset = this.getBitset(componentNr);
384   return bitset.get(attributeNr);
385 }
386 /**
387  *  Returns true if this component's attribute is
388  *  an lvalue in any explicit constraint; that is,
389  *  if this.setMarked() was called.
390  */
391 private final boolean isMarked(int componentNr, int attributeNr) {
392   java.util.BitSet bitset = this.getBitset(componentNr);
393   return bitset.get(attributeNr + (XmFormLayout.TOP + 1));
394 }
395 /**
396  *  Reshape all components in the container.  Typically,
397  *  this causes a call to this.reconstrain() only the first time.
398  */
399 public void layoutContainer(java.awt.Container parent) {
400   java.awt.Dimension dummy = this.preferredLayoutSize(parent); // reconstrain if necessary
401   Trace.user(this, "layoutContainer" + " myPreferredLayoutSize w=" + dummy.width + ", h=" + dummy.height + ", changedFlag=" + changedFlag + " (should be false)\n");
402   if (!this.changedFlag) { // changedFlag == false
403     for (int c = 0; c < this.tuples.size(); ++c) {
404       Object tuple[] = (Object[]) this.tuples.elementAt(c);
405       try {
406         int x = ((Integer) tuple[XmFormLayout.LEFT]).intValue();
407         int y = ((Integer) tuple[XmFormLayout.TOP]).intValue();
408         int w = ((Integer) tuple[XmFormLayout.RIGHT]).intValue() - x;
409         int h = ((Integer) tuple[XmFormLayout.BOTTOM]).intValue() - y;
410         Trace.message(this, "layoutContainer" + " component= " + (String) tuple[XmFormLayout.NAME] + ", x=" + x + ", y=" + y + ", w=" + w + ", h=" + h);
411         java.awt.Component component = (java.awt.Component) tuple[XmFormLayout.COMPONENT];
412         component.setBounds(x, y, w, h);
413       } catch (NullPointerException npex) {
414         Trace.exception(this, "in method layoutContainer. The component >" + (String) tuple[XmFormLayout.NAME] + "< has invalid or missing constraints" + " and is therefore not displayed");
415       }
416     }
417   }
418 }
419 /**
420  *  XmFormLayout knowns only one size (the preferred size).
421  */
422 public Dimension minimumLayoutSize(Container parent) {
423   // return preferredLayoutSize(parent);
424   // changed 30.9.1999 mhg: solved problems of panel resize with split pane
425   return new Dimension(20, 20);
426 }
427 private final int opposite(int attrNr) {
428   int oppositeAttrNr = XmFormLayout.INVALID; 
429   // invalid attr # (never happens)
430 
431   if (attrNr == XmFormLayout.BOTTOM) {
432     oppositeAttrNr = XmFormLayout.TOP;
433   } else
434     if (attrNr == XmFormLayout.LEFT) {
435       oppositeAttrNr = XmFormLayout.RIGHT;
436     } else if (attrNr == XmFormLayout.RIGHT) {
437       oppositeAttrNr = XmFormLayout.LEFT;
438     } else if (attrNr == XmFormLayout.TOP) {
439       oppositeAttrNr = XmFormLayout.BOTTOM;
440     }
441   return oppositeAttrNr;
442 }
443 /**
444  *  Parse a fully-qualified attribute name 'a.b' into
445  *  a component 'a' and an attribute 'b', and return
446  *  the component number and attribute number.
447  */
448 private final int[] parseAttr(String fqAttrName) throws Exception {
449   int i = fqAttrName.indexOf('.');
450   if (i < 1) {
451     throw new Exception(this.myName + "'parseAttr() invalid fqAttr: " + fqAttrName);
452   }
453   String componentName = fqAttrName.substring(0, i);
454   String attrName = fqAttrName.substring(i + 1);
455   int tuple[] = new int[2];
456   if (componentName.equals("form")) {
457     tuple[0] = XmFormLayout.FORM;
458   } else {
459     tuple[0] = this.getComponentNr(componentName);
460   }
461   tuple[1] = this.getAttrNr(attrName);
462   return tuple;
463 }
464 public Dimension preferredLayoutSize(Container parent) {
465   Insets insets = parent.getInsets();
466   int dx = insets.left + insets.right;
467   int dy = insets.top + insets.bottom;
468   Trace.user(this, "preferredLayoutSize" + " x: " + this.formDimensions.width + "  dx: " + dx + "  y: " + this.formDimensions.height + "  dy: " + dy);
469   int x = insets.left;
470   int y = insets.top;
471   int w = parent.getSize().width - dx;
472   int h = parent.getSize().height - dy;
473   this.reshape(x, y, w, h);
474   return new Dimension(this.formDimensions.width + dx, this.formDimensions.height + dy);
475 }
476 private void processConstraints(String newConstraints[]) {
477   if (newConstraints == null) {
478     Trace.message(this, "XmFormLayout" + "'XmFormLayout() newConstraints is null!\n");
479   }
480   for (int i = 0; i < newConstraints.length; i++) {
481     newConstraints[i] = this.removeBlanks(newConstraints[i]);
482   }
483   this.constraints = newConstraints;
484   this.formDimensions = new java.awt.Dimension(0, 0);
485   this.formLocation = new java.awt.Point(0, 0);
486   this.nameToIndex = new java.util.Hashtable();
487   this.tuples = new java.util.Vector();
488   this.changedFlag = true;
489 }
490 private String[] readConstraintsFromFile(String fileConstraints) {
491   try {
492     return readConstraintsFromStream(new BufferedReader(new InputStreamReader(new FileInputStream(new File(fileConstraints)))));
493   } catch (Exception ex) {
494     Trace.exception(this, "-- readConstraintsFromStream: Exception " + ex);
495   }
496   return null;
497 }
498 private String[] readConstraintsFromStream(BufferedReader inStream) {
499   Vector lines = new Vector(20);
500   String[] result = null;
501   int numLines;
502   String line;
503   try {
504     do {
505       line = inStream.readLine();
506       if (null != line)
507         lines.addElement(line);
508     } while (null != line);
509   } catch (NullPointerException npex) {
510     Trace.exception(this, "-- readConstraintsFromStream: NullPointerException");
511   } catch (IOException e2) {
512     Trace.exception(this, "-- readConstraintsFromStream: IOException");
513   }
514   if ((numLines = lines.size()) > 0) {
515     result = new String[numLines];
516     for (int i = 0; i < numLines; i++) {
517       result[i] = (String) lines.elementAt(i);
518     }
519   }
520   return result;
521 }
522 private String[] readConstraintsFromURL(String urlConstraints) {
523   URL myURL = null;
524   try {
525     myURL = new URL(urlConstraints);
526     return readConstraintsFromStream(new BufferedReader(new InputStreamReader(myURL.openStream())));
527   } catch (Exception ex) {
528     Trace.exception(this, "-- readConstraintsFromURL: Exception " + ex);
529   }
530   return null;
531 }
532 /**
533  *  Layout the container according to constraints.
534  *  This may be time-consuming, so it should only be
535  *  done if changedFlag is true.
536  */
537 private final void reconstrain() throws Exception {
538   java.util.BitSet constraintBitset = new java.util.BitSet();
539   for (int c = 0; c < this.tuples.size(); ++c) {
540     java.util.BitSet componentBitset = this.getBitset(c);
541     /*
542        *  The componentBitset has no clearAllBits()
543      *  method so AND with any blank bitset to clear it.
544      */
545     componentBitset.and(constraintBitset);
546   }
547   boolean deferFlag = false;
548   int nrTries = 0;
549   do {
550     Trace.message(this, "reconstrain" + " iteration=" + (nrTries + 1) + "*****\n");
551     deferFlag = false;
552     if (!this.explicit(constraintBitset)) {
553       deferFlag = true;
554     }
555     if (!this.implicit()) {
556       deferFlag = true;
557     }
558   } while (deferFlag && ++nrTries < 30);
559   if (deferFlag) {
560     Trace.exception(this, "in method reconstrain. Too many iterations!!! " + "Probably a missing or incorrect constraint!");
561   }
562   this.changedFlag = false;
563 }
564 /**
565  *  remove blanks from a constraint and return the result
566  */
567 private String removeBlanks(String name) {
568   StringBuffer newName = new StringBuffer();
569   for (int i = 0; i < name.length(); i++) {
570     char c = name.charAt(i);
571     if (c != ' ')
572       newName.append(c);
573   }
574   return newName.toString();
575 }
576 /**
577  *  Removes a component.  This isn't particularly fast,
578  *  but it is rarely called, if ever.
579  */
580 public void removeLayoutComponent(Component oldComponent) {
581   int nrComponents = this.tuples.size();
582   for (int c = 0; c < nrComponents; ++c) {
583     if (this.getComponent(c) == oldComponent) {
584       String componentName = this.getComponentName(c);
585       this.nameToIndex.remove(componentName);
586       this.changedFlag = true;
587     }
588   }
589 }
590 /**
591  *  If the container's location or shape has
592  *  changed, or if any of the component's have
593  *  changed, then re-compute the constraints;
594  *  otherwise use what was already computed.
595  */
596 private final void reshape(int x, int y, int w, int h) {
597   if (this.formDimensions.width != w || this.formDimensions.height != h) {
598     Trace.message(this, "reshape" + " ***SIZE CHANGED*** w=" + w + ", h=" + h + " *******\n");
599     this.formDimensions.width = w;
600     this.formDimensions.height = h;
601     this.changedFlag = true;
602   }
603   if (this.formLocation.x != x || this.formLocation.y != y) {
604     this.formLocation.x = x;
605     this.formLocation.y = y;
606     this.changedFlag = true;
607   }
608   if (changedFlag) {
609     try {
610       this.reconstrain();
611     } catch (Exception exception) {
612       Trace.exception(this, "reshape - " + exception.getMessage());
613     }
614   }
615 }
616 /**
617  *  Try to set a attribute; returns true if the was set
618  *  or false if it was deferred (the latter will happen
619  *  if the value is XmFormLayout.UNBOUND).
620  */
621 private final boolean setAttr(int componentNr, int attrNr, int value) throws Exception {
622   Trace.user(this, "setAttr" + " c=" + componentNr + ", a=" + attrNr + ", v=" + value);
623   if (componentNr == XmFormLayout.FORM) {
624     throw new Exception(this.myName + "'setAttr() can't set form\n");
625   }
626   this.setMarked(componentNr, attrNr);
627   boolean boundFlag = false;
628   if (value != XmFormLayout.UNBOUND) {
629     Object tuple[] = (Object[]) this.tuples.elementAt(componentNr);
630     tuple[attrNr] = new Integer(value);
631     this.setBound(componentNr, attrNr);
632     boundFlag = true;
633   }
634   return boundFlag;
635 }
636 /**
637  *  Try to set a attribute 'c.a'; returns true if the
638  *  was set or false if it was deferred (the latter
639  *  will happen if the value is XmFormLayout.UNBOUND).
640  */
641 private final boolean setAttr(String fqAttrName, int value) throws Exception {
642   Trace.user(this, "setAttr" + " fqAttr=" + fqAttrName + ", value=" + value);
643   int tuple[] = this.parseAttr(fqAttrName);
644   return this.setAttr(tuple[0], tuple[1], value);
645 }
646 private final void setBound(int componentNr, int attrNr) {
647   Trace.user(this, "setBound" + " c=" + componentNr + ", a=" + attrNr);
648   java.util.BitSet bitset = this.getBitset(componentNr);
649   bitset.set(attrNr);
650 }
651 private final void setMarked(int componentNr, int attrNr) {
652   java.util.BitSet bitset = this.getBitset(componentNr);
653   bitset.set(attrNr + (XmFormLayout.TOP + 1));
654 }
655 }