KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > layoutsupport > delegates > GridBagLayoutSupport


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.form.layoutsupport.delegates;
21
22 import java.awt.*;
23 import java.beans.*;
24 import java.util.*;
25 import java.util.List JavaDoc;
26 import java.lang.ref.*;
27 import java.lang.reflect.*;
28
29 import org.openide.nodes.Node;
30 import org.openide.util.NbBundle;
31
32 import org.netbeans.modules.form.layoutsupport.*;
33 import org.netbeans.modules.form.codestructure.*;
34 import org.netbeans.modules.form.FormProperty;
35
36 /**
37  * Support class for GridBagLayout. This is an example of support for layout
38  * managers with complex layout constraints for which rather special code
39  * structure must be managed - GridBagConstraints require to be set up
40  * field by field.
41  *
42  * @author Tran Duc Trung, Tomas Pavek
43  */

44
45 public class GridBagLayoutSupport extends AbstractLayoutSupport
46 {
47     private static Reference customizerRef;
48
49     /** Gets the supported layout manager class - GridBagLayout.
50      * @return the class supported by this delegate
51      */

52     public Class JavaDoc getSupportedClass() {
53         return GridBagLayout.class;
54     }
55
56     /** Returns a class of customizer for GridBagLayout.
57      * @return layout customizer class
58      */

59     public Class JavaDoc getCustomizerClass() {
60         return GridBagCustomizer.Window.class;
61     }
62
63     /** Creates an instance of customizer for GridBagLayout.
64      * @return layout customizer class
65      */

66     public Component getSupportCustomizer() {
67         GridBagCustomizer.Window customizer = null;
68         if (customizerRef != null)
69             customizer = (GridBagCustomizer.Window) customizerRef.get();
70         if (customizer == null) {
71             customizer = new GridBagCustomizer.Window();
72             customizerRef = new WeakReference(customizer);
73         }
74         customizer.setObject(this);
75         return customizer;
76     }
77
78     /** This method is called when switching layout - giving an opportunity to
79      * convert the previous constrainst of components to constraints of the new
80      * layout (this layout). Conversion from AbsoluteConstraints to
81      * GridBagConstraints is implemented here.
82      * @param previousConstraints [input] layout constraints of components in
83      * the previous layout
84      * @param currentConstraints [output] array of converted constraints for
85      * the new layout - to be filled
86      * @param components [input] real components in a real container having the
87      * previous layout
88      */

89     public void convertConstraints(LayoutConstraints[] previousConstraints,
90                                    LayoutConstraints[] currentConstraints,
91                                    Component[] components)
92     {
93         if (currentConstraints == null || components == null
94                 || components.length > currentConstraints.length
95                 || components.length == 0
96                 || !(previousConstraints[0]
97                      instanceof AbsoluteLayoutSupport.AbsoluteLayoutConstraints))
98             return;
99         
100         List JavaDoc xlines = new ArrayList();
101         List JavaDoc ylines = new ArrayList();
102         
103         Rectangle parentbound;
104         Container con = components[0].getParent();
105         if (con == null) {
106             parentbound = components[0].getBounds();
107         } else {
108             parentbound = con.getBounds();
109         }
110         
111         // Determine the size of the grid
112
insertLines(0, xlines);
113         insertLines(0, ylines);
114         
115         for (int i=0; i < components.length; i++) {
116             Rectangle ibounds = components[i].getBounds();
117             
118             if (ibounds.width > 0) {
119                 insertLines(ibounds.x + ibounds.width, xlines);
120             } else {
121                 insertLines(ibounds.x + 1, xlines);
122             }
123             
124             if (ibounds.height > 0) {
125                 insertLines(ibounds.y + ibounds.height, ylines);
126             } else {
127                 insertLines(ibounds.y + 1, ylines);
128             }
129         }
130         
131         // Determine grid width of components.
132
LayoutInfo[] layouts = new LayoutInfo[components.length];
133         for (int i=0; i < layouts.length; i++)
134             layouts[i] = new LayoutInfo();
135         
136         for (int i=0; i < xlines.size() - 1; i++) {
137             int x1 = ((Integer JavaDoc)xlines.get(i)).intValue();
138             int x2 = ((Integer JavaDoc)xlines.get(i+1)).intValue();
139             
140             for (int j=0; j < components.length; j++) {
141                 Rectangle jbounds = components[j].getBounds();
142                 if (jbounds.width <= 0) {
143                     jbounds.width = 1;
144                 }
145                 if (isOverlapped(x1, x2, jbounds.x, jbounds.x + jbounds.width - 1))
146                     layouts[j].incGridWidth(i);
147             }
148         }
149         
150         // Determine grid height of components.
151
for (int i=0; i < ylines.size() - 1; i++) {
152             int y1 = ((Integer JavaDoc)ylines.get(i)).intValue();
153             int y2 = ((Integer JavaDoc)ylines.get(i+1)).intValue();
154             
155             for (int j=0; j < components.length; j++) {
156                 Rectangle jbounds = components[j].getBounds();
157                 if (jbounds.height <= 0) {
158                     jbounds.height = 1;
159                 }
160                 if (isOverlapped(y1, y2, jbounds.y, jbounds.y + jbounds.height - 1))
161                     layouts[j].incGridHeight(i);
162             }
163         }
164         
165         // Calculate insets of the components.
166
for (int i=0; i < components.length; i++) {
167             Rectangle curbounds = components[i].getBounds();
168             int lastleft = 0;
169             int lasttop = 0;
170             
171             for (int j = 0; j < components.length; j++) {
172                 Rectangle jbounds = components[j].getBounds();
173                 int width = jbounds.width;
174                 if(width < 0) width = 0;
175                 if(jbounds.x + width - 1 < curbounds.x){
176                     if(jbounds.x + width > lastleft){
177                         lastleft = jbounds.x + width;
178                     }
179                 }
180                 int height = jbounds.height;
181                 if (height < 0) height = 0;
182                 if (jbounds.y + height - 1 < curbounds.y) {
183                     if(jbounds.y + height > lasttop){
184                         lasttop = jbounds.y + height;
185                     }
186                 }
187             }
188             
189             layouts[i].setLeft(curbounds.x - lastleft);
190             layouts[i].setTop(curbounds.y - lasttop);
191             
192             int width = (curbounds.width < 0) ? 0 : curbounds.width;
193             int height = (curbounds.height < 0) ? 0 : curbounds.height;
194
195             if (layouts[i].getLastGridX() == xlines.size() - 2) {
196                 layouts[i].setRight(parentbound.width - curbounds.x - width);
197             }
198             if (layouts[i].getLastGridY() == ylines.size() - 2) {
199                 layouts[i].setBottom(parentbound.height - curbounds.y - height);
200             }
201         }
202         
203         // GridBagLayout puts the remaining width of the component into the last
204
// grid column/row (if the component has weight 0). This would not be
205
// a problem for us if it would take components sorted according to
206
// their increasing x/y grid coordinate. Unfortunately it takes
207
// components sorted according to their increasing grid width/height.
208
// This can result in a layout that is much wider/higher then the previous
209
// absolute layout. The following code forces the right order by
210
// introduction of new (otherwise redundant) grid lines.
211

212         LayoutInfoComparator comp = new LayoutInfoComparator(LayoutInfoComparator.XAXIS);
213         LayoutInfo [] layoutsX = (LayoutInfo []) layouts.clone();
214         LayoutInfo [] layoutsY = (LayoutInfo []) layouts.clone();
215         Arrays.sort(layoutsX, comp);
216         comp.cord = LayoutInfoComparator.YAXIS;
217         Arrays.sort(layoutsY, comp);
218         
219         for (int i = 0; i < components.length; i++) {
220             int expand = 0;
221             int lastgrid = layoutsX[i].getLastGridX();
222             for (int j = i + 1; j < components.length; j++) {
223                 if (layoutsX[j].containsGridX(lastgrid) && (layoutsX[j].getLastGridX() > lastgrid)
224                     && (layoutsX[i].gridwidth >= layoutsX[j].gridwidth)
225                     && (expand < layoutsX[i].gridwidth - layoutsX[j].gridwidth + 1)) {
226                     expand = layoutsX[i].gridwidth - layoutsX[j].gridwidth + 1;
227                 }
228             }
229             if (expand > 0) {
230                 for (int j = i + 1; j < components.length; j++) {
231                     if (layoutsX[j].containsGridX(lastgrid) && layoutsX[j].getLastGridX() > lastgrid) {
232                         layoutsX[j].expandGridWidth(expand);
233                     } else if (layoutsX[j].gridx > lastgrid) {
234                         layoutsX[j].moveGridX(expand);
235                     }
236                 }
237             }
238             
239             expand = 0;
240             lastgrid = layoutsY[i].getLastGridY();
241             for (int j = i + 1; j < components.length; j++) {
242                 if (layoutsY[j].containsGridY(lastgrid) && (layoutsY[j].getLastGridY() > lastgrid)
243                     && (layoutsY[i].gridheight >= layoutsY[j].gridheight)
244                     && (expand < layoutsY[i].gridheight - layoutsY[j].gridheight + 1)) {
245                     expand = layoutsY[i].gridheight - layoutsY[j].gridheight + 1;
246                 }
247             }
248             if (expand > 0) {
249                 for (int j = i + 1; j < components.length; j++) {
250                     if (layoutsY[j].containsGridY(lastgrid) && layoutsY[j].getLastGridY() > lastgrid) {
251                         layoutsY[j].expandGridHeight(expand);
252                     } else if(layoutsY[j].gridy > lastgrid) {
253                         layoutsY[j].moveGridY(expand);
254                     }
255                 }
256             }
257         }
258     
259         // Generate constraints
260
for (int i=0; i < components.length; i++) {
261             if (Math.max(layouts[i].gridx + layouts[i].gridwidth - 1,
262                 layouts[i].gridy + layouts[i].gridheight - 1) >= 512) {
263                 for (int j=0; j<i; j++) {
264                     currentConstraints[j] = null; // Reset partially converted constraints
265
}
266                 org.openide.DialogDisplayer.getDefault().notify(
267                     new org.openide.NotifyDescriptor.Message(
268                         NbBundle.getMessage(AbstractLayoutSupport.class, "MSG_ERR_MoreThan512"))); // NOI18N
269
return;
270             }
271             GridBagConstraints gbc = new GridBagConstraints();
272             gbc.gridx = layouts[i].gridx;
273             gbc.gridy = layouts[i].gridy;
274             gbc.gridwidth = layouts[i].gridwidth;
275             gbc.gridheight = layouts[i].gridheight;
276             gbc.anchor = GridBagConstraints.NORTHWEST;
277             
278             gbc.insets = new java.awt.Insets JavaDoc(layouts[i].top , layouts[i].left,
279             layouts[i].bottom, layouts[i].right);
280             
281             if (components[i].getClass().getName().equals("javax.swing.JScrollPane")) { // NOI18N
282
gbc.weightx = 1.0;
283                 gbc.weighty = 1.0;
284                 gbc.fill = java.awt.GridBagConstraints.BOTH;
285             }
286             
287             Rectangle bounds = components[i].getBounds();
288             Dimension minsize = components[i].getMinimumSize();
289             Dimension prefsize = components[i].getPreferredSize();
290             
291             if (bounds.width > minsize.width)
292                 gbc.ipadx = bounds.width - minsize.width;
293             else if (bounds.width < prefsize.width)
294                 gbc.ipadx = bounds.width - prefsize.width;
295             if (bounds.height > minsize.height)
296                 gbc.ipady = bounds.height - minsize.height;
297             else if (bounds.height < prefsize.height)
298                 gbc.ipady = bounds.height - prefsize.height;
299             
300             currentConstraints[i] = new GridBagLayoutConstraints(gbc);
301         }
302     }
303     
304     private static boolean isOverlapped(int border1, int border2,
305                                         int compPos1, int compPos2)
306     {
307         return compPos2 >= border1 && compPos1 < border2;
308     }
309     
310     private static void insertLines(int line, java.util.List JavaDoc lines) {
311         if (line < 0)
312             line = 0;
313         for (int i=0; i < lines.size(); i++) {
314             int ival = ((Integer JavaDoc)lines.get(i)).intValue();
315             if (line < ival) {
316                 lines.add(i, new Integer JavaDoc(line));
317                 return;
318             }
319             else if (line == ival)
320                 return;
321         }
322         lines.add(new Integer JavaDoc(line));
323     }
324     
325     /**
326      * Comparator of <code>LayoutInfo</code> objects.
327      */

328     private static class LayoutInfoComparator implements java.util.Comparator JavaDoc{
329         final static int XAXIS = 0;
330         final static int YAXIS = 1;
331         int cord;
332         
333         public LayoutInfoComparator(int cord){
334             this.cord = cord;
335         }
336         
337         public int compare(Object JavaDoc left, Object JavaDoc right) {
338             LayoutInfo layoutleft = (LayoutInfo) left;
339             LayoutInfo layoutright = (LayoutInfo) right;
340             
341             if ((left == null) || (right == null)) return 0;
342             if (cord == XAXIS) {
343                 return layoutleft.getLastGridX() - layoutright.getLastGridX();
344             } else {
345                 return layoutleft.getLastGridY() - layoutright.getLastGridY();
346             }
347         }
348         
349     }
350  
351     /**
352      * Layout information for one component.
353      */

354     private static class LayoutInfo {
355         /** Grid coordinates. */
356         int gridx, gridy;
357         /** Grid width. */
358         int gridwidth;
359         /** Grid height. */
360         int gridheight;
361         /** Insets. */
362         int top = 0, left = 0, bottom = 0, right = 0;
363         
364         void setLeft(int left){
365             if(left < 0) left = 0;
366             this.left = left;
367         }
368         
369         void setTop(int top){
370             if(top < 0) top = 0;
371             this.top = top;
372         }
373         
374         void setBottom(int bottom){
375             if(bottom < 0) bottom = 0;
376             this.bottom = bottom;
377         }
378         
379         void setRight(int right){
380             if(right < 0) right = 0;
381             this.right = right;
382         }
383         
384         void moveGridX(int diff) {
385             gridx += diff;
386         }
387         
388         void moveGridY(int diff) {
389             gridy += diff;
390         }
391         
392         void expandGridWidth(int diff) {
393             gridwidth += diff;
394         }
395         
396         void expandGridHeight(int diff) {
397             gridheight += diff;
398         }
399         
400         void incGridWidth(int gridx) {
401             if (gridwidth == 0)
402                 this.gridx = gridx;
403             gridwidth++;
404         }
405         
406         void incGridHeight(int gridy) {
407             if (gridheight == 0)
408                 this.gridy = gridy;
409             gridheight++;
410         }
411         
412         boolean containsGridX(int grid){
413             return ((grid >= gridx) && (grid < gridx + gridwidth));
414         }
415         
416         boolean containsGridY(int grid){
417             return ((grid >= gridy) && (grid < gridy + gridheight));
418         }
419     
420         int getLastGridX(){
421             return gridx + gridwidth - 1;
422         }
423         
424         int getLastGridY(){
425             return gridy + gridheight - 1;
426         }
427         
428     }
429
430     // --------
431

432     /** This method is called from readComponentCode method to read layout
433      * constraints of a component from code (GridBagConstraints in this case).
434      * @param constrExp CodeExpression object of the constraints (taken from
435      * add method in the code)
436      * @param constrCode CodeGroup to be filled with the relevant constraints
437      * initialization code
438      * @param compExp CodeExpression of the component for which the constraints
439      * are read (not needed here)
440      * @return LayoutConstraints based on information read form code
441      */

442     protected LayoutConstraints readConstraintsCode(CodeExpression constrExp,
443                                                     CodeGroup constrCode,
444                                                     CodeExpression compExp)
445     {
446         GridBagLayoutConstraints constr = new GridBagLayoutConstraints();
447         // reading is done in GridBagLayoutConstraints
448
constr.readCodeExpression(constrExp, constrCode);
449         return constr;
450     }
451
452     /** Called from createComponentCode method, creates code for a component
453      * layout constraints (opposite to readConstraintsCode).
454      * @param constrCode CodeGroup to be filled with constraints code
455      * @param constr layout constraints metaobject representing the constraints
456      * @param compExp CodeExpression object representing the component; not
457      * needed here
458      * @return created CodeExpression representing the layout constraints
459      */

460     protected CodeExpression createConstraintsCode(CodeGroup constrCode,
461                                                    LayoutConstraints constr,
462                                                    CodeExpression compExp,
463                                                    int index)
464     {
465         if (!(constr instanceof GridBagLayoutConstraints))
466             return null;
467
468         // the code creation is done in GridBagLayoutConstraints
469
return ((GridBagLayoutConstraints)constr).createCodeExpression(
470                                             getCodeStructure(), constrCode);
471     }
472
473     /** This method is called to get a default component layout constraints
474      * metaobject in case it is not provided (e.g. in addComponents method).
475      * @return the default LayoutConstraints object for the supported layout;
476      * null if no component constraints are used
477      */

478     protected LayoutConstraints createDefaultConstraints() {
479         return new GridBagLayoutConstraints();
480     }
481
482     // -----------------
483

484     /** LayoutConstraints implementation class for GridBagConstraints.
485      * GridBagConstraints class is special in that it requires more code
486      * statements for initialization (setting up the individual fields).
487      *
488      * There are two possible code variants: simple and complex.
489      * In the simple situation, no parameter of GridBagConstraints is set, so
490      * the code looks like:
491      * container.add(component, new GridBagConstraints());
492      *
493      * In the complex situation, there are some parameters set - this requires
494      * additional code statement for each parameter, and also a variable to
495      * be used for the constraints object. Then the code looks like:
496      * GridBagConstraints gridBagConstraints;
497      * ...
498      * gridBagConstraints = new GridBagConstraints();
499      * gridBagConstraints.gridx = 1;
500      * gridBagConstraints.gridy = 2;
501      * container.add(component, gridBagConstraints);
502      */

503     public static class GridBagLayoutConstraints implements LayoutConstraints {
504         private GridBagConstraints constraints;
505
506         private GridBagConstraints defaultConstraints = new GridBagConstraints();
507
508         private Property[] properties;
509
510         private CodeExpression constraintsExpression;
511         private CodeGroup constraintsCode; // set of all relevant statements
512
private CodeStatement[] propertyStatements; // statements for properties
513

514         private static Constructor constrConstructor;
515
516         private static final int variableType = CodeVariable.LOCAL
517                                          | CodeVariable.EXPLICIT_DECLARATION;
518         private static final int variableMask = CodeVariable.SCOPE_MASK
519                                          | CodeVariable.DECLARATION_MASK;
520         private static final String JavaDoc defaultVariableName = "gridBagConstraints"; // NOI18N
521

522         public GridBagLayoutConstraints() {
523             constraints = new GridBagConstraints();
524         }
525
526         public GridBagLayoutConstraints(GridBagConstraints constraints) {
527             this.constraints = constraints;
528         }
529
530         public Node.Property[] getProperties() {
531             if (properties == null) {
532                 createProperties();
533                 reinstateProperties();
534             }
535             return properties;
536         }
537
538         public Object JavaDoc getConstraintsObject() {
539             return constraints;
540         }
541
542         public LayoutConstraints cloneConstraints() {
543             return new GridBagLayoutConstraints((GridBagConstraints)
544                                                 constraints.clone());
545         }
546
547         // -------
548

549         /** This method creates code expression for the constraints. It's
550          * called from the delegate's createConstraintsCode method.
551          * @param codeStructure CodeStructure in which the expression will be
552          * created
553          * @param constrCode CodeGroup to be filled with all the initialization
554          * statements
555          * @return CodeExpression representing the constraints
556          */

557         private CodeExpression createCodeExpression(CodeStructure codeStructure,
558                                                     CodeGroup constrCode)
559         {
560             this.constraintsCode = constrCode;
561             propertyStatements = null;
562
563             // GridBagConstraints is created by a simple constructor...
564
constraintsExpression = codeStructure.createExpression(
565                                         getConstraintsConstructor(),
566                                         CodeStructure.EMPTY_PARAMS);
567             // ...but the additionlly it requires to create the initialization
568
// code statements
569
updateCodeExpression();
570
571             return constraintsExpression;
572         }
573
574         /** This method reads CodeExpression object representing the
575          * constraints and also all its initialization statements which are
576          * mapped to the constraints properties. It's called from the
577          * delegate's readConstraintsCode method.
578          * @param constrExp CodeExpression of the constraints
579          * @param constrCode CodeGroup to be filled with recognize
580          * initialization statements
581          */

582         private void readCodeExpression(CodeExpression constrExp,
583                                         CodeGroup constrCode)
584         {
585             constraintsExpression = constrExp;
586             constraintsCode = constrCode;
587             propertyStatements = null;
588
589 // constrExp.setOrigin(CodeStructure.createOrigin(
590
// getConstraintsConstructor(),
591
// CodeStructure.EMPTY_PARAMS));
592

593             getProperties(); // ensure properties are created
594

595             boolean isAnyChanged = false;
596
597             Iterator it = CodeStructure.getDefinedStatementsIterator(constrExp);
598             while (it.hasNext()) {
599                 // go through all the statements of constraints code expression
600
CodeStatement statement = (CodeStatement) it.next();
601                 for (int j=0; j < properties.length; j++) {
602                     Property prop = properties[j];
603                     if (prop.field.equals(statement.getMetaObject())) {
604                         // this statement represents a GridBagConstraints field
605
// assignment, we map the corresponding property to it
606
FormCodeSupport.readPropertyStatement(
607                                             statement, prop, false);
608                         setPropertyStatement(j, statement);
609                         if (prop.isChanged()) { // this is a non-default value
610
constrCode.addStatement(statement);
611                             isAnyChanged = true;
612                         }
613                         break;
614                     }
615                 }
616             }
617
618             setupVariable(isAnyChanged);
619         }
620
621         /** This method updates the constraints code according to the
622          * properties. This is called at the beginning - when the constraints
623          * code expression is created - and then after each change of the
624          * constraints properties. This keeps the code consistent with the
625          * properties.
626          */

627         private void updateCodeExpression() {
628             if (constraintsCode == null || constraintsExpression == null)
629                 return;
630
631             constraintsCode.removeAll();
632
633             getProperties(); // ensure properties are created
634

635             boolean isAnyChanged = false;
636             for (int i=0; i < properties.length; i++)
637                 // for each changed property, add the corresponding statement
638
// to the code (constraintsCode - instance of CodeGroup)
639
if (properties[i].isChanged()) {
640                     constraintsCode.addStatement(getPropertyStatement(i));
641                     isAnyChanged = true;
642                 }
643
644             setupVariable(isAnyChanged);
645         }
646
647         /** This method returns the code statement corresponding to property
648          * of given index. The statement is created if it does not exist yet.
649          * @param index index of required statement
650          */

651         private CodeStatement getPropertyStatement(int index) {
652             if (propertyStatements == null)
653                 propertyStatements = new CodeStatement[properties.length];
654
655             CodeStatement propStatement = propertyStatements[index];
656             if (propStatement == null) {
657                 CodeExpression propExp =
658                     constraintsExpression.getCodeStructure().createExpression(
659                         FormCodeSupport.createOrigin(properties[index]));
660
661                 // statement is field assignment; the property code expression
662
// represents the assigned value
663
propStatement = CodeStructure.createStatement(
664                                     constraintsExpression,
665                                     properties[index].field,
666                                     propExp);
667
668                 propertyStatements[index] = propStatement;
669             }
670             return propStatement;
671         }
672
673         /** Sets the code statement read form code for given property index.
674          * @param index index of the corresponding property
675          * @param propStatement CodeStatement to be set
676          */

677         private void setPropertyStatement(int index,
678                                           CodeStatement propStatement)
679         {
680             if (propertyStatements == null)
681                 propertyStatements = new CodeStatement[properties.length];
682             propertyStatements[index] = propStatement;
683         }
684
685         /** This method sets up the variable for constraints code expression.
686          * The variable is needed only there's some property change (i.e.
687          * there's some statement in which the variable would be used). Once
688          * the variable is created, it's used for all the GridBagConstraints
689          * in the form.
690          */

691         private void setupVariable(boolean anyChangedProperty) {
692             CodeStructure codeStructure =
693                 constraintsExpression.getCodeStructure();
694             CodeVariable var = constraintsExpression.getVariable();
695
696             if (anyChangedProperty) { // there should be a variable
697
if (var == null) { // no variable currently used
698
var = findVariable(); // find and reuse variable
699
if (var == null) { // create a new variable
700
var = codeStructure.createVariableForExpression(
701                                                 constraintsExpression,
702                                                 variableType,
703                                                 defaultVariableName);
704                     }
705                     else { // attach the constraints expression to the variable
706
codeStructure.attachExpressionToVariable(
707                                           constraintsExpression, var);
708                     }
709                 }
710                 // add variable assignment code
711
constraintsCode.addStatement(
712                                   0, var.getAssignment(constraintsExpression));
713             }
714             else { // no variable needed
715
codeStructure.removeExpressionFromVariable(
716                                   constraintsExpression);
717             }
718         }
719
720         private CodeVariable findVariable() {
721             CodeStructure codeStructure =
722                 constraintsExpression.getCodeStructure();
723
724             // first try "gridBagConstraints" name - this succeeds in most
725
// cases (unless the name is used elsewhere or not created yet)
726
CodeVariable var = codeStructure.getVariable(defaultVariableName);
727             if (var != null
728                     && (var.getType() & variableMask) == variableType
729                     && GridBagConstraints.class.equals(var.getDeclaredType()))
730                 return var;
731
732             // try to find variable of corresponding type (time expensive)
733
Iterator it = codeStructure.getVariablesIterator(
734                                             variableType,
735                                             variableMask,
736                                             GridBagConstraints.class);
737             while (it.hasNext()) {
738                 var = (CodeVariable) it.next();
739                 if (var.getName().startsWith(defaultVariableName))
740                     return var;
741             }
742
743             return null;
744         }
745
746         private void createProperties() {
747             properties = new Property[] {
748                 new Property("gridx", // NOI18N
749
Integer.TYPE,
750                              getBundle().getString("PROP_gridx"), // NOI18N
751
getBundle().getString("HINT_gridx"), // NOI18N
752
GridPosEditor.class),
753
754                 new Property("gridy", // NOI18N
755
Integer.TYPE,
756                              getBundle().getString("PROP_gridy"), // NOI18N
757
getBundle().getString("HINT_gridy"), // NOI18N
758
GridPosEditor.class),
759
760                 new Property("gridwidth", // NOI18N
761
Integer.TYPE,
762                              getBundle().getString("PROP_gridwidth"), // NOI18N
763
getBundle().getString("HINT_gridwidth"), // NOI18N
764
GridSizeEditor.class),
765
766                 new Property("gridheight", // NOI18N
767
Integer.TYPE,
768                              getBundle().getString("PROP_gridheight"), // NOI18N
769
getBundle().getString("HINT_gridheight"), // NOI18N
770
GridSizeEditor.class),
771
772                 new Property("fill", // NOI18N
773
Integer.TYPE,
774                              getBundle().getString("PROP_fill"), // NOI18N
775
getBundle().getString("HINT_fill"), // NOI18N
776
FillEditor.class),
777
778                 new Property("ipadx", // NOI18N
779
Integer.TYPE,
780                              getBundle().getString("PROP_ipadx"), // NOI18N
781
getBundle().getString("HINT_ipadx"), // NOI18N
782
null),
783
784                 new Property("ipady", // NOI18N
785
Integer.TYPE,
786                               getBundle().getString("PROP_ipady"), // NOI18N
787
getBundle().getString("HINT_ipady"), // NOI18N
788
null),
789
790                 new Property("anchor", // NOI18N
791
Integer.TYPE,
792                              getBundle().getString("PROP_anchor"), // NOI18N
793
getBundle().getString("HINT_anchor"), // NOI18N
794
AnchorEditor.class),
795
796                 new Property("weightx", // NOI18N
797
Double.TYPE,
798                              getBundle().getString("PROP_weightx"), // NOI18N
799
getBundle().getString("HINT_weightx"), // NOI18N
800
null),
801
802                 new Property("weighty", // NOI18N
803
Double.TYPE,
804                              getBundle().getString("PROP_weighty"), // NOI18N
805
getBundle().getString("HINT_weighty"), // NOI18N
806
null),
807
808                 new Property("insets", // NOI18N
809
Insets.class,
810                              getBundle().getString("PROP_insets"), // NOI18N
811
getBundle().getString("HINT_insets"), // NOI18N
812
null)
813             };
814
815             // properties with editable combo box
816
properties[0].setValue("canEditAsText", Boolean.TRUE); // NOI18N
817
properties[1].setValue("canEditAsText", Boolean.TRUE); // NOI18N
818
properties[2].setValue("canEditAsText", Boolean.TRUE); // NOI18N
819
properties[3].setValue("canEditAsText", Boolean.TRUE); // NOI18N
820
}
821
822         private void reinstateProperties() {
823             try {
824                 for (int i=0; i < properties.length; i++) {
825                     FormProperty prop = (FormProperty) properties[i];
826                     prop.reinstateProperty();
827                 }
828             }
829             catch(IllegalAccessException JavaDoc e1) {} // should not happen
830
catch(InvocationTargetException e2) {} // should not happen
831
}
832
833         private static Constructor getConstraintsConstructor() {
834             if (constrConstructor == null) {
835                 try {
836                     constrConstructor =
837                         GridBagConstraints.class.getConstructor(new Class JavaDoc[0]);
838                 }
839                 catch (NoSuchMethodException JavaDoc ex) { // should not happen
840
ex.printStackTrace();
841                 }
842             }
843             return constrConstructor;
844         }
845
846         // ---------
847

848         /** Property implementation for GridBagLayoutConstraints. Each property
849          * is tied to one field of GridBagConstraints. After a change in
850          * property, updateCodeExpression is called to reflect the change in
851          * the code.
852          */

853         private final class Property extends FormProperty {
854             private Field field;
855             private Class JavaDoc propertyEditorClass;
856
857             Property(String JavaDoc name, Class JavaDoc type,
858                      String JavaDoc displayName, String JavaDoc shortDescription,
859                      Class JavaDoc propertyEditorClass)
860             {
861                 super("GridBagLayoutConstraints "+name, type, // NOI18N
862
displayName, shortDescription);
863                 this.propertyEditorClass = propertyEditorClass;
864                 try {
865                     field = GridBagConstraints.class.getField(name);
866                 }
867                 catch (NoSuchFieldException JavaDoc ex) { // should not happen
868
ex.printStackTrace();
869                 }
870             }
871
872             public Object JavaDoc getTargetValue() {
873                 try {
874                     return field.get(constraints);
875                 }
876                 catch (Exception JavaDoc ex) { // should not happen
877
ex.printStackTrace();
878                     return null;
879                 }
880             }
881
882             public void setTargetValue(Object JavaDoc value) {
883                 try {
884                     field.set(constraints, value);
885                 }
886                 catch (Exception JavaDoc ex) { // should not happen
887
ex.printStackTrace();
888                 }
889             }
890
891             public boolean supportsDefaultValue () {
892                 return true;
893             }
894
895             public Object JavaDoc getDefaultValue() {
896                 try {
897                     return field.get(defaultConstraints);
898                 }
899                 catch (Exception JavaDoc ex) { // should not happen
900
ex.printStackTrace();
901                     return null;
902                 }
903             }
904
905             public PropertyEditor getExpliciteEditor() {
906                 if (propertyEditorClass == null)
907                     return null;
908                 try {
909                     return (PropertyEditor) propertyEditorClass.newInstance();
910                 }
911                 catch (Exception JavaDoc ex) { //should not happen
912
ex.printStackTrace();
913                     return null;
914                 }
915             }
916
917             protected void propertyValueChanged(Object JavaDoc old, Object JavaDoc current) {
918                 // #36932 - GridBagLayout allows max. 512 grid size
919
if (current instanceof Integer JavaDoc) {
920                     String JavaDoc name = getName();
921                     if (((name.endsWith("gridx") || name.endsWith("gridwidth")) // NOI18N
922
&& constraints.gridx + constraints.gridwidth > 512)
923                      || ((name.endsWith("gridy") || name.endsWith("gridheight")) // NOI18N
924
&& constraints.gridy + constraints.gridheight > 512))
925                     {
926                         boolean fire = isChangeFiring();
927                         setChangeFiring(false);
928                         try {
929                             setValue(old);
930                         }
931                         catch (Exception JavaDoc ex) {} // should not happen
932
setChangeFiring(fire);
933                         return;
934                     }
935                 }
936
937                 if (isChangeFiring())
938                     updateCodeExpression();
939                 super.propertyValueChanged(old, current);
940             }
941
942             public void setPropertyContext(
943                 org.netbeans.modules.form.FormPropertyContext ctx)
944             { // disabling this method due to limited persistence
945
} // capabilities (compatibility with previous versions)
946
}
947     }
948
949     // ------------
950
// property editors for properties of GridBagLayoutConstraints
951

952     private abstract static class GridBagConstrEditor extends PropertyEditorSupport {
953         String JavaDoc[] tags;
954         Integer JavaDoc[] values;
955         String JavaDoc[] javaInitStrings;
956         boolean otherValuesAllowed;
957
958         public String JavaDoc[] getTags() {
959             return tags;
960         }
961
962         public String JavaDoc getAsText() {
963             Object JavaDoc value = getValue();
964             for (int i=0; i < values.length; i++)
965                 if (values[i].equals(value))
966                     return tags[i];
967
968             return otherValuesAllowed && value != null ?
969                        value.toString() : null;
970         }
971
972         public void setAsText(String JavaDoc str) {
973             for (int i=0; i < tags.length; i++)
974                 if (tags[i].equals(str)) {
975                     setValue(values[i]);
976                     return;
977                 }
978
979             if (otherValuesAllowed)
980                 try {
981                     setValue(new Integer JavaDoc(Integer.parseInt(str)));
982                 }
983                 catch (NumberFormatException JavaDoc e) {} // ignore
984
}
985
986         public String JavaDoc getJavaInitializationString() {
987             Object JavaDoc value = getValue();
988             for (int i=0; i < values.length; i++)
989                 if (values[i].equals(value))
990                     return javaInitStrings[i];
991
992             if (!otherValuesAllowed)
993                 return javaInitStrings[0];
994             return value != null ? value.toString() : null;
995         }
996     }
997
998     public static final class GridPosEditor extends GridBagConstrEditor {
999
1000        public GridPosEditor() {
1001            tags = new String JavaDoc[] {
1002                getBundle().getString("VALUE_relative") // NOI18N
1003
};
1004            values = new Integer JavaDoc[] {
1005                new Integer JavaDoc(GridBagConstraints.RELATIVE)
1006            };
1007            javaInitStrings = new String JavaDoc[] {
1008                "java.awt.GridBagConstraints.RELATIVE" // NOI18N
1009
};
1010            otherValuesAllowed = true;
1011        }
1012    }
1013
1014    public static final class GridSizeEditor extends GridBagConstrEditor {
1015
1016        public GridSizeEditor() {
1017            tags = new String JavaDoc[] {
1018                getBundle().getString("VALUE_relative"), // NOI18N
1019
getBundle().getString("VALUE_remainder") // NOI18N
1020
};
1021            values = new Integer JavaDoc[] {
1022                new Integer JavaDoc(GridBagConstraints.RELATIVE),
1023                new Integer JavaDoc(GridBagConstraints.REMAINDER)
1024            };
1025            javaInitStrings = new String JavaDoc[] {
1026                "java.awt.GridBagConstraints.RELATIVE", // NOI18N
1027
"java.awt.GridBagConstraints.REMAINDER" // NOI18N
1028
};
1029            otherValuesAllowed = true;
1030        }
1031    }
1032
1033    public static final class FillEditor extends GridBagConstrEditor {
1034        public FillEditor() {
1035            tags = new String JavaDoc[] {
1036                getBundle().getString("VALUE_fill_none"), // NOI18N
1037
getBundle().getString("VALUE_fill_horizontal"), // NOI18N
1038
getBundle().getString("VALUE_fill_vertical"), // NOI18N
1039
getBundle().getString("VALUE_fill_both") // NOI18N
1040
};
1041            values = new Integer JavaDoc[] {
1042                new Integer JavaDoc(GridBagConstraints.NONE),
1043                new Integer JavaDoc(GridBagConstraints.HORIZONTAL),
1044                new Integer JavaDoc(GridBagConstraints.VERTICAL),
1045                new Integer JavaDoc(GridBagConstraints.BOTH)
1046            };
1047            javaInitStrings = new String JavaDoc[] {
1048                "java.awt.GridBagConstraints.NONE", // NOI18N
1049
"java.awt.GridBagConstraints.HORIZONTAL", // NOI18N
1050
"java.awt.GridBagConstraints.VERTICAL", // NOI18N
1051
"java.awt.GridBagConstraints.BOTH" // NOI18N
1052
};
1053            otherValuesAllowed = false;
1054        }
1055    }
1056
1057    public static final class AnchorEditor extends GridBagConstrEditor {
1058        public AnchorEditor() {
1059            tags = new String JavaDoc[] {
1060                getBundle().getString("VALUE_anchor_center"), // NOI18N
1061
getBundle().getString("VALUE_anchor_north"), // NOI18N
1062
getBundle().getString("VALUE_anchor_northeast"), // NOI18N
1063
getBundle().getString("VALUE_anchor_east"), // NOI18N
1064
getBundle().getString("VALUE_anchor_southeast"), // NOI18N
1065
getBundle().getString("VALUE_anchor_south"), // NOI18N
1066
getBundle().getString("VALUE_anchor_southwest"), // NOI18N
1067
getBundle().getString("VALUE_anchor_west"), // NOI18N
1068
getBundle().getString("VALUE_anchor_northwest"), // NOI18N
1069
getBundle().getString("VALUE_anchor_pagestart"), // NOI18N
1070
getBundle().getString("VALUE_anchor_pageend"), // NOI18N
1071
getBundle().getString("VALUE_anchor_linestart"), // NOI18N
1072
getBundle().getString("VALUE_anchor_lineend"), // NOI18N
1073
getBundle().getString("VALUE_anchor_firstlinestart"), // NOI18N
1074
getBundle().getString("VALUE_anchor_firstlineend"), // NOI18N
1075
getBundle().getString("VALUE_anchor_lastlinestart"), // NOI18N
1076
getBundle().getString("VALUE_anchor_lastlineend") // NOI18N
1077
};
1078            values = new Integer JavaDoc[] {
1079                new Integer JavaDoc(GridBagConstraints.CENTER),
1080                new Integer JavaDoc(GridBagConstraints.NORTH),
1081                new Integer JavaDoc(GridBagConstraints.NORTHEAST),
1082                new Integer JavaDoc(GridBagConstraints.EAST),
1083                new Integer JavaDoc(GridBagConstraints.SOUTHEAST),
1084                new Integer JavaDoc(GridBagConstraints.SOUTH),
1085                new Integer JavaDoc(GridBagConstraints.SOUTHWEST),
1086                new Integer JavaDoc(GridBagConstraints.WEST),
1087                new Integer JavaDoc(GridBagConstraints.NORTHWEST),
1088                new Integer JavaDoc(GridBagConstraints.PAGE_START),
1089                new Integer JavaDoc(GridBagConstraints.PAGE_END),
1090                new Integer JavaDoc(GridBagConstraints.LINE_START),
1091                new Integer JavaDoc(GridBagConstraints.LINE_END),
1092                new Integer JavaDoc(GridBagConstraints.FIRST_LINE_START),
1093                new Integer JavaDoc(GridBagConstraints.FIRST_LINE_END),
1094                new Integer JavaDoc(GridBagConstraints.LAST_LINE_START),
1095                new Integer JavaDoc(GridBagConstraints.LAST_LINE_END)
1096            };
1097            javaInitStrings = new String JavaDoc[] {
1098                "java.awt.GridBagConstraints.CENTER", // NOI18N
1099
"java.awt.GridBagConstraints.NORTH", // NOI18N
1100
"java.awt.GridBagConstraints.NORTHEAST", // NOI18N
1101
"java.awt.GridBagConstraints.EAST", // NOI18N
1102
"java.awt.GridBagConstraints.SOUTHEAST", // NOI18N
1103
"java.awt.GridBagConstraints.SOUTH", // NOI18N
1104
"java.awt.GridBagConstraints.SOUTHWEST", // NOI18N
1105
"java.awt.GridBagConstraints.WEST", // NOI18N
1106
"java.awt.GridBagConstraints.NORTHWEST", // NOI18N
1107
"java.awt.GridBagConstraints.PAGE_START", // NOI18N
1108
"java.awt.GridBagConstraints.PAGE_END", // NOI18N
1109
"java.awt.GridBagConstraints.LINE_START", // NOI18N
1110
"java.awt.GridBagConstraints.LINE_END", // NOI18N
1111
"java.awt.GridBagConstraints.FIRST_LINE_START", // NOI18N
1112
"java.awt.GridBagConstraints.FIRST_LINE_END", // NOI18N
1113
"java.awt.GridBagConstraints.LAST_LINE_START", // NOI18N
1114
"java.awt.GridBagConstraints.LAST_LINE_END" // NOI18N
1115
};
1116            otherValuesAllowed = false;
1117        }
1118    }
1119
1120    // ------
1121
// temporary hacks for GridBagCustomizer and GridBagControlCenter
1122

1123    static ResourceBundle getBundleHack() {
1124        return getBundle(); // from AbstractLayoutSupport
1125
}
1126
1127    LayoutSupportContext getLayoutSupportHack() {
1128        return super.getLayoutContext();
1129    }
1130}
1131
Popular Tags