KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > JavaCodeGenerator


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;
21
22 import com.sun.source.tree.ClassTree;
23 import com.sun.source.tree.ExpressionTree;
24 import com.sun.source.tree.Tree;
25 import com.sun.source.util.TreePath;
26 import java.util.logging.Level JavaDoc;
27 import java.util.logging.Logger JavaDoc;
28 import javax.lang.model.element.Element;
29 import javax.lang.model.element.TypeElement;
30 import javax.lang.model.type.TypeMirror;
31 import javax.swing.JEditorPane JavaDoc;
32 import org.netbeans.api.editor.guards.InteriorSection;
33 import org.netbeans.api.editor.guards.SimpleSection;
34 import org.netbeans.api.java.source.CancellableTask;
35 import org.netbeans.api.java.source.CompilationController;
36 import org.netbeans.api.java.source.JavaSource;
37 import org.netbeans.api.java.source.TreeMaker;
38 import org.netbeans.api.java.source.WorkingCopy;
39 import org.netbeans.modules.form.editors.ModifierEditor;
40 import org.openide.*;
41 import org.openide.filesystems.*;
42 import org.openide.nodes.*;
43 import org.openide.text.IndentEngine;
44
45 import org.netbeans.api.editor.fold.*;
46
47 import org.netbeans.api.java.classpath.ClassPath;
48
49 import org.netbeans.modules.form.editors.CustomCodeEditor;
50 import org.netbeans.modules.form.codestructure.*;
51 import org.netbeans.modules.form.layoutsupport.LayoutSupportManager;
52 import org.netbeans.modules.form.layoutdesign.LayoutComponent;
53 import org.netbeans.modules.form.layoutdesign.support.SwingLayoutCodeGenerator;
54
55 import java.awt.*;
56 import java.beans.*;
57 import java.io.*;
58 import java.lang.reflect.*;
59 import java.util.*;
60
61 /**
62  * JavaCodeGenerator is the default code generator which produces a Java source
63  * for the form.
64  *
65  * @author Ian Formanek, Jan Stola
66  */

67
68 class JavaCodeGenerator extends CodeGenerator {
69
70     static final String JavaDoc PROP_VARIABLE_MODIFIER = "modifiers"; // NOI18N
71
static final String JavaDoc PROP_VARIABLE_LOCAL = "useLocalVariable"; // NOI18N
72
static final String JavaDoc PROP_SERIALIZE_TO = "serializeTo"; // NOI18N
73
static final String JavaDoc PROP_CODE_GENERATION = "codeGeneration"; // NOI18N
74
static final String JavaDoc PROP_CREATE_CODE_PRE = "creationCodePre"; // NOI18N
75
static final String JavaDoc PROP_CREATE_CODE_POST = "creationCodePost"; // NOI18N
76
static final String JavaDoc PROP_CREATE_CODE_CUSTOM = "creationCodeCustom"; // NOI18N
77
static final String JavaDoc PROP_INIT_CODE_PRE = "initCodePre"; // NOI18N
78
static final String JavaDoc PROP_INIT_CODE_POST = "initCodePost"; // NOI18N
79
static final String JavaDoc PROP_LISTENERS_POST = "listenersCodePost"; // NOI18N
80
static final String JavaDoc PROP_ADDING_PRE = "addingCodePre"; // NOI18N
81
static final String JavaDoc PROP_ADDING_POST = "addingCodePost"; // NOI18N
82
static final String JavaDoc PROP_LAYOUT_PRE = "layoutCodePre"; // NOI18N
83
static final String JavaDoc PROP_LAYOUT_POST = "layoutCodePost"; // NOI18N
84
static final String JavaDoc PROP_ALL_SET_POST = "allCodePost"; // NOI18N
85
static final String JavaDoc PROP_DECLARATION_PRE = "declarationPre"; // NOI18N
86
static final String JavaDoc PROP_DECLARATION_POST = "declarationPost"; // NOI18N
87
static final String JavaDoc PROP_GENERATE_MNEMONICS = "generateMnemonicsCode"; // Mnemonics support // NOI18N
88
static final String JavaDoc PROP_LISTENER_GENERATION_STYLE = "listenerGenerationStyle"; // NOI18N
89

90     static final String JavaDoc AUX_VARIABLE_MODIFIER =
91         "JavaCodeGenerator_VariableModifier"; // NOI18N
92
static final String JavaDoc AUX_VARIABLE_LOCAL =
93         "JavaCodeGenerator_VariableLocal"; // NOI18N
94
static final String JavaDoc AUX_SERIALIZE_TO =
95         "JavaCodeGenerator_SerializeTo"; // NOI18N
96
static final String JavaDoc AUX_CODE_GENERATION =
97         "JavaCodeGenerator_CodeGeneration"; // NOI18N
98
static final String JavaDoc AUX_CREATE_CODE_PRE =
99         "JavaCodeGenerator_CreateCodePre"; // NOI18N
100
static final String JavaDoc AUX_CREATE_CODE_POST =
101         "JavaCodeGenerator_CreateCodePost"; // NOI18N
102
static final String JavaDoc AUX_CREATE_CODE_CUSTOM =
103         "JavaCodeGenerator_CreateCodeCustom"; // NOI18N
104
static final String JavaDoc AUX_INIT_CODE_PRE =
105         "JavaCodeGenerator_InitCodePre"; // NOI18N
106
static final String JavaDoc AUX_INIT_CODE_POST =
107         "JavaCodeGenerator_InitCodePost"; // NOI18N
108
static final String JavaDoc AUX_LISTENERS_POST =
109         "JavaCodeGenerator_ListenersCodePost"; // NOI18N
110
static final String JavaDoc AUX_ADDING_PRE =
111         "JavaCodeGenerator_AddingCodePre"; // NOI18N
112
static final String JavaDoc AUX_ADDING_POST =
113         "JavaCodeGenerator_AddingCodePost"; // NOI18N
114
static final String JavaDoc AUX_LAYOUT_PRE =
115         "JavaCodeGenerator_LayoutCodePre"; // NOI18N
116
static final String JavaDoc AUX_LAYOUT_POST =
117         "JavaCodeGenerator_LayoutCodePost"; // NOI18N
118
static final String JavaDoc AUX_ALL_SET_POST =
119         "JavaCodeGenerator_allCodePost"; // NOI18N
120
static final String JavaDoc AUX_DECLARATION_PRE =
121         "JavaCodeGenerator_DeclarationPre"; // NOI18N
122
static final String JavaDoc AUX_DECLARATION_POST =
123         "JavaCodeGenerator_DeclarationPost"; // NOI18N
124

125     static final Integer JavaDoc VALUE_GENERATE_CODE = new Integer JavaDoc(0);
126     static final Integer JavaDoc VALUE_SERIALIZE = new Integer JavaDoc(1);
127
128     // types of code generation of event listeners
129
static final int ANONYMOUS_INNERCLASSES = 0;
130     static final int CEDL_INNERCLASS = 1;
131     static final int CEDL_MAINCLASS = 2;
132
133     // types of code generation of layout code
134
static final int LAYOUT_CODE_AUTO = 0;
135     static final int LAYOUT_CODE_JDK6 = 1;
136     static final int LAYOUT_CODE_LIBRARY = 2;
137
138     private static final String JavaDoc EVT_SECTION_PREFIX = "event_"; // NOI18N
139

140     private static final String JavaDoc DEFAULT_LISTENER_CLASS_NAME = "FormListener"; // NOI18N
141

142     static final String JavaDoc CUSTOM_CODE_MARK = "\u001F"; // NOI18N
143
private static final String JavaDoc CODE_MARK = "*/\n\\"; // NOI18N
144
private static final String JavaDoc MARKED_PROPERTY_CODE = "*/\n\\0"; // NOI18N
145
private static final String JavaDoc PROPERTY_LINE_COMMENT = "*/\n\\1"; // NOI18N
146

147     private static final String JavaDoc RESOURCE_BUNDLE_OPENING_CODE = "java.util.ResourceBundle.getBundle("; // NOI18N
148
private static final String JavaDoc RESOURCE_BUNDLE_CLOSING_CODE = ")."; // NOI18N
149
private Map<String JavaDoc,String JavaDoc> bundleVariables;
150
151     private static String JavaDoc variablesHeader;
152     private static String JavaDoc variablesFooter;
153     private static String JavaDoc eventDispatchCodeComment;
154
155     /** The FormLoaderSettings instance */
156     private static FormLoaderSettings formSettings = FormLoaderSettings.getInstance();
157                    
158
159     private FormModel formModel;
160     private FormEditorSupport formEditorSupport;
161
162     private boolean initialized = false;
163     private boolean canGenerate = true;
164     private boolean codeUpToDate = true;
165
166     private String JavaDoc listenerClassName;
167     private String JavaDoc listenerVariableName;
168
169     // data needed when listener generation style is CEDL_MAINCLASS
170
private Class JavaDoc[] listenersInMainClass;
171     private Class JavaDoc[] listenersInMainClass_lastSet;
172
173     private int emptyLineCounter;
174     private int emptyLineRequest;
175
176     private Map constructorProperties;
177     private Map<RADComponent, java.util.List JavaDoc<FormProperty>> parentDependentProperties;
178     private Map<RADComponent, java.util.List JavaDoc<FormProperty>> childrenDependentProperties;
179
180     private SwingLayoutCodeGenerator swingGenerator;
181
182     private static class PropertiesFilter implements FormProperty.Filter {
183         
184     private final java.util.List JavaDoc properties;
185     
186     public PropertiesFilter(java.util.List JavaDoc properties) {
187         this.properties = properties;
188     }
189     
190         public boolean accept(FormProperty property) {
191         return (property.isChanged()
192                        && (properties == null
193                            || !properties.contains(property)))
194                     || property.getPreCode() != null
195                     || property.getPostCode() != null;
196         }
197     };
198
199     /** Creates new JavaCodeGenerator */
200
201 // public JavaCodeGenerator() {
202
// }
203

204     public void initialize(FormModel formModel) {
205         if (!initialized) {
206             this.formModel = formModel;
207             FormDataObject formDO = FormEditor.getFormDataObject(formModel);
208             formEditorSupport = formDO.getFormEditorSupport();
209
210             if (formDO.getPrimaryFile().canWrite()) {
211                 canGenerate = true;
212                 formModel.addFormModelListener(new FormListener());
213             }
214             else canGenerate = false;
215
216             SimpleSection initComponentsSection = formEditorSupport.getInitComponentSection();
217             SimpleSection variablesSection = formEditorSupport.getVariablesSection();
218
219             if (initComponentsSection == null || variablesSection == null) {
220                 System.err.println("ERROR: Cannot initialize guarded sections... code generation is disabled."); // NOI18N
221
canGenerate = false;
222             }
223
224             initialized = true;
225         }
226     }
227
228     /**
229      * Alows the code generator to provide synthetic properties for specified
230      * component which are specific to the code generation method. E.g. a
231      * JavaCodeGenerator will return variableName property, as it generates
232      * global Java variable for every component
233      * @param component The RADComponent for which the properties are to be obtained
234      */

235
236     public Node.Property[] getSyntheticProperties(final RADComponent component) {
237         ResourceBundle bundle = FormUtils.getBundle();
238         java.util.List JavaDoc propList = new ArrayList();
239         if (component == null) {
240             propList.add(new VariablesModifierProperty());
241             propList.add(new LocalVariablesProperty());
242             propList.add(new GenerateMnemonicsCodeProperty());
243             propList.add(new ListenerGenerationStyleProperty());
244             propList.add(new LayoutCodeTargetProperty());
245         } else if (component != formModel.getTopRADComponent()) {
246             
247             propList.add(createBeanClassNameProperty(component));
248             
249             propList.add(new PropertySupport.ReadWrite(
250                 RADComponent.PROP_NAME,
251                 String JavaDoc.class,
252                 bundle.getString("MSG_JC_VariableName"), // NOI18N
253
bundle.getString("MSG_JC_VariableDesc")) // NOI18N
254
{
255                 public void setValue(Object JavaDoc value) {
256                     if (!(value instanceof String JavaDoc))
257                         throw new IllegalArgumentException JavaDoc();
258
259                     component.setName((String JavaDoc)value);
260                     component.getNodeReference().firePropertyChangeHelper(
261                         RADComponent.PROP_NAME, null, null); // NOI18N
262
}
263
264                 public Object JavaDoc getValue() {
265                     return component.getName();
266                 }
267
268                 public boolean canWrite() {
269                     return JavaCodeGenerator.this.canGenerate && !component.isReadOnly();
270                 }
271             });
272
273             final FormProperty modifProp = new FormProperty(
274                 PROP_VARIABLE_MODIFIER,
275                 Integer JavaDoc.class,
276                 bundle.getString("MSG_JC_VariableModifiers"), // NOI18N
277
null)
278             {
279                 public void setTargetValue(Object JavaDoc value) {
280                     if (!(value instanceof Integer JavaDoc))
281                         throw new IllegalArgumentException JavaDoc();
282
283                     Object JavaDoc oldValue = getTargetValue();
284
285                     CodeStructure codeStructure = formModel.getCodeStructure();
286                     CodeExpression exp = component.getCodeExpression();
287                     int varType = exp.getVariable().getType();
288                     String JavaDoc varName = component.getName();
289
290                     varType &= ~CodeVariable.ALL_MODIF_MASK;
291                     varType |= ((Integer JavaDoc)value).intValue() & CodeVariable.ALL_MODIF_MASK;
292
293                     if ((varType & CodeVariable.ALL_MODIF_MASK)
294                             != (formModel.getSettings().getVariablesModifier()
295                                 & CodeVariable.ALL_MODIF_MASK))
296                     { // non-default value
297
component.setAuxValue(AUX_VARIABLE_MODIFIER,
298                                 new Integer JavaDoc(varType & CodeVariable.ALL_MODIF_MASK)); // value
299
}
300                     else { // default value
301
varType = 0x30DF; // default
302
if (component.getAuxValue(AUX_VARIABLE_MODIFIER) != null) {
303                             component.getAuxValues().remove(AUX_VARIABLE_MODIFIER);
304                         }
305                     }
306
307                     codeStructure.removeExpressionFromVariable(exp);
308                     codeStructure.createVariableForExpression(
309                                          exp, varType, varName);
310                 }
311
312                 public Object JavaDoc getTargetValue() {
313                     Object JavaDoc val = component.getAuxValue(AUX_VARIABLE_MODIFIER);
314                     if (val != null)
315                         return val;
316
317                     return new Integer JavaDoc(formModel.getSettings().getVariablesModifier());
318                 }
319
320                 public boolean supportsDefaultValue() {
321                     return component.getAuxValue(AUX_VARIABLE_LOCAL) == null;
322                 }
323
324                 public Object JavaDoc getDefaultValue() {
325                     return component.getAuxValue(AUX_VARIABLE_LOCAL) == null ?
326                            new Integer JavaDoc(formModel.getSettings().getVariablesModifier()) : null;
327                 }
328
329                 protected void propertyValueChanged(Object JavaDoc old, Object JavaDoc current) {
330                     super.propertyValueChanged(old, current);
331                     if (isChangeFiring()) {
332                         formModel.fireSyntheticPropertyChanged(
333                             component, getName(), old, current);
334                         if (component.getNodeReference() != null) {
335                             component.getNodeReference().firePropertyChangeHelper(
336                                 getName(), null, null);
337                         }
338                     }
339                 }
340
341                 public boolean canWrite() {
342                     return JavaCodeGenerator.this.canGenerate && !component.isReadOnly();
343                 }
344
345                 public PropertyEditor getExpliciteEditor() { // getPropertyEditor
346
Boolean JavaDoc local = (Boolean JavaDoc) component.getAuxValue(AUX_VARIABLE_LOCAL);
347                     if (local == null)
348                         local = Boolean.valueOf(formModel.getSettings().getVariablesLocal());
349                     return Boolean.TRUE.equals(local) ?
350                         new ModifierEditor(Modifier.FINAL)
351                         :
352                         new ModifierEditor(Modifier.PUBLIC
353                                            | Modifier.PROTECTED
354                                            | Modifier.PRIVATE
355                                            | Modifier.STATIC
356                                            | Modifier.FINAL
357                                            | Modifier.TRANSIENT
358                                            | Modifier.VOLATILE);
359                 }
360             };
361             modifProp.setShortDescription(bundle.getString("MSG_JC_VariableModifiersDesc")); // NOI18N
362
propList.add(modifProp);
363
364             FormProperty localProp = new FormProperty(
365                 PROP_VARIABLE_LOCAL,
366                 Boolean.TYPE,
367                 bundle.getString("MSG_JC_UseLocalVar"), // NOI18N
368
null)
369             {
370                 public void setTargetValue(Object JavaDoc value) {
371                     if (!(value instanceof Boolean JavaDoc))
372                         throw new IllegalArgumentException JavaDoc();
373
374                     Boolean JavaDoc oldValue = (Boolean JavaDoc) getTargetValue();
375 // if (value.equals(oldValue)) return;
376

377                     CodeStructure codeStructure = formModel.getCodeStructure();
378                     CodeExpression exp = component.getCodeExpression();
379                     int varType = exp.getVariable().getType();
380                     String JavaDoc varName = component.getName();
381
382                     varType &= CodeVariable.FINAL
383                                | ~(CodeVariable.ALL_MODIF_MASK | CodeVariable.SCOPE_MASK);
384                     if (Boolean.TRUE.equals(value))
385                         varType |= CodeVariable.LOCAL;
386                     else
387                         varType |= CodeVariable.FIELD
388                                    | formModel.getSettings().getVariablesModifier();
389
390                     if (((varType & CodeVariable.LOCAL) != 0)
391                             != (formModel.getSettings().getVariablesLocal()))
392                     { // non-default value
393
component.setAuxValue(AUX_VARIABLE_LOCAL, value);
394                         try {
395                             modifProp.setValue(new Integer JavaDoc(varType & CodeVariable.ALL_MODIF_MASK));
396                         }
397                         catch (Exception JavaDoc ex) { // should not happen
398
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
399                         }
400                     }
401                     else { // default value
402
varType = 0x30DF; // default
403
if (component.getAuxValue(AUX_VARIABLE_LOCAL) != null) {
404                             component.getAuxValues().remove(AUX_VARIABLE_LOCAL);
405                         }
406                         try {
407                             modifProp.restoreDefaultValue();
408                         }
409                         catch (Exception JavaDoc ex) { // should not happen
410
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
411                         }
412                     }
413
414                     codeStructure.removeExpressionFromVariable(exp);
415                     codeStructure.createVariableForExpression(
416                                          exp, varType, varName);
417                 }
418
419                 public Object JavaDoc getTargetValue() {
420                     Object JavaDoc val = component.getAuxValue(AUX_VARIABLE_LOCAL);
421                     if (val != null)
422                         return val;
423
424                     return Boolean.valueOf(formModel.getSettings().getVariablesLocal());
425                 }
426
427                 public boolean supportsDefaultValue() {
428                     return true;
429                 }
430
431                 public Object JavaDoc getDefaultValue() {
432                     return Boolean.valueOf(formModel.getSettings().getVariablesLocal());
433                 }
434
435                 protected void propertyValueChanged(Object JavaDoc old, Object JavaDoc current) {
436                     super.propertyValueChanged(old, current);
437                     if (isChangeFiring()) {
438                         formModel.fireSyntheticPropertyChanged(
439                             component, getName(), old, current);
440                         if (component.getNodeReference() != null) {
441                             component.getNodeReference().firePropertyChangeHelper(
442                                 getName(), null, null);
443                         }
444                     }
445                 }
446
447                 public boolean canWrite() {
448                     return JavaCodeGenerator.this.canGenerate && !component.isReadOnly();
449                 }
450             };
451             localProp.setShortDescription(bundle.getString("MSG_JC_UseLocalVarDesc")); // NOI18N
452
propList.add(localProp);
453
454             // Mnemonics support - start -
455
if (javax.swing.JLabel JavaDoc.class.isAssignableFrom(component.getBeanClass())
456                     || javax.swing.AbstractButton JavaDoc.class.isAssignableFrom(component.getBeanClass()))
457                 propList.add(new PropertySupport.ReadWrite(
458                     PROP_GENERATE_MNEMONICS,
459                     Boolean.TYPE,
460                     bundle.getString("PROP_GENERATE_MNEMONICS"), // NOI18N
461
bundle.getString("HINT_GENERATE_MNEMONICS2")) // NOI18N
462
{
463                     public void setValue(Object JavaDoc value) {
464                         Object JavaDoc oldValue = getValue();
465                         component.setAuxValue(PROP_GENERATE_MNEMONICS, value);
466                         formModel.fireSyntheticPropertyChanged(
467                             component, PROP_GENERATE_MNEMONICS, oldValue, value);
468                         component.getNodeReference().firePropertyChangeHelper(
469                             PROP_GENERATE_MNEMONICS, null, null); // NOI18N
470
}
471
472                     public Object JavaDoc getValue() {
473                         return isUsingMnemonics(component) ?
474                                Boolean.TRUE : Boolean.FALSE;
475                     }
476
477                     public boolean canWrite() {
478                         return JavaCodeGenerator.this.canGenerate && !component.isReadOnly();
479                     }
480
481                     public boolean supportsDefaultValue() {
482                         return true;
483                     }
484
485                     public void restoreDefaultValue() {
486                         setValue(null);
487                     }
488                 });
489             // Mnemonics support - end -
490

491             propList.add(new CodeProperty(
492                     component,
493                     PROP_CREATE_CODE_CUSTOM, AUX_CREATE_CODE_CUSTOM,
494                     bundle.getString("MSG_JC_CustomCreationCode"), // NOI18N
495
bundle.getString("MSG_JC_CustomCreationCodeDesc"))); // NOI18N
496

497             propList.add(new CodeProperty(
498                     component,
499                     PROP_CREATE_CODE_PRE, AUX_CREATE_CODE_PRE,
500                     bundle.getString("MSG_JC_PreCreationCode"), // NOI18N
501
bundle.getString("MSG_JC_PreCreationCodeDesc"))); // NOI18N
502
propList.add(new CodeProperty(
503                     component,
504                     PROP_CREATE_CODE_POST, AUX_CREATE_CODE_POST,
505                     bundle.getString("MSG_JC_PostCreationCode"), // NOI18N
506
bundle.getString("MSG_JC_PostCreationCodeDesc"))); // NOI18N
507

508             propList.add(new CodeProperty(
509                     component,
510                     PROP_INIT_CODE_PRE, AUX_INIT_CODE_PRE,
511                     bundle.getString("MSG_JC_PreInitCode"), // NOI18N
512
bundle.getString("MSG_JC_PreInitCodeDesc"))); // NOI18N
513
propList.add(new CodeProperty(
514                     component,
515                     PROP_INIT_CODE_POST, AUX_INIT_CODE_POST,
516                     bundle.getString("MSG_JC_PostInitCode"), // NOI18N
517
bundle.getString("MSG_JC_PostInitCodeDesc"))); // NOI18N
518

519             propList.add(new CodeProperty(
520                     component,
521                     PROP_LISTENERS_POST, AUX_LISTENERS_POST,
522                     bundle.getString("MSG_JC_PostListenersCode"), // NOI18N
523
bundle.getString("MSG_JC_PostListenersCodeDesc"))); // NOI18N
524

525             if (component.getParentComponent() != null) {
526                 propList.add(new CodeProperty(
527                         component,
528                         PROP_ADDING_PRE, AUX_ADDING_PRE,
529                         bundle.getString("MSG_JC_PreAddCode"), // NOI18N
530
bundle.getString("MSG_JC_PreAddCodeDesc"))); // NOI18N
531
propList.add(new CodeProperty(
532                         component,
533                         PROP_ADDING_POST, AUX_ADDING_POST,
534                         bundle.getString("MSG_JC_PostAddCode"), // NOI18N
535
bundle.getString("MSG_JC_PostAddCodeDesc"))); // NOI18N
536
}
537
538             if (component instanceof ComponentContainer) {
539                 propList.add(new CodeProperty(
540                         component,
541                         PROP_LAYOUT_PRE, AUX_LAYOUT_PRE,
542                         bundle.getString("MSG_JC_PrePopulationCode"), // NOI18N
543
bundle.getString("MSG_JC_PrePopulationCodeDesc"))); // NOI18N
544
propList.add(new CodeProperty(
545                         component,
546                         PROP_LAYOUT_POST, AUX_LAYOUT_POST,
547                         bundle.getString("MSG_JC_PostPopulationCode"), // NOI18N
548
bundle.getString("MSG_JC_PostPopulationCodeDesc"))); // NOI18N
549
}
550
551             propList.add(new CodeProperty(
552                     component,
553                     PROP_ALL_SET_POST, AUX_ALL_SET_POST,
554                     bundle.getString("MSG_JC_AfterAllSetCode"), // NOI18N
555
bundle.getString("MSG_JC_AfterAllSetCodeDesc"))); // NOI18N
556

557             propList.add(new CodeProperty(
558                     component,
559                     PROP_DECLARATION_PRE, AUX_DECLARATION_PRE,
560                     bundle.getString("MSG_JC_PreDeclaration"), // NOI18N
561
bundle.getString("MSG_JC_PreDeclarationDesc"))); // NOI18N
562
propList.add(new CodeProperty(
563                     component,
564                     PROP_DECLARATION_POST, AUX_DECLARATION_POST,
565                     bundle.getString("MSG_JC_PostDeclaration"), // NOI18N
566
bundle.getString("MSG_JC_PostDeclarationDesc"))); // NOI18N
567

568             propList.add(new PropertySupport.ReadWrite(
569                 PROP_CODE_GENERATION,
570                 Integer.TYPE,
571                 bundle.getString("MSG_JC_CodeGeneration"), // NOI18N
572
bundle.getString("MSG_JC_CodeGenerationDesc")) // NOI18N
573
{
574                 public void setValue(Object JavaDoc value) {
575                     if (!(value instanceof Integer JavaDoc))
576                         throw new IllegalArgumentException JavaDoc();
577
578                     Object JavaDoc oldValue = getValue();
579
580                     if (!getDefaultValue().equals(value))
581                         component.setAuxValue(AUX_CODE_GENERATION, value);
582                     else if (component.getAuxValue(AUX_CODE_GENERATION) != null) {
583                         component.getAuxValues().remove(AUX_CODE_GENERATION);
584                     }
585
586                     if (value.equals(VALUE_SERIALIZE)
587                             && component.getAuxValue(AUX_SERIALIZE_TO) == null)
588                         component.setAuxValue(AUX_SERIALIZE_TO,
589                                               getDefaultSerializedName(component));
590
591                     formModel.fireSyntheticPropertyChanged(
592                         component, PROP_CODE_GENERATION, oldValue, value);
593                     component.getNodeReference().firePropertyChangeHelper(
594                         PROP_CODE_GENERATION, null, null); // NOI18N
595
}
596
597                 public Object JavaDoc getValue() {
598                     Object JavaDoc value = component.getAuxValue(AUX_CODE_GENERATION);
599                     if (value == null)
600                         value = getDefaultValue();
601                     return value;
602                 }
603
604                 public boolean canWrite() {
605                     return JavaCodeGenerator.this.canGenerate && !component.isReadOnly();
606                 }
607
608                 public PropertyEditor getPropertyEditor() {
609                     return new CodeGenerateEditor(component);
610                 }
611
612                 private Object JavaDoc getDefaultValue() {
613                     return component.hasHiddenState() ?
614                                 VALUE_SERIALIZE : VALUE_GENERATE_CODE;
615                 }
616             });
617
618             propList.add(new PropertySupport.ReadWrite(
619                 PROP_SERIALIZE_TO,
620                 String JavaDoc.class,
621                 bundle.getString("MSG_JC_SerializeTo"), // NOI18N
622
bundle.getString("MSG_JC_SerializeToDesc")) // NOI18N
623
{
624                 public void setValue(Object JavaDoc value) {
625                     if (!(value instanceof String JavaDoc))
626                         throw new IllegalArgumentException JavaDoc();
627
628                     Object JavaDoc oldValue = getValue();
629
630                     if (!"".equals(value)) // NOI18N
631
component.setAuxValue(AUX_SERIALIZE_TO, value);
632                     else if (component.getAuxValue(AUX_SERIALIZE_TO) != null) {
633                         component.getAuxValues().remove(AUX_SERIALIZE_TO);
634                     }
635
636                     formModel.fireSyntheticPropertyChanged(
637                         component, PROP_SERIALIZE_TO, oldValue, value);
638                     component.getNodeReference().firePropertyChangeHelper(
639                         PROP_SERIALIZE_TO, null, null); // NOI18N
640
}
641
642                 public Object JavaDoc getValue() {
643                     Object JavaDoc value = component.getAuxValue(AUX_SERIALIZE_TO);
644                     if (value == null)
645                         value = getDefaultSerializedName(component);
646                     return value;
647                 }
648
649                 public boolean canWrite() {
650                     return JavaCodeGenerator.this.canGenerate && !component.isReadOnly();
651                 }
652             });
653         }
654         else if (Component.class.isAssignableFrom(component.getBeanClass()))
655         {
656             propList.add(new PropertySupport.ReadOnly(
657                 FormDesigner.PROP_DESIGNER_SIZE,
658                 Dimension.class,
659                 bundle.getString("MSG_DesignerSize"), // NOI18N
660
bundle.getString("HINT_DesignerSize")) // NOI18N
661
{
662                 public void setValue(Object JavaDoc value) {
663                     if (!(value instanceof Dimension))
664                         throw new IllegalArgumentException JavaDoc();
665                     if (!getDefaultValue().equals(value))
666                         component.setAuxValue(FormDesigner.PROP_DESIGNER_SIZE, value);
667                     else if (component.getAuxValue(FormDesigner.PROP_DESIGNER_SIZE) != null) {
668                         component.getAuxValues().remove(FormDesigner.PROP_DESIGNER_SIZE);
669                     }
670                 }
671
672                 public Object JavaDoc getValue() {
673                     Object JavaDoc value = component.getAuxValue(FormDesigner.PROP_DESIGNER_SIZE);
674                     if (value == null)
675                         value = getDefaultValue();
676                     return value;
677                 }
678
679                 private Object JavaDoc getDefaultValue() {
680                     return new Dimension(400, 300);
681                 }
682             });
683         }
684
685         Node.Property[] props = new Node.Property[propList.size()];
686         propList.toArray(props);
687         return props;
688     }
689
690     public static PropertySupport createBeanClassNameProperty(final RADComponent component) {
691         final ResourceBundle bundle = FormUtils.getBundle();
692         
693         return new PropertySupport.ReadOnly(
694                 "beanClass", // NOI18N
695
String JavaDoc.class,
696                 bundle.getString("MSG_JC_BeanClass"), // NOI18N
697
bundle.getString("MSG_JC_BeanClassDesc")) // NOI18N
698
{
699         String JavaDoc invalid = null;
700                 public Object JavaDoc getValue() {
701                     if(!component.isValid()) {
702             if(invalid==null) {
703                 invalid = bundle.getString("CTL_LB_InvalidComponent"); // NOI18N
704
}
705                         return component.getMissingClassName() + ": [" + invalid + "]"; // NOI18N
706
}
707                     Class JavaDoc beanClass = component.getBeanClass();
708                     if(beanClass!=null) {
709                         return beanClass.toString();
710                     }
711                     return ""; // NOI18N
712
}
713
714                 public boolean canWrite() {
715                     return false;
716                 }
717                 
718                 public PropertyEditor getPropertyEditor() {
719                     return new PropertyEditorSupport(){};
720                 }
721             };
722     }
723     //
724
// Private Methods
725
//
726

727     private String JavaDoc getDefaultSerializedName(RADComponent component) {
728         return component.getFormModel().getName()
729             + "_" + component.getName(); // NOI18N
730
}
731
732     void regenerateInitComponents() {
733         if (!initialized || !canGenerate)
734             return;
735
736         // find indent engine to use or imitate
737
IndentEngine indentEngine = IndentEngine.find(
738                                         formEditorSupport.getDocument());
739
740         final SimpleSection initComponentsSection = formEditorSupport.getInitComponentSection();
741         int initComponentsOffset = initComponentsSection.getCaretPosition().getOffset();
742
743         // create Writer for writing the generated code in
744
StringWriter initCodeBuffer = new StringWriter(1024);
745         CodeWriter initCodeWriter;
746         if (formSettings.getUseIndentEngine()) { // use original indent engine
747
initCodeWriter = new CodeWriter(
748                     indentEngine.createWriter(formEditorSupport.getDocument(),
749                                               initComponentsOffset,
750                                               initCodeBuffer),
751                     true);
752         }
753         else {
754             initCodeWriter = new CodeWriter(initCodeBuffer, true);
755         }
756         // optimization - only properties need to go through CodeWriter
757
Writer writer = initCodeWriter.getWriter();
758
759         cleanup();
760
761         try {
762             boolean expandInitComponents = false;
763             boolean foldGeneratedCode = formSettings.getFoldGeneratedCode();
764             if (foldGeneratedCode) {
765                 String JavaDoc foldDescription = " " + FormUtils.getBundleString("MSG_GeneratedCode"); // NOI18N
766
javax.swing.JEditorPane JavaDoc editorPane = formEditorSupport.getEditorPane();
767                 if (editorPane != null) {
768                     FoldHierarchy foldHierarchy = FoldHierarchy.get(editorPane);
769                     Fold fold = FoldUtilities.findNearestFold(foldHierarchy, initComponentsOffset);
770                     expandInitComponents = (fold != null) && foldDescription.equals(fold.getDescription()) && !fold.isCollapsed();
771                 }
772                 writer.write("// <editor-fold defaultstate=\"collapsed\" desc=\""); // NOI18N
773
writer.write(foldDescription);
774                 writer.write("\">\n"); // NOI18N
775
}
776
777             writer.write("private void initComponents() {\n"); // NOI18N
778

779             addLocalVariables(writer);
780
781             emptyLineRequest++;
782             Collection<RADComponent> otherComps = formModel.getOtherComponents();
783             for (RADComponent metacomp : otherComps) {
784                 addCreateCode(metacomp, initCodeWriter);
785             }
786             RADComponent top = formModel.getTopRADComponent();
787             addCreateCode(top, initCodeWriter);
788
789             if (formModel.getSettings().getListenerGenerationStyle() == CEDL_INNERCLASS
790                 && anyEvents())
791             {
792                 emptyLineRequest++;
793                 addDispatchListenerDeclaration(writer);
794             }
795
796             for (RADComponent metacomp : otherComps) {
797                 addInitCode(metacomp, initCodeWriter, null);
798             }
799             addInitCode(top, initCodeWriter, null);
800
801             generateFormSizeCode(writer);
802
803             writer.write("}"); // no new line because of fold footer // NOI18N
804

805             int listenerCodeStyle = formModel.getSettings().getListenerGenerationStyle();
806             if ((listenerCodeStyle == CEDL_INNERCLASS
807                   || listenerCodeStyle == CEDL_MAINCLASS)
808                 && anyEvents())
809             {
810                 writer.write("\n\n"); // NOI18N
811
writer.write(getEventDispatchCodeComment());
812                 writer.write("\n"); // NOI18N
813

814                 generateDispatchListenerCode(writer);
815             }
816             else listenersInMainClass = null;
817
818             if (foldGeneratedCode) {
819                 writer.write("// </editor-fold>\n"); // NOI18N
820
}
821             else {
822                 writer.write("\n"); // NOI18N
823
}
824             writer.close();
825
826              // set the text into the guarded block
827
String JavaDoc newText = initCodeBuffer.toString();
828             if (!formSettings.getUseIndentEngine()) {
829                 newText = indentCode(newText, 1, indentEngine);
830             }
831             initComponentsSection.setText(newText);
832             
833             if (expandInitComponents) {
834                 FoldHierarchy foldHierarchy = FoldHierarchy.get(formEditorSupport.getEditorPane());
835                 Fold fold = FoldUtilities.findNearestFold(foldHierarchy, initComponentsOffset);
836                 if (fold != null) {
837                     foldHierarchy.expand(fold);
838                 }
839             }
840             clearUndo();
841         }
842         catch (IOException e) { // should not happen
843
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
844         }
845
846         cleanup();
847     }
848
849     private void cleanup() {
850         emptyLineCounter = 0;
851         emptyLineRequest = 0;
852         if (constructorProperties != null)
853             constructorProperties.clear();
854         if (parentDependentProperties != null)
855             parentDependentProperties.clear();
856         if (childrenDependentProperties != null)
857             childrenDependentProperties.clear();
858         formModel.getCodeStructure().clearExternalVariableNames();
859         bundleVariables = null;
860     }
861
862     private void regenerateVariables() {
863         if (!initialized || !canGenerate)
864             return;
865         
866         IndentEngine indentEngine = IndentEngine.find(
867                                         formEditorSupport.getDocument());
868
869         StringWriter variablesBuffer = new StringWriter(1024);
870         CodeWriter variablesWriter;
871         final SimpleSection variablesSection = formEditorSupport.getVariablesSection();
872         
873         if (formSettings.getUseIndentEngine()) {
874             variablesWriter = new CodeWriter(
875                     indentEngine.createWriter(formEditorSupport.getDocument(),
876                                               variablesSection.getCaretPosition().getOffset(),
877                                               variablesBuffer),
878                     false);
879         }
880         else {
881             variablesWriter = new CodeWriter(variablesBuffer, false);
882         }
883         
884         try {
885         variablesWriter.write(getVariablesHeaderComment());
886             variablesWriter.write("\n"); // NOI18N
887

888             addFieldVariables(variablesWriter);
889             
890             variablesWriter.write(getVariablesFooterComment());
891             variablesWriter.write("\n"); // NOI18N
892
variablesWriter.getWriter().close();
893
894             String JavaDoc newText = variablesBuffer.toString();
895             if (!formSettings.getUseIndentEngine())
896                 newText = indentCode(newText, 1, indentEngine);
897
898             variablesSection.setText(newText);
899             clearUndo();
900         }
901         catch (IOException e) { // should not happen
902
e.printStackTrace();
903         }
904     }
905     
906     private void addCreateCode(RADComponent comp, CodeWriter initCodeWriter)
907         throws IOException
908     {
909         if (comp == null)
910             return;
911
912         if (comp != formModel.getTopRADComponent()) {
913             generateComponentCreate(comp, initCodeWriter, true, null);
914         }
915         if (comp instanceof ComponentContainer) {
916             RADComponent[] children =((ComponentContainer)comp).getSubBeans();
917             for (int i = 0; i < children.length; i++) {
918                 addCreateCode(children[i], initCodeWriter);
919             }
920         }
921     }
922
923     private void addInitCode(RADComponent comp,
924                              CodeWriter initCodeWriter,
925                              CustomCodeData codeData)
926         throws IOException
927     {
928         if (comp == null)
929             return;
930
931         Writer writer = initCodeWriter.getWriter();
932
933         int counter0 = emptyLineCounter;
934         int request0 = emptyLineRequest;
935         emptyLineRequest++;
936
937         generateComponentProperties(comp, initCodeWriter, codeData);
938         generateComponentEvents(comp, initCodeWriter, codeData);
939
940         if (comp instanceof ComponentContainer) {
941             boolean freeDesign = RADVisualContainer.isFreeDesignContainer(comp);
942             ComponentContainer cont = (ComponentContainer) comp;
943             if (!freeDesign) // layout and pre-population code before sub-components
944
generateOldLayout(cont, initCodeWriter, codeData);
945
946             if (codeData == null) { // normal code generation
947
// generate code of sub-components
948
RADComponent[] subBeans = cont.getSubBeans();
949                 for (RADComponent subcomp : subBeans) {
950                     addInitCode(subcomp, initCodeWriter, null);
951                 }
952                 if (freeDesign) { // generate complete layout code
953
// GroupLayout setup code also adds all sub-components
954
RADVisualContainer visualCont = (RADVisualContainer) cont;
955                     emptyLineRequest++;
956                     generatePrePopulationCode(visualCont, writer, null);
957                     emptyLineRequest++;
958                     for (RADComponent subcomp : visualCont.getSubComponents()) {
959                         generateComponentAddPre(subcomp, writer, null);
960                     }
961                     emptyLineRequest++;
962                     generateFreeDesignLayoutCode(visualCont, initCodeWriter); // this always generates something
963
emptyLineRequest++;
964                     // some code for belonging to sub-components is generated
965
// after adding (a11y, after-all-set)
966
for (RADComponent subcomp : visualCont.getSubComponents()) { // excluding menu
967
generateComponentAddPost(subcomp, initCodeWriter, null);
968                         generateAccessibilityCode(subcomp, initCodeWriter, null);
969                         generateAfterAllSetCode(subcomp, writer, null);
970                     }
971                     emptyLineRequest++;
972                 }
973                 else if (subBeans.length > 0)
974                     emptyLineRequest++; // empty line after sub-components
975
}
976             else { // build code data for editing
977
if (RADVisualContainer.isFreeDesignContainer(comp)) {
978                     String JavaDoc substCode = "// " + FormUtils.getBundleString("CustomCode-SubstSub"); // NOI18N
979
codeData.addGuardedBlock(substCode);
980                     generatePrePopulationCode(comp, writer, codeData);
981                     substCode = "// " + FormUtils.getBundleString("CustomCode-SubstLayout"); // NOI18N
982
codeData.addGuardedBlock(substCode);
983                 }
984                 else { // with LM, the pre-layout code is elsewhere (before properties)
985
String JavaDoc substCode = "// " + FormUtils.getBundleString("CustomCode-SubstSubAndLayout"); // NOI18N
986
codeData.addGuardedBlock(substCode);
987                 }
988             }
989
990             int counter1 = emptyLineCounter;
991             emptyLineRequest++;
992             generatePostPopulationCode(comp, initCodeWriter, codeData);
993             if (emptyLineCounter == counter1)
994                 emptyLineRequest--; // no post-population code, don't force empty line
995
else
996                 emptyLineRequest++; // force empty line after post-population
997
}
998
999         if (emptyLineCounter == counter0)
1000            emptyLineRequest = request0; // no code was generated, don't force empty line
1001

1002        if (!RADVisualContainer.isInFreeDesign(comp)) { // in container with LM, or menu component
1003
// add to parent container (if not root itself)
1004
generateComponentAddCode(comp, initCodeWriter, codeData);
1005            boolean endingCode = false;
1006            if (generateAccessibilityCode(comp, initCodeWriter, codeData))
1007                endingCode = true;
1008            if (generateAfterAllSetCode(comp, writer, codeData))
1009                endingCode = true;
1010            if (endingCode)
1011                emptyLineRequest++; // force empty line after
1012
}
1013        else if (codeData != null) { // build code data for editing
1014
// In free design this is generated with parent container (see above).
1015
// But building code data is invoked only for the component itself,
1016
// not for its parent, so we must do it here.
1017
generateComponentAddPre(comp, writer, codeData);
1018            String JavaDoc substCode = "// " + FormUtils.getBundleString("CustomCode-SubstAdding"); // NOI18N
1019
codeData.addGuardedBlock(substCode);
1020            generateComponentAddPost(comp, initCodeWriter, codeData);
1021            generateAccessibilityCode(comp, initCodeWriter, codeData);
1022            generateAfterAllSetCode(comp, writer, codeData);
1023        }
1024    }
1025
1026    private void generateOldLayout(ComponentContainer cont,
1027                                   CodeWriter initCodeWriter,
1028                                   CustomCodeData codeData)
1029        throws IOException
1030    {
1031        RADVisualContainer visualCont = cont instanceof RADVisualContainer ?
1032                                        (RADVisualContainer) cont : null;
1033        LayoutSupportManager layoutSupport = visualCont != null ?
1034                                             visualCont.getLayoutSupport() : null;
1035
1036        if (layoutSupport != null) { // setLayout code for old layout support
1037
if (layoutSupport.isLayoutChanged()) {
1038                Iterator it = layoutSupport.getLayoutCode().getStatementsIterator();
1039                if (codeData == null && it.hasNext())
1040                    generateEmptyLineIfNeeded(initCodeWriter.getWriter());
1041                while (it.hasNext()) {
1042                    CodeStatement statement = (CodeStatement) it.next();
1043                    initCodeWriter.write(getStatementJavaString(statement, "")); // NOI18N
1044
initCodeWriter.write("\n"); // NOI18N
1045
}
1046
1047                if (codeData != null) { // build code data for editing
1048
String JavaDoc code = indentCode(initCodeWriter.extractString());
1049                    codeData.addGuardedBlock(code);
1050                }
1051            }
1052        }
1053
1054        generatePrePopulationCode((RADComponent)cont, initCodeWriter.getWriter(), codeData);
1055    }
1056
1057    private boolean generateAfterAllSetCode(RADComponent comp,
1058                                            Writer writer,
1059                                            CustomCodeData codeData)
1060        throws IOException
1061    {
1062        boolean generated = false;
1063
1064        String JavaDoc postCode = (String JavaDoc) comp.getAuxValue(AUX_ALL_SET_POST);
1065        if (codeData != null) { // build code data for editing
1066
codeData.addEditableBlock(postCode,
1067                                      (FormProperty) comp.getSyntheticProperty(PROP_ALL_SET_POST),
1068                                      0,
1069                                      FormUtils.getBundleString("CustomCode-AfterAllSet"), // NOI18N
1070
FormUtils.getBundleString("MSG_JC_PostPopulationCodeDesc")); // NOI18N
1071
}
1072        // normal code generation
1073
else if (postCode != null && !postCode.equals("")) { // NOI18N
1074
generateEmptyLineIfNeeded(writer);
1075            writer.write(postCode);
1076            if (!postCode.endsWith("\n")) // NOI18N
1077
writer.write("\n"); // NOI18N
1078
generated = true;
1079        }
1080
1081        return generated;
1082    }
1083
1084    private void generateComponentCreate(RADComponent comp,
1085                                         CodeWriter initCodeWriter,
1086                                         boolean insideMethod, // if this for initComponents
1087
CustomCodeData codeData)
1088        throws IOException
1089    {
1090        if (comp instanceof RADMenuItemComponent
1091            && ((RADMenuItemComponent)comp).getMenuItemType()
1092                   == RADMenuItemComponent.T_SEPARATOR)
1093        { // do not generate anything for AWT separator as it is not a real component
1094
return;
1095        }
1096
1097        // optimization - only properties need to go through CodeWriter
1098
Writer writer = initCodeWriter.getWriter();
1099
1100        CodeVariable var = comp.getCodeExpression().getVariable();
1101        int varType = var.getType();
1102        boolean localVariable = (varType & CodeVariable.SCOPE_MASK) == CodeVariable.LOCAL;
1103
1104        if (insideMethod) {
1105            if (isFinalFieldVariable(varType))
1106                return; // is generated in field variables (here we are in initComponents)
1107

1108            String JavaDoc preCode = (String JavaDoc) comp.getAuxValue(AUX_CREATE_CODE_PRE);
1109            if (codeData != null) { // build code data for editing
1110
codeData.addEditableBlock(preCode,
1111                                          (FormProperty) comp.getSyntheticProperty(PROP_CREATE_CODE_PRE),
1112                                          2, // preference index
1113
FormUtils.getBundleString("CustomCode-PreCreation"), // NOI18N
1114
FormUtils.getBundleString("MSG_JC_PreCreationCodeDesc")); // NOI18N
1115
}
1116            else if (preCode != null && !preCode.equals("")) { // NOI18N
1117
// normal generation of custom pre-creation code
1118
generateEmptyLineIfNeeded(writer);
1119                writer.write(preCode);
1120                if (!preCode.endsWith("\n")) // NOI18N
1121
writer.write("\n"); // NOI18N
1122
}
1123
1124            if (localVariable)
1125                generateDeclarationPre(comp, writer, codeData);
1126        }
1127
1128        String JavaDoc customCode = null; // for code data editing
1129
boolean codeCustomized = false; // for code data editing
1130

1131        Integer JavaDoc generationType = (Integer JavaDoc)comp.getAuxValue(AUX_CODE_GENERATION);
1132        if (comp.hasHiddenState() || VALUE_SERIALIZE.equals(generationType)) {
1133            // generate code for restoring serialized component [only works for field variables]
1134
if (!insideMethod)
1135                return;
1136
1137            String JavaDoc serializeTo = (String JavaDoc)comp.getAuxValue(AUX_SERIALIZE_TO);
1138            if (serializeTo == null) {
1139                serializeTo = getDefaultSerializedName(comp);
1140                comp.setAuxValue(AUX_SERIALIZE_TO, serializeTo);
1141            }
1142            if (codeData == null)
1143                generateEmptyLineIfNeeded(writer);
1144            writer.write("try {\n"); // NOI18N
1145
writer.write(comp.getName());
1146            writer.write(" =("); // NOI18N
1147
writer.write(getSourceClassName(comp.getBeanClass()));
1148            writer.write(")java.beans.Beans.instantiate(getClass().getClassLoader(), \""); // NOI18N
1149

1150            // write package name
1151
FileObject fo = formEditorSupport.getFormDataObject().getPrimaryFile();
1152            ClassPath cp = ClassPath.getClassPath(fo, ClassPath.SOURCE);
1153            String JavaDoc packageName = cp.getResourceName(fo.getParent());
1154            if (!"".equals(packageName)) { // NOI18N
1155
writer.write(packageName + "."); // NOI18N
1156
}
1157            writer.write(serializeTo);
1158            writer.write("\");\n"); // NOI18N
1159
writer.write("} catch (ClassNotFoundException e) {\n"); // NOI18N
1160
writer.write("e.printStackTrace();\n"); // NOI18N
1161
writer.write("} catch (java.io.IOException e) {\n"); // NOI18N
1162
writer.write("e.printStackTrace();\n"); // NOI18N
1163
writer.write("}\n"); // NOI18N
1164
}
1165        else { // generate standard component creation code
1166
if (codeData == null)
1167                generateEmptyLineIfNeeded(writer);
1168
1169            StringBuffer JavaDoc varBuf = new StringBuffer JavaDoc();
1170
1171            if (localVariable || isFinalFieldVariable(varType)) { // also generate declaration
1172
varBuf.append(Modifier.toString(
1173                                varType & CodeVariable.ALL_MODIF_MASK));
1174                varBuf.append(" "); // NOI18N
1175
varBuf.append(getSourceClassName(comp.getBeanClass()));
1176                varBuf.append(" "); // NOI18N
1177
}
1178
1179            varBuf.append(var.getName());
1180
1181            String JavaDoc customCreateCode = (String JavaDoc) comp.getAuxValue(AUX_CREATE_CODE_CUSTOM);
1182            if (customCreateCode != null && !customCreateCode.equals("")) { // NOI18N
1183
// there is a custom creation code provided
1184
if (codeData == null) { // normal code generation
1185
writer.write(varBuf.toString());
1186                    writer.write(" = "); // NOI18N
1187
writer.write(customCreateCode);
1188                    if (!customCreateCode.endsWith(";")) // NOI18N
1189
writer.write(";"); // NOI18N
1190
writer.write("\n"); // NOI18N
1191
}
1192                else { // build code data for editing
1193
if (customCreateCode.endsWith(";")) // NOI18N
1194
customCreateCode = customCreateCode.substring(0, customCreateCode.length()-1);
1195                    customCode = composeCustomCreationCode(varBuf, customCreateCode);
1196                    codeCustomized = true;
1197                }
1198            }
1199            if (customCreateCode == null || customCreateCode.equals("") || codeData != null) { // NOI18N
1200
// compose default creation code
1201
CreationDescriptor desc = CreationFactory.getDescriptor(
1202                                                              comp.getBeanClass());
1203                if (desc == null)
1204                    desc = new CreationDescriptor(comp.getBeanClass());
1205
1206                CreationDescriptor.Creator creator =
1207                    desc.findBestCreator(comp.getKnownBeanProperties(),
1208                                         CreationDescriptor.CHANGED_ONLY);
1209                if (creator == null) // known properties are not enough...
1210
creator = desc.findBestCreator(comp.getAllBeanProperties(),
1211                                               CreationDescriptor.CHANGED_ONLY);
1212
1213                Class JavaDoc[] exceptions = creator.getExceptionTypes();
1214                if (insideMethod && needTryCode(exceptions)) {
1215                    if (localVariable) {
1216                        writer.write(varBuf.toString());
1217                        writer.write(";\n"); // NOI18N
1218
}
1219                    writer.write("try {\n"); // NOI18N
1220
writer.write(var.getName());
1221                }
1222                else {
1223                    writer.write(varBuf.toString());
1224                    exceptions = null;
1225                }
1226
1227                writer.write(" = "); // NOI18N
1228

1229                String JavaDoc[] propNames = creator.getPropertyNames();
1230                FormProperty[] props;
1231                if (propNames.length > 0) {
1232                    if (constructorProperties == null)
1233                        constructorProperties = new HashMap();
1234
1235            java.util.List JavaDoc usedProperties = new ArrayList(propNames.length);
1236                    props = new FormProperty[propNames.length];
1237
1238                    for (int i=0; i < propNames.length; i++) {
1239                        FormProperty prop = comp.getBeanProperty(propNames[i]);
1240                        props[i] = prop;
1241            usedProperties.add(prop);
1242                    }
1243            constructorProperties.put(comp, usedProperties);
1244                }
1245                else props = RADComponent.NO_PROPERTIES;
1246
1247                String JavaDoc defaultCreationCode = creator.getJavaCreationCode(props, null);
1248                initCodeWriter.write(defaultCreationCode + ";\n"); // NOI18N
1249

1250                if (codeData != null && customCode == null) // get default custom code (without try/catch)
1251
customCode = composeCustomCreationCode(varBuf, defaultCreationCode);
1252
1253                if (exceptions != null)
1254                    generateCatchCode(exceptions, writer);
1255            }
1256        }
1257        if (codeData != null) {
1258            String JavaDoc defaultCode = indentCode(initCodeWriter.extractString());
1259            codeData.addGuardedBlock(defaultCode, customCode, CUSTOM_CODE_MARK, codeCustomized,
1260                                     (FormProperty) comp.getSyntheticProperty(PROP_CREATE_CODE_CUSTOM),
1261                                     FormUtils.getBundleString("CustomCode-Creation"), // NOI18N
1262
FormUtils.getBundleString("CustomCode-Creation_Hint")); // NOI18N
1263
}
1264
1265        if (insideMethod) {
1266            if (localVariable)
1267                generateDeclarationPost(comp, writer, codeData);
1268
1269            String JavaDoc postCode = (String JavaDoc) comp.getAuxValue(AUX_CREATE_CODE_POST);
1270            if (codeData != null) { // build code data for editing
1271
codeData.addEditableBlock(postCode,
1272                                          (FormProperty) comp.getSyntheticProperty(PROP_CREATE_CODE_POST),
1273                                          0, // preference index
1274
FormUtils.getBundleString("CustomCode-PostCreation"), // NOI18N
1275
FormUtils.getBundleString("MSG_JC_PostCreationCodeDesc")); // NOI18N
1276
}
1277            else if (postCode != null && !postCode.equals("")) { // NOI18N
1278
// normal generation of post-creation code
1279
writer.write(postCode);
1280                if (!postCode.endsWith("\n")) // NOI18N
1281
writer.write("\n"); // NOI18N
1282
}
1283        }
1284    }
1285
1286    // used only when building "code data" for editing
1287
private String JavaDoc composeCustomCreationCode(StringBuffer JavaDoc buf, String JavaDoc creationCode) {
1288        buf.append(" = "); // NOI18N
1289
buf.append(CUSTOM_CODE_MARK);
1290        buf.append(creationCode);
1291        buf.append(CUSTOM_CODE_MARK);
1292        buf.append(";\n"); // NOI18N
1293
return indentCode(buf.toString());
1294    }
1295
1296    private void generateComponentProperties(RADComponent comp,
1297                                             CodeWriter initCodeWriter,
1298                                             CustomCodeData codeData)
1299        throws IOException
1300    {
1301        Writer writer = initCodeWriter.getWriter();
1302
1303        String JavaDoc preCode = (String JavaDoc) comp.getAuxValue(AUX_INIT_CODE_PRE);
1304        if (codeData != null) { // build code data for editing
1305
codeData.addEditableBlock(preCode,
1306                                      (FormProperty) comp.getSyntheticProperty(PROP_INIT_CODE_PRE),
1307                                      10, // preference index
1308
FormUtils.getBundleString("CustomCode-PreInit"), // NOI18N
1309
FormUtils.getBundleString("MSG_JC_PreInitCodeDesc")); // NOI18N
1310
}
1311        else if (preCode != null && !preCode.equals("")) { // NOI18N
1312
generateEmptyLineIfNeeded(writer);
1313            writer.write(preCode);
1314            if (!preCode.endsWith("\n")) // NOI18N
1315
writer.write("\n"); // NOI18N
1316
}
1317
1318        Object JavaDoc genType = comp.getAuxValue(AUX_CODE_GENERATION);
1319        if (!comp.hasHiddenState()
1320                && (genType == null || VALUE_GENERATE_CODE.equals(genType)))
1321        { // not serialized, generate properties
1322
java.util.List JavaDoc usedProperties = constructorProperties != null ? (java.util.List JavaDoc)constructorProperties.get(comp) : null;
1323            Iterator it = comp.getBeanPropertiesIterator(new PropertiesFilter(usedProperties), false);
1324            while (it.hasNext()) {
1325                FormProperty prop = (FormProperty) it.next();
1326
1327                java.util.List JavaDoc<FormProperty> depPropList = null;
1328                if (FormUtils.isMarkedParentDependentProperty(prop)) {
1329                    // needs to be generated after the component is added to the parent container
1330
if (parentDependentProperties != null)
1331                        depPropList = parentDependentProperties.get(comp);
1332                    else {
1333                        parentDependentProperties = new HashMap();
1334                        depPropList = null;
1335                    }
1336                    if (depPropList == null) {
1337                        depPropList = new LinkedList();
1338                        parentDependentProperties.put(comp, depPropList);
1339                    }
1340                    depPropList.add(prop);
1341                }
1342                if (FormUtils.isMarkedChildrenDependentProperty(prop)) {
1343                    // needs to be added after all sub-components are added to this container
1344
if (childrenDependentProperties != null)
1345                        depPropList = childrenDependentProperties.get(comp);
1346                    else {
1347                        childrenDependentProperties = new HashMap();
1348                        depPropList = null;
1349                    }
1350                    if (depPropList == null) {
1351                        depPropList = new LinkedList();
1352                        childrenDependentProperties.put(comp, depPropList);
1353                    }
1354                    depPropList.add(prop);
1355                }
1356                
1357                if (depPropList == null) { // independent property, generate here directly
1358
generateProperty(prop, comp, null, initCodeWriter, codeData);
1359                }
1360            }
1361        }
1362
1363        String JavaDoc postCode = (String JavaDoc) comp.getAuxValue(AUX_INIT_CODE_POST);
1364        if (codeData != null) { // build code data for editing
1365
codeData.addEditableBlock(postCode,
1366                                      (FormProperty) comp.getSyntheticProperty(PROP_INIT_CODE_POST),
1367                                      7, // preference index
1368
FormUtils.getBundleString("CustomCode-PostInit"), // NOI18N
1369
FormUtils.getBundleString("MSG_JC_PostInitCodeDesc")); // NOI18N
1370
}
1371        else if (postCode != null && !postCode.equals("")) { // NOI18N
1372
generateEmptyLineIfNeeded(writer);
1373            writer.write(postCode);
1374            if (!postCode.endsWith("\n")) // NOI18N
1375
writer.write("\n"); // NOI18N
1376
}
1377    }
1378
1379    private boolean generateAccessibilityCode(RADComponent comp,
1380                                              CodeWriter initCodeWriter,
1381                                              CustomCodeData codeData)
1382        throws IOException
1383    {
1384        boolean generated = false;
1385        Object JavaDoc genType = comp.getAuxValue(AUX_CODE_GENERATION);
1386        if (!comp.hasHiddenState()
1387                && (genType == null || VALUE_GENERATE_CODE.equals(genType)))
1388        { // not serialized
1389
FormProperty[] props;
1390            if (comp instanceof RADVisualComponent)
1391                props = ((RADVisualComponent)comp).getAccessibilityProperties();
1392            else if (comp instanceof RADMenuItemComponent)
1393                props = ((RADMenuItemComponent)comp).getAccessibilityProperties();
1394            else return false;
1395
1396            for (int i=0; i < props.length; i++) {
1397                boolean gen = generateProperty(props[i], comp, null, initCodeWriter, codeData);
1398                if (gen)
1399                    generated = true;
1400            }
1401        }
1402        return generated;
1403    }
1404
1405    private void generateComponentAddCode(RADComponent comp,
1406                                          CodeWriter initCodeWriter,
1407                                          CustomCodeData codeData)
1408        throws IOException
1409    {
1410        RADComponent parent = comp.getParentComponent();
1411        if (parent == null)
1412            return;
1413
1414        // optimization - only properties need to go through CodeWriter
1415
Writer writer = initCodeWriter.getWriter();
1416
1417        generateComponentAddPre(comp, initCodeWriter.getWriter(), codeData);
1418
1419        if (comp instanceof RADVisualComponent) {
1420            // adding visual component to container with old layout support
1421
LayoutSupportManager laysup = ((RADVisualComponent)comp).getParentLayoutSupport();
1422            CodeGroup componentCode = laysup != null ?
1423                laysup.getComponentCode((RADVisualComponent)comp) : null;
1424            if (componentCode != null) {
1425                Iterator it = componentCode.getStatementsIterator();
1426                if (codeData == null && it.hasNext())
1427                    generateEmptyLineIfNeeded(writer);
1428                while (it.hasNext()) {
1429                    CodeStatement statement = (CodeStatement) it.next();
1430                    initCodeWriter.write(getStatementJavaString(statement, "")); // NOI18N
1431
initCodeWriter.write("\n"); // NOI18N
1432
}
1433            }
1434        }
1435        else if (comp instanceof RADMenuItemComponent) {
1436            RADMenuItemComponent menuComp = (RADMenuItemComponent) comp;
1437            if (parent instanceof RADVisualContainer) { // menu bar to visual container
1438
String JavaDoc menuCode;
1439                Class JavaDoc contClass = parent.getBeanClass();
1440
1441                if (menuComp.getMenuItemType() == RADMenuItemComponent.T_JMENUBAR
1442                        && javax.swing.RootPaneContainer JavaDoc.class.isAssignableFrom(contClass))
1443                    menuCode = "setJMenuBar"; // NOI18N
1444
else if (menuComp.getMenuItemType() == RADMenuItemComponent.T_MENUBAR
1445                         && java.awt.Frame JavaDoc.class.isAssignableFrom(contClass))
1446                    menuCode = "setMenuBar"; // NOI18N
1447
else
1448                    menuCode = null;
1449
1450                if (menuCode != null) {
1451                    if (codeData == null)
1452                        generateEmptyLineIfNeeded(writer);
1453                    writer.write(getComponentInvokeString(parent, true));
1454                    writer.write(menuCode);
1455                    writer.write("("); // NOI18N
1456
writer.write(getComponentParameterString(menuComp, true));
1457                    writer.write(");\n"); // NOI18N
1458
}
1459            }
1460            else { // menu component to another component
1461
assert parent instanceof RADMenuComponent;
1462                if (codeData == null)
1463                    generateEmptyLineIfNeeded(writer);
1464                if (menuComp.getMenuItemType() == RADMenuItemComponent.T_SEPARATOR) {
1465                    // treat AWT Separator specially - it is not a regular component
1466
writer.write(getComponentInvokeString(parent, true));
1467                    writer.write("addSeparator();"); // NOI18N
1468
}
1469                else {
1470                    writer.write(getComponentInvokeString(parent, true));
1471                    writer.write("add("); // NOI18N
1472
writer.write(getComponentParameterString(comp, true));
1473                    writer.write(");\n"); // NOI18N
1474
}
1475            }
1476        }
1477        // no other type of adding supported [assert false ?]
1478

1479        if (codeData != null) { // build code data for editing
1480
String JavaDoc code = initCodeWriter.extractString();
1481            if (code != null && !code.equals("")) // NOI18N
1482
codeData.addGuardedBlock(indentCode(code));
1483        }
1484
1485        generateComponentAddPost(comp, initCodeWriter, codeData);
1486    }
1487
1488    private void generateComponentAddPre(RADComponent comp,
1489                                         Writer writer,
1490                                         CustomCodeData codeData)
1491        throws IOException
1492    {
1493        String JavaDoc preCode = (String JavaDoc) comp.getAuxValue(AUX_ADDING_PRE);
1494        if (codeData != null) { // build code data for editing
1495
codeData.addEditableBlock(preCode,
1496                                      (FormProperty) comp.getSyntheticProperty(PROP_ADDING_PRE),
1497                                      0, // preference index
1498
FormUtils.getBundleString("CustomCode-PreAdding"), // NOI18N
1499
FormUtils.getBundleString("MSG_JC_PreAddCodeDesc")); // NOI18N
1500
}
1501        else if (preCode != null && !preCode.equals("")) { // NOI18N
1502
generateEmptyLineIfNeeded(writer);
1503            writer.write(preCode);
1504            if (!preCode.endsWith("\n")) // NOI18N
1505
writer.write("\n"); // NOI18N
1506
}
1507    }
1508
1509    private void generateComponentAddPost(RADComponent comp,
1510                                          CodeWriter initCodeWriter,
1511                                          CustomCodeData codeData)
1512        throws IOException
1513    {
1514        // some known (i.e. hardcoded) properties need to be set after
1515
// the component is added to the parent container
1516
java.util.List JavaDoc<FormProperty> postProps;
1517        if (parentDependentProperties != null
1518            && (postProps = parentDependentProperties.get(comp)) != null)
1519        {
1520            for (FormProperty prop : postProps) {
1521                generateProperty(prop, comp, null, initCodeWriter, codeData);
1522            }
1523        }
1524
1525        String JavaDoc postCode = (String JavaDoc) comp.getAuxValue(AUX_ADDING_POST);
1526        if (codeData != null) { // build code data for editing
1527
codeData.addEditableBlock(postCode,
1528                                      (FormProperty) comp.getSyntheticProperty(PROP_ADDING_POST),
1529                                      0, // preference index
1530
FormUtils.getBundleString("CustomCode-PostAdding"), // NOI18N
1531
FormUtils.getBundleString("MSG_JC_PostAddCodeDesc")); // NOI18N
1532
}
1533        else if (postCode != null && !postCode.equals("")) { // NOI18N
1534
generateEmptyLineIfNeeded(initCodeWriter.getWriter());
1535            initCodeWriter.getWriter().write(postCode);
1536            if (!postCode.endsWith("\n")) // NOI18N
1537
initCodeWriter.getWriter().write("\n"); // NOI18N
1538
}
1539    }
1540
1541    private void generateFreeDesignLayoutCode(RADVisualContainer cont, CodeWriter initCodeWriter)
1542        throws IOException
1543    {
1544        LayoutComponent layoutCont = formModel.getLayoutModel().getLayoutComponent(cont.getId());
1545        if (layoutCont == null)
1546            return;
1547
1548        // optimization - only properties need to go through CodeWriter
1549
Writer writer = initCodeWriter.getWriter();
1550
1551        RADVisualComponent[] comps = cont.getSubComponents();
1552
1553        // layout code and adding sub-components
1554
generateEmptyLineIfNeeded(writer);
1555        SwingLayoutCodeGenerator.ComponentInfo[] infos = new SwingLayoutCodeGenerator.ComponentInfo[comps.length];
1556        for (int i=0; i<comps.length; i++) {
1557            RADVisualComponent subComp = comps[i];
1558            SwingLayoutCodeGenerator.ComponentInfo info = new SwingLayoutCodeGenerator.ComponentInfo();
1559            info.id = subComp.getId();
1560            info.variableName = getExpressionJavaString(subComp.getCodeExpression(), ""); // NOI18N
1561
info.clazz = subComp.getBeanClass();
1562            Node.Property minProp = subComp.getPropertyByName("minimumSize"); // NOI18N
1563
Node.Property prefProp = subComp.getPropertyByName("preferredSize"); // NOI18N
1564
Node.Property maxProp = subComp.getPropertyByName("maximumSize"); // NOI18N
1565
info.sizingChanged = !(((minProp == null) || minProp.isDefaultValue())
1566                && ((prefProp == null) || prefProp.isDefaultValue())
1567                && ((maxProp == null) || maxProp.isDefaultValue()));
1568            info.minSize = ((Component)subComp.getBeanInstance()).getMinimumSize();
1569            infos[i] = info;
1570        }
1571        CodeExpression contExpr = LayoutSupportManager.containerDelegateCodeExpression(
1572                                    cont, formModel.getCodeStructure());
1573        String JavaDoc contExprStr = getExpressionJavaString(contExpr, ""); // NOI18N
1574
CodeVariable contVar = cont.getCodeExpression().getVariable();
1575        String JavaDoc contVarName = (contVar == null) ? null : contVar.getName();
1576        SwingLayoutCodeGenerator swingGenerator = getSwingGenerator();
1577        swingGenerator.generateContainerLayout(
1578            writer,
1579            layoutCont,
1580            contExprStr,
1581            contVarName,
1582            infos,
1583            formModel.getSettings().getLayoutCodeTarget() == LAYOUT_CODE_LIBRARY);
1584    }
1585
1586    private SwingLayoutCodeGenerator getSwingGenerator() {
1587        if (swingGenerator == null) {
1588            swingGenerator = new SwingLayoutCodeGenerator(formModel.getLayoutModel());
1589        }
1590        return swingGenerator;
1591    }
1592
1593    private void generatePrePopulationCode(RADComponent cont,
1594                                           Writer writer,
1595                                           CustomCodeData codeData)
1596        throws IOException
1597    {
1598        String JavaDoc preCode = (String JavaDoc) cont.getAuxValue(AUX_LAYOUT_PRE);
1599        if (codeData != null) { // build code data for editing
1600
codeData.addEditableBlock(preCode,
1601                                      (FormProperty) cont.getSyntheticProperty(PROP_LAYOUT_PRE),
1602                                      2, // preference index
1603
FormUtils.getBundleString("CustomCode-PrePopulation"), // NOI18N
1604
FormUtils.getBundleString("MSG_JC_PrePopulationCodeDesc")); // NOI18N
1605
}
1606        else if (preCode != null && !preCode.equals("")) { // NOI18N
1607
generateEmptyLineIfNeeded(writer);
1608            writer.write(preCode);
1609            if (!preCode.endsWith("\n")) // NOI18N
1610
writer.write("\n"); // NOI18N
1611
}
1612    }
1613
1614    private void generatePostPopulationCode(RADComponent cont,
1615                                            CodeWriter initCodeWriter,
1616                                            CustomCodeData codeData)
1617        throws IOException
1618    {
1619        // some known (i.e. hardcoded) container properties need to be set after
1620
// all sub-components are added
1621
java.util.List JavaDoc<FormProperty> postProps;
1622        if (childrenDependentProperties != null
1623            && (postProps = childrenDependentProperties.get(cont)) != null)
1624        {
1625            for (FormProperty prop : postProps) {
1626                generateProperty(prop, cont, null, initCodeWriter, codeData);
1627            }
1628        }
1629
1630        // custom post-layout (post-population) code
1631
String JavaDoc postCode = (String JavaDoc) cont.getAuxValue(AUX_LAYOUT_POST);
1632        if (codeData != null) { // build code data for editing
1633
codeData.addEditableBlock(postCode,
1634                                      (FormProperty) cont.getSyntheticProperty(PROP_LAYOUT_POST),
1635                                      4, // preference index
1636
FormUtils.getBundleString("CustomCode-PostPopulation"), // NOI18N
1637
FormUtils.getBundleString("MSG_JC_PostPopulationCodeDesc")); // NOI18N
1638
}
1639        else if (postCode != null && !postCode.equals("")) { // NOI18N
1640
generateEmptyLineIfNeeded(initCodeWriter.getWriter());
1641            initCodeWriter.getWriter().write(postCode);
1642            if (!postCode.endsWith("\n")) // NOI18N
1643
initCodeWriter.getWriter().write("\n"); // NOI18N
1644
}
1645    }
1646
1647    private void generateFormSizeCode(Writer writer) throws IOException {
1648        if (formModel.getTopRADComponent() instanceof RADVisualFormContainer) {
1649            RADVisualFormContainer visualForm =
1650                (RADVisualFormContainer) formModel.getTopRADComponent();
1651
1652            // generate size code according to form size policy
1653
int formPolicy = visualForm.getFormSizePolicy();
1654            boolean genSize = visualForm.getGenerateSize();
1655            boolean genPosition = visualForm.getGeneratePosition();
1656            boolean genCenter = visualForm.getGenerateCenter();
1657            Dimension formSize = visualForm.getFormSize();
1658            Point formPosition = visualForm.getFormPosition();
1659
1660            String JavaDoc sizeText = ""; // NOI18N
1661

1662            if (formPolicy == RADVisualFormContainer.GEN_PACK)
1663                sizeText = "pack();\n"; // NOI18N
1664
else if (formPolicy == RADVisualFormContainer.GEN_BOUNDS) {
1665                if (genCenter) {
1666                    StringBuffer JavaDoc sizeBuffer = new StringBuffer JavaDoc();
1667                    if (genSize) {
1668// sizeBuffer.append("pack();\n"); // NOI18N
1669
sizeBuffer.append("java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();\n"); // NOI18N
1670
sizeBuffer.append("setBounds((screenSize.width-"+formSize.width+")/2, (screenSize.height-"+formSize.height+")/2, "+formSize.width + ", " + formSize.height + ");\n"); // NOI18N
1671
// sizeBuffer.append("setSize(new java.awt.Dimension("+formSize.width + ", " + formSize.height + "));\n"); // NOI18N
1672
// sizeBuffer.append("setLocation((screenSize.width-"+formSize.width+")/2,(screenSize.height-"+formSize.height+")/2);\n"); // NOI18N
1673
}
1674                    else {
1675                        sizeBuffer.append("pack();\n"); // NOI18N
1676
sizeBuffer.append("java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();\n"); // NOI18N
1677
sizeBuffer.append("java.awt.Dimension dialogSize = getSize();\n"); // NOI18N
1678
sizeBuffer.append("setLocation((screenSize.width-dialogSize.width)/2,(screenSize.height-dialogSize.height)/2);\n"); // NOI18N
1679
}
1680                    sizeText = sizeBuffer.toString();
1681                }
1682                else if (genPosition && genSize) // both size and position
1683
sizeText = "setBounds("+formPosition.x + ", " // NOI18N
1684
+ formPosition.y +", " // NOI18N
1685
+ formSize.width + ", " // NOI18N
1686
+ formSize.height + ");\n"; // NOI18N
1687
else if (genPosition) // position only
1688
sizeText = "setLocation(new java.awt.Point(" // NOI18N
1689
+ formPosition.x + ", " // NOI18N
1690
+ formPosition.y + "));\n"; // NOI18N
1691
else if (genSize) // size only
1692
sizeText = "setSize(new java.awt.Dimension(" // NOI18N
1693
+ formSize.width + ", " // NOI18N
1694
+ formSize.height + "));\n"; // NOI18N
1695
}
1696
1697            if (!sizeText.equals("")) { // NOI18N
1698
emptyLineRequest++;
1699                generateEmptyLineIfNeeded(writer);
1700                writer.write(sizeText);
1701            }
1702        }
1703    }
1704
1705    private boolean generateProperty(FormProperty prop,
1706                                     RADComponent comp,
1707                                     String JavaDoc setterVariable,
1708                                     CodeWriter initCodeWriter,
1709                                     CustomCodeData codeData)
1710        throws IOException
1711    {
1712        String JavaDoc preCode = prop.getPreCode();
1713        String JavaDoc postCode = prop.getPostCode();
1714        boolean valueSet = prop.isChanged();
1715
1716        if ((preCode == null || preCode.equals("")) // NOI18N
1717
&& (postCode == null || postCode.equals("")) // NOI18N
1718
&& !valueSet)
1719            return false; // nothing set
1720

1721        if (codeData == null)
1722            generateEmptyLineIfNeeded(initCodeWriter.getWriter());
1723
1724        // 1. pre-initialization code
1725
if (codeData != null) { // build code data for editing
1726
String JavaDoc name;
1727            if (prop.getWriteMethod() != null)
1728                name = prop.getWriteMethod().getName();
1729            else {
1730                name = prop.getName();
1731                if (name.indexOf('.') >= 0)
1732                    name = name.substring(name.lastIndexOf('.')+1);
1733            }
1734            codeData.addEditableBlock(
1735                    preCode, prop, 0, // preference index
1736
FormUtils.getFormattedBundleString("CustomCode-PreProperty_Format", // NOI18N
1737
new Object JavaDoc[] { name }),
1738                    FormUtils.getBundleString("CustomCode-PreProperty_Hint"), // NOI18N
1739
true, false);
1740        }
1741        else if (preCode != null && !preCode.equals("")) { // NOI18N
1742
initCodeWriter.getWriter().write(preCode);
1743            if (!preCode.endsWith("\n")) // NOI18N
1744
initCodeWriter.getWriter().write("\n"); // NOI18N
1745
}
1746
1747        // 2. property setter code
1748
if (valueSet) {
1749        if (setterVariable == null)
1750        setterVariable = getComponentInvokeString(comp, true);
1751
1752            generatePropertySetter(prop, comp, setterVariable, initCodeWriter, codeData);
1753
1754            if (codeData != null) { // build code data for editing
1755
String JavaDoc customCode = indentCode(initCodeWriter.extractString());
1756                String JavaDoc defaultCode;
1757                boolean codeCustomized = isPropertyWithCustomCode(prop);
1758                if (codeCustomized)
1759                    defaultCode = "// " + FormUtils.getBundleString("CustomCode-SubstNoValue"); // NOI18N
1760
else {
1761                    generatePropertySetter(prop, comp, setterVariable, initCodeWriter, null);
1762                    defaultCode = indentCode(initCodeWriter.extractString());
1763                }
1764                codeData.addGuardedBlock(defaultCode, customCode, CUSTOM_CODE_MARK, codeCustomized,
1765                                         prop,
1766                                         FormUtils.getBundleString("CustomCode-Property"), // NOI18N
1767
FormUtils.getBundleString("CustomCode-Property_Hint")); // NOI18N
1768
}
1769        }
1770
1771        // 3. post-initialization code
1772
if (codeData != null) { // build code data for editing
1773
String JavaDoc name;
1774            if (prop.getWriteMethod() != null)
1775                name = prop.getWriteMethod().getName();
1776            else {
1777                name = prop.getName();
1778                if (name.indexOf('.') >= 0)
1779                    name = name.substring(name.lastIndexOf('.')+1);
1780            }
1781            codeData.addEditableBlock(
1782                    postCode, prop, 0, // preference index
1783
FormUtils.getFormattedBundleString("CustomCode-PostProperty_Format", // NOI18N
1784
new Object JavaDoc[] { name }),
1785                    FormUtils.getBundleString("CustomCode-PostProperty_Hint"), // NOI18N
1786
false, true);
1787        }
1788        else if (postCode != null && !postCode.equals("")) { // NOI18N
1789
initCodeWriter.getWriter().write(postCode);
1790            if (!postCode.endsWith("\n")) // NOI18N
1791
initCodeWriter.getWriter().write("\n"); // NOI18N
1792
}
1793
1794        return true;
1795    }
1796
1797    static boolean isPropertyWithCustomCode(Node.Property prop) {
1798        try {
1799            Object JavaDoc value = prop.getValue();
1800            return value instanceof RADConnectionPropertyEditor.RADConnectionDesignValue
1801                   && ((RADConnectionPropertyEditor.RADConnectionDesignValue)value).getType()
1802                        == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_CODE;
1803        }
1804        catch (Exception JavaDoc ex) {} // should not happen
1805
return false;
1806    }
1807
1808    private void generatePropertySetter(FormProperty prop,
1809                                        RADComponent comp,
1810                                        String JavaDoc setterVariable,
1811                                        CodeWriter initCodeWriter,
1812                                        CustomCodeData codeData)
1813        throws IOException
1814    {
1815        Object JavaDoc value = null;
1816        try {
1817            value = prop.getValue();
1818        }
1819        catch (Exception JavaDoc ex) { // should not happen
1820
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
1821            return;
1822        }
1823
1824        if( prop.getCurrentEditor() instanceof BeanPropertyEditor && value != null) {
1825            generatePropertyBeanSetterCode(prop, value, setterVariable, initCodeWriter, codeData);
1826        }
1827        else {
1828            String JavaDoc propValueCode = prop.getJavaInitializationString();
1829            if (codeData != null) // building code data for editing
1830
propValueCode = CUSTOM_CODE_MARK + propValueCode + CUSTOM_CODE_MARK;
1831            String JavaDoc javaStr = null;
1832
1833            if ((javaStr = prop.getWholeSetterCode(propValueCode)) != null) { // button group property
1834
initCodeWriter.write(javaStr);
1835                if (!javaStr.endsWith("\n")) // NOI18N
1836
initCodeWriter.write("\n"); // NOI18N
1837
}
1838            // Mnemonics support - start -
1839
else if (comp != null
1840                     && "text".equals(prop.getName()) // NOI18N
1841
&& canUseMnemonics(comp) && isUsingMnemonics(comp))
1842            {
1843                if (propValueCode != null) {
1844                    initCodeWriter.write("org.openide.awt.Mnemonics.setLocalizedText(" // NOI18N
1845
+ comp.getName() + ", " + propValueCode + ");\n"); // NOI18N
1846
}
1847            }
1848            // Mnemonics support - end -
1849
else if ((javaStr = prop.getPartialSetterCode(propValueCode)) != null) {
1850                // this is a normal property
1851
generateSimpleSetterCode(prop, javaStr, setterVariable, initCodeWriter);
1852            }
1853        }
1854    }
1855
1856    private void generatePropertyBeanSetterCode(FormProperty prop,
1857                        Object JavaDoc value,
1858                        String JavaDoc setterVariable,
1859                        CodeWriter initCodeWriter,
1860                                                CustomCodeData codeData)
1861    throws IOException
1862    {
1863    
1864    FormProperty[] properties = null;
1865    Class JavaDoc propertyType = null;
1866    Object JavaDoc realValue = prop.getRealValue(value);
1867    propertyType = realValue.getClass();
1868                
1869    prop.getCurrentEditor().setValue(value);
1870    BeanPropertyEditor beanPropertyEditor = (BeanPropertyEditor) prop.getCurrentEditor();
1871    properties = (FormProperty[]) beanPropertyEditor.getProperties();
1872        if ((properties == null) || (properties.length == 0)) return;
1873
1874    CreationDescriptor.Creator creator = getPropertyCreator(propertyType, properties);
1875    java.util.List JavaDoc creatorProperties = getCreatorProperties(creator, properties);
1876                                                            
1877    java.util.List JavaDoc remainingProperties = new ArrayList();
1878    if(properties !=null) {
1879        for (int i = 0; i < properties.length; i++) {
1880        if( properties[i].isChanged() &&
1881                !creatorProperties.contains(properties[i]) )
1882        {
1883            remainingProperties.add(properties[i]);
1884        }
1885        }
1886    }
1887
1888    String JavaDoc propertyInitializationString =
1889        creator.getJavaCreationCode(
1890            (FormProperty[])creatorProperties.toArray(new FormProperty[creatorProperties.size()]), prop.getValueType());
1891        if (codeData != null)
1892            propertyInitializationString = CUSTOM_CODE_MARK + propertyInitializationString + CUSTOM_CODE_MARK;
1893
1894    if(remainingProperties.size() == 0) {
1895        generateSimpleSetterCode(prop,
1896                     prop.getPartialSetterCode(propertyInitializationString),
1897                     setterVariable,
1898                     initCodeWriter);
1899    } else if(remainingProperties.size() > 0) {
1900        generateWholePropertyInitialization(prop, propertyType, setterVariable,
1901                 propertyInitializationString, remainingProperties, initCodeWriter);
1902    }
1903    }
1904
1905    private java.util.List JavaDoc getCreatorProperties(CreationDescriptor.Creator creator, FormProperty[] properties) {
1906    String JavaDoc[] propNames = creator.getPropertyNames();
1907    java.util.List JavaDoc creatorProperties;
1908    if (propNames.length > 0) {
1909        creatorProperties = new ArrayList(propNames.length);
1910        for (int i=0; i < propNames.length; i++) {
1911        for (int j = 0; j < properties.length; j++) {
1912            if(properties[j].getName().equals(propNames[i])) {
1913            creatorProperties.add(properties[j]);
1914            break;
1915            }
1916        }
1917        }
1918    } else {
1919        creatorProperties = new ArrayList(0);
1920    }
1921    return creatorProperties;
1922    }
1923    
1924    private CreationDescriptor.Creator getPropertyCreator(Class JavaDoc clazz, FormProperty[] properties) {
1925    CreationDescriptor creationDesc = CreationFactory.getDescriptor(clazz);
1926    return creationDesc.findBestCreator(properties,
1927                        // XXX CHANGED_ONLY ???
1928
CreationDescriptor.CHANGED_ONLY | CreationDescriptor.PLACE_ALL);
1929    }
1930    
1931    private void generateWholePropertyInitialization(FormProperty prop,
1932                          Class JavaDoc propertyType,
1933                          String JavaDoc setterVariable,
1934                          String JavaDoc propertyInitializationString,
1935                          java.util.List JavaDoc remainingProperties,
1936                          CodeWriter initCodeWriter)
1937    throws IOException
1938    {
1939    String JavaDoc variableName = formModel.getCodeStructure().getExternalVariableName(propertyType, null, true);
1940
1941    String JavaDoc javaStr = propertyType.getName() + " " + variableName + " = " + propertyInitializationString; // NOI18N
1942
initCodeWriter.write(javaStr);
1943    initCodeWriter.write(";\n"); // NOI18N
1944

1945    for (Iterator it = remainingProperties.iterator(); it.hasNext();) {
1946        generateProperty((FormProperty) it.next(), null, variableName + ".", initCodeWriter, null); // NOI18N
1947
}
1948
1949    generateSimpleSetterCode(prop,
1950                 prop.getWriteMethod().getName() + "(" + variableName + ")", // NOI18N
1951
setterVariable,
1952                 initCodeWriter);
1953    }
1954    
1955    private void generateSimpleSetterCode(FormProperty prop,
1956                          String JavaDoc partialSetterCode,
1957                                      String JavaDoc setterVariable,
1958                          CodeWriter initCodeWriter)
1959    throws IOException
1960    {
1961
1962    // if the setter throws checked exceptions,
1963
// we must generate try/catch block around it.
1964
Class JavaDoc[] exceptions = null;
1965    Method writeMethod = prop.getWriteMethod();
1966    if (writeMethod != null) {
1967        exceptions = writeMethod.getExceptionTypes();
1968        if (needTryCode(exceptions))
1969        initCodeWriter.write("try {\n"); // NOI18N
1970
else
1971        exceptions = null;
1972    }
1973
1974    initCodeWriter.write(setterVariable + partialSetterCode + ";\n"); // NOI18N
1975

1976    // add the catch code if needed
1977
if (exceptions != null)
1978        generateCatchCode(exceptions, initCodeWriter.getWriter());
1979    }
1980
1981    // generates code for handling events of one component
1982
// (all component.addXXXListener() calls)
1983
private void generateComponentEvents(RADComponent component,
1984                                         CodeWriter initCodeWriter,
1985                                         CustomCodeData codeData)
1986        throws IOException
1987    {
1988        Writer writer = initCodeWriter.getWriter();
1989
1990        EventSetDescriptor lastEventSetDesc = null;
1991        java.util.List JavaDoc listenerEvents = null;
1992
1993        // we must deal somehow with the fact that for some (pathological)
1994
// events only anonymous innerclass listener can be generated
1995
// (CEDL cannot be used)
1996
int defaultMode = formModel.getSettings().getListenerGenerationStyle();
1997        int mode = defaultMode;
1998        boolean mixedMode = false;
1999
2000        Event[] events = component.getKnownEvents();
2001        for (int i=0; i < events.length; i++) {
2002            Event event = events[i];
2003            if (!event.hasEventHandlers())
2004                continue;
2005
2006            EventSetDescriptor eventSetDesc = event.getEventSetDescriptor();
2007            if (eventSetDesc != lastEventSetDesc) {
2008                if (lastEventSetDesc != null) {
2009                    // new listener encountered, generate the previous one
2010
if (codeData == null)
2011                        generateEmptyLineIfNeeded(writer);
2012                    generateListenerAddCode(component, lastEventSetDesc, listenerEvents, mode, writer);
2013                    if (mixedMode)
2014                        generateListenerAddCode(component, lastEventSetDesc, listenerEvents, defaultMode, writer);
2015                    if (listenerEvents != null)
2016                        listenerEvents.clear();
2017                }
2018
2019                lastEventSetDesc = eventSetDesc;
2020            }
2021
2022            if (defaultMode != ANONYMOUS_INNERCLASSES)
2023                if (mode == defaultMode) {
2024                    if (!event.isInCEDL())
2025                        mode = ANONYMOUS_INNERCLASSES;
2026                }
2027                else if (event.isInCEDL())
2028                    mixedMode = true;
2029
2030            if (defaultMode == ANONYMOUS_INNERCLASSES || !event.isInCEDL()) {
2031                if (listenerEvents == null)
2032                    listenerEvents = new ArrayList();
2033                listenerEvents.add(event);
2034            }
2035        }
2036
2037        if (lastEventSetDesc != null) {
2038            // generate the last listener
2039
if (codeData == null)
2040                generateEmptyLineIfNeeded(writer);
2041            generateListenerAddCode(component, lastEventSetDesc, listenerEvents, mode, writer);
2042            if (mixedMode)
2043                generateListenerAddCode(component, lastEventSetDesc, listenerEvents, defaultMode, writer);
2044        }
2045
2046        String JavaDoc postCode = (String JavaDoc) component.getAuxValue(AUX_LISTENERS_POST);
2047        if (codeData != null) { // build code data for editing
2048
String JavaDoc code = initCodeWriter.extractString();
2049            if (code != null && !code.equals("")) // NOI18N
2050
codeData.addGuardedBlock(indentCode(code));
2051            codeData.addEditableBlock(postCode,
2052                                      (FormProperty) component.getSyntheticProperty(PROP_LISTENERS_POST),
2053                                      0, // preference index
2054
FormUtils.getBundleString("CustomCode-PostListeners"), // NOI18N
2055
FormUtils.getBundleString("MSG_JC_PostListenersCodeDesc")); // NOI18N
2056
}
2057        else if (postCode != null && !postCode.equals("")) { // NOI18N
2058
generateEmptyLineIfNeeded(writer);
2059            writer.write(postCode);
2060            if (!postCode.endsWith("\n")) // NOI18N
2061
writer.write("\n"); // NOI18N
2062
}
2063    }
2064
2065    // generates complete code for handling one listener
2066
// (one component.addXXXListener() call)
2067
private void generateListenerAddCode(RADComponent comp,
2068                                         EventSetDescriptor eventSetDesc,
2069                                         java.util.List JavaDoc eventList,
2070                                         int mode,
2071                                         Writer codeWriter)
2072        throws IOException
2073    {
2074        Method addListenerMethod = eventSetDesc.getAddListenerMethod();
2075        Class JavaDoc[] exceptions = addListenerMethod.getExceptionTypes();
2076        if (needTryCode(exceptions))
2077            codeWriter.write("try {\n"); // NOI18N
2078
else
2079            exceptions = null;
2080
2081        codeWriter.write(getComponentInvokeString(comp, true));
2082        codeWriter.write(addListenerMethod.getName());
2083        codeWriter.write("("); // NOI18N
2084

2085        switch (mode) {
2086            case ANONYMOUS_INNERCLASSES:
2087                codeWriter.write("new "); // NOI18N
2088

2089                // try to find adpater to use instead of full listener impl
2090
Class JavaDoc listenerType = eventSetDesc.getListenerType();
2091                Class JavaDoc adapterClass = BeanSupport.getAdapterForListener(
2092                                                           listenerType);
2093                if (adapterClass != null) { // use listener adapter class
2094
codeWriter.write(getSourceClassName(adapterClass) + "() {\n"); // NOI18N
2095

2096                    for (int i=0; i < eventList.size(); i++) {
2097                        Event event = (Event) eventList.get(i);
2098                        String JavaDoc[] paramNames = generateListenerMethodHeader(
2099                                   null, event.getListenerMethod(), codeWriter);
2100                        generateEventHandlerCalls(event, paramNames, codeWriter, true);
2101                        codeWriter.write("}\n"); // NOI18N
2102
}
2103                }
2104                else { // generate full listener implementation (all methods)
2105
codeWriter.write(getSourceClassName(listenerType) + "() {\n"); // NOI18N
2106

2107                    Method[] methods = eventSetDesc.getListenerMethods();
2108                    for (int i=0; i < methods.length; i++) {
2109                        Method m = methods[i];
2110                        Event event = null;
2111                        for (int j=0; j < eventList.size(); j++) {
2112                            Event e = (Event) eventList.get(j);
2113                            if (m.equals(e.getListenerMethod())) {
2114                                event = e;
2115                                break;
2116                            }
2117                        }
2118                        String JavaDoc[] paramNames =
2119                            generateListenerMethodHeader(null, m, codeWriter);
2120                        if (event != null)
2121                            generateEventHandlerCalls(event, paramNames, codeWriter, true);
2122                        codeWriter.write("}\n"); // NOI18N
2123
}
2124                }
2125
2126                codeWriter.write("}"); // NOI18N
2127
break;
2128
2129            case CEDL_INNERCLASS:
2130                codeWriter.write(getListenerVariableName());
2131                break;
2132
2133            case CEDL_MAINCLASS:
2134                codeWriter.write("this"); // NOI18N
2135
break;
2136        }
2137
2138        codeWriter.write(");\n"); // NOI18N
2139

2140        if (exceptions != null)
2141            generateCatchCode(exceptions, codeWriter);
2142    }
2143
2144    private RADComponent codeVariableToRADComponent(CodeVariable var) {
2145        RADComponent metacomp = null;
2146        Iterator iter = var.getAttachedExpressions().iterator();
2147        if (iter.hasNext()) {
2148            Object JavaDoc metaobject = ((CodeExpression)iter.next()).getOrigin().getMetaObject();
2149            if (metaobject instanceof RADComponent) {
2150                metacomp = (RADComponent)metaobject;
2151            }
2152        }
2153        return metacomp;
2154    }
2155
2156    private void addFieldVariables(CodeWriter variablesWriter)
2157        throws IOException
2158    {
2159        Iterator it = getSortedVariables(CodeVariable.FIELD,
2160                                         CodeVariable.SCOPE_MASK);
2161
2162        while (it.hasNext()) {
2163            CodeVariable var = (CodeVariable) it.next();
2164            RADComponent metacomp = codeVariableToRADComponent(var);
2165            if (metacomp != null)
2166                generateComponentFieldVariable(metacomp, variablesWriter, null);
2167            // there should not be other than component variables as fields
2168
}
2169    }
2170
2171    private void addLocalVariables(Writer writer)
2172        throws IOException
2173    {
2174        Iterator it = getSortedVariables(
2175            CodeVariable.LOCAL | CodeVariable.EXPLICIT_DECLARATION,
2176            CodeVariable.SCOPE_MASK | CodeVariable.DECLARATION_MASK);
2177
2178        if (it.hasNext())
2179            generateEmptyLineIfNeeded(writer);
2180
2181        while (it.hasNext()) {
2182            CodeVariable var = (CodeVariable) it.next();
2183            if (codeVariableToRADComponent(var) == null) {
2184                // other than component variable (e.g. GridBagConstraints)
2185
writer.write(var.getDeclaration().getJavaCodeString(null, null));
2186                writer.write("\n"); // NOI18N
2187
}
2188        }
2189    }
2190
2191    private void generateComponentFieldVariable(RADComponent metacomp,
2192                                           CodeWriter codeWriter,
2193                                           CustomCodeData codeData)
2194        throws IOException
2195    {
2196        // optimization - only properties need to go through CodeWriter
2197
Writer writer = codeWriter.getWriter();
2198
2199        generateDeclarationPre(metacomp, writer, codeData);
2200
2201        CodeVariable var = metacomp.getCodeExpression().getVariable();
2202        if (isFinalFieldVariable(var.getType())) { // add also creation assignment
2203
generateComponentCreate(metacomp, codeWriter, false, codeData);
2204        }
2205        else { // simple declaration
2206
writer.write(var.getDeclaration().getJavaCodeString(null, null));
2207            writer.write("\n"); // NOI18N
2208

2209            if (codeData != null) { // build code data for editing
2210
String JavaDoc code = indentCode(codeWriter.extractString());
2211                codeData.addGuardedBlock(code);
2212            }
2213        }
2214
2215        generateDeclarationPost(metacomp, writer, codeData);
2216    }
2217
2218    private static boolean isFinalFieldVariable(int varType) {
2219        return (varType & (CodeVariable.FINAL | CodeVariable.SCOPE_MASK))
2220                == (CodeVariable.FINAL | CodeVariable.FIELD);
2221    }
2222
2223    private static void generateDeclarationPre(RADComponent metacomp,
2224                                               Writer writer,
2225                                               CustomCodeData codeData)
2226        throws IOException
2227    {
2228        String JavaDoc preCode = (String JavaDoc) metacomp.getAuxValue(AUX_DECLARATION_PRE);
2229        if (codeData != null) { // build code data for editing
2230
codeData.addEditableBlock(preCode,
2231                                      (FormProperty) metacomp.getSyntheticProperty(PROP_DECLARATION_PRE),
2232                                      0, // preference index
2233
FormUtils.getBundleString("CustomCode-PreDeclaration"), // NOI18N
2234
FormUtils.getBundleString("MSG_JC_PreDeclarationDesc")); // NOI18N
2235
}
2236        else if (preCode != null && !preCode.equals("")) { // NOI18N
2237
writer.write(preCode);
2238            if (!preCode.endsWith("\n")) // NOI18N
2239
writer.write("\n"); // NOI18N
2240
}
2241    }
2242
2243    private static void generateDeclarationPost(RADComponent metacomp,
2244                                                Writer writer,
2245                                                CustomCodeData codeData)
2246        throws IOException
2247    {
2248        String JavaDoc postCode = (String JavaDoc) metacomp.getAuxValue(AUX_DECLARATION_POST);
2249        if (codeData != null) { // build code data for editing
2250
codeData.addEditableBlock(postCode,
2251                                      (FormProperty) metacomp.getSyntheticProperty(PROP_DECLARATION_POST),
2252                                      0, // preference index
2253
FormUtils.getBundleString("CustomCode-PostDeclaration"), // NOI18N
2254
FormUtils.getBundleString("MSG_JC_PostDeclarationDesc")); // NOI18N
2255
}
2256        else if (postCode != null && !postCode.equals("")) { // NOI18N
2257
writer.write(postCode);
2258            if (!postCode.endsWith("\n")) // NOI18N
2259
writer.write("\n"); // NOI18N
2260
}
2261    }
2262
2263    /** Adds new empty line if currentAreaNumber has raised from last time.
2264     * Should never be called when building "code data" for editing.
2265     */

2266    private void generateEmptyLineIfNeeded(Writer writer) throws IOException {
2267        if (emptyLineCounter != emptyLineRequest) {
2268            writer.write("\n"); // NOI18N
2269
}
2270        emptyLineCounter = emptyLineRequest;
2271    }
2272
2273    private Iterator getSortedVariables(int type, int typeMask) {
2274        Collection allVariables = formModel.getCodeStructure().getAllVariables();
2275        java.util.List JavaDoc variables = new ArrayList(allVariables.size());
2276        Iterator it = allVariables.iterator();
2277        while (it.hasNext()) {
2278            CodeVariable var = (CodeVariable) it.next();
2279            if (var.getDeclaredType() == org.netbeans.modules.form.Separator.class)
2280                continue; // treat AWT Separator specially - it is not a component
2281
if ((var.getType() & typeMask) == (type & typeMask))
2282                variables.add(var);
2283        }
2284        Collections.sort(variables, new Comparator() {
2285            public int compare(Object JavaDoc o1, Object JavaDoc o2) {
2286                return ((CodeVariable)o1).getName().compareTo(
2287                        ((CodeVariable)o2).getName());
2288            }
2289        });
2290        return variables.iterator();
2291    }
2292
2293    // Mnemonics support - start -
2294
static boolean canUseMnemonics(RADComponent comp) {
2295        return javax.swing.JLabel JavaDoc.class.isAssignableFrom(comp.getBeanClass())
2296               || javax.swing.AbstractButton JavaDoc.class.isAssignableFrom(comp.getBeanClass());
2297    }
2298
2299    static boolean isUsingMnemonics(RADComponent comp) {
2300        Object JavaDoc mnem = comp.getAuxValue(PROP_GENERATE_MNEMONICS);
2301        if (mnem != null)
2302            return Boolean.TRUE.equals(mnem);
2303
2304        return comp.getFormModel().getSettings().getGenerateMnemonicsCode();
2305    }
2306    // Mnemonics support - end -
2307

2308    private String JavaDoc getComponentParameterString(RADComponent component,
2309                                               boolean inMainClass)
2310    {
2311        if (component == formModel.getTopRADComponent())
2312            return inMainClass ?
2313                     "this" : // NOI18N
2314
formEditorSupport.getFormDataObject().getName() + ".this"; // NOI18N
2315
else
2316            return component.getName();
2317    }
2318
2319    private String JavaDoc getComponentInvokeString(RADComponent component,
2320                                            boolean inMainClass)
2321    {
2322        if (component == formModel.getTopRADComponent())
2323            return inMainClass ?
2324                     "" : // NOI18N
2325
formEditorSupport.getFormDataObject().getName() + ".this."; // NOI18N
2326
else
2327            return component.getName() + "."; // NOI18N
2328
}
2329
2330    static String JavaDoc getSourceClassName(Class JavaDoc cls) {
2331        return cls.getName().replace('$', '.').replace('+', '.').replace('/', '.'); // NOI18N
2332
}
2333
2334    private static String JavaDoc getVariablesHeaderComment() {
2335        if (variablesHeader == null)
2336            variablesHeader = FormUtils.getBundleString("MSG_VariablesBegin"); // NOI18N
2337
return variablesHeader;
2338    }
2339
2340    private static String JavaDoc getVariablesFooterComment() {
2341        if (variablesFooter == null)
2342            variablesFooter = FormUtils.getBundleString("MSG_VariablesEnd"); // NOI18N
2343
return variablesFooter;
2344    }
2345
2346    private static String JavaDoc getEventDispatchCodeComment() {
2347        if (eventDispatchCodeComment == null)
2348            eventDispatchCodeComment = FormUtils.getBundleString("MSG_EventDispatchCodeComment"); // NOI18N
2349
return eventDispatchCodeComment;
2350    }
2351
2352    private boolean needTryCode(Class JavaDoc[] exceptions) {
2353        if (exceptions != null)
2354            for (int i=0; i < exceptions.length; i++)
2355                if (Exception JavaDoc.class.isAssignableFrom(exceptions[i])
2356                    && !RuntimeException JavaDoc.class.isAssignableFrom(exceptions[i]))
2357                {
2358                    return true;
2359                }
2360
2361        return false;
2362    }
2363
2364    private void generateCatchCode(Class JavaDoc[] exceptions, Writer initCodeWriter)
2365        throws IOException
2366    {
2367        initCodeWriter.write("}"); // NOI18N
2368
for (int i=0, exCount=0; i < exceptions.length; i++) {
2369            Class JavaDoc exception = exceptions[i];
2370            if (!Exception JavaDoc.class.isAssignableFrom(exception)
2371                    || RuntimeException JavaDoc.class.isAssignableFrom(exception))
2372                continue; // need not be caught
2373

2374            if (i > 0) {
2375                int j;
2376                for (j=0; j < i; j++)
2377                    if (exceptions[j].isAssignableFrom(exception))
2378                        break;
2379                if (j < i)
2380                    continue; // a subclass of this exception already caught
2381
}
2382
2383            initCodeWriter.write(" catch ("); // NOI18N
2384
initCodeWriter.write(getSourceClassName(exception));
2385            initCodeWriter.write(" "); // NOI18N
2386

2387            String JavaDoc varName = "e" + ++exCount; // NOI18N
2388

2389            initCodeWriter.write(varName);
2390            initCodeWriter.write(") {\n"); // NOI18N
2391
initCodeWriter.write(varName);
2392            initCodeWriter.write(".printStackTrace();\n"); // NOI18N
2393
// [shouldn't return be generated here?]
2394
initCodeWriter.write("}"); // NOI18N
2395
}
2396        initCodeWriter.write("\n"); // NOI18N
2397
}
2398
2399    private void addDispatchListenerDeclaration(Writer codeWriter)
2400        throws IOException
2401    {
2402        generateEmptyLineIfNeeded(codeWriter);
2403
2404        listenerVariableName = null;
2405        codeWriter.write(getListenerClassName());
2406        codeWriter.write(" "); // NOI18N
2407
codeWriter.write(getListenerVariableName());
2408        codeWriter.write(" = new "); // NOI18N
2409
codeWriter.write(getListenerClassName());
2410        codeWriter.write("();\n"); // NOI18N
2411
}
2412
2413    private void generateDispatchListenerCode(Writer codeWriter)
2414        throws IOException
2415    { // always ends up with } as last character (no new line - because of fold footer)
2416
FormEvents formEvents = formModel.getFormEvents();
2417        boolean innerclass = formModel.getSettings().getListenerGenerationStyle() == CEDL_INNERCLASS;
2418        boolean mainclass = formModel.getSettings().getListenerGenerationStyle() == CEDL_MAINCLASS;
2419
2420        Class JavaDoc[] listenersToImplement = formEvents.getCEDLTypes();
2421        Arrays.sort(listenersToImplement, new Comparator() {
2422            public int compare(Object JavaDoc o1, Object JavaDoc o2) {
2423                return ((Class JavaDoc)o1).getName().compareTo(((Class JavaDoc)o2).getName());
2424            }
2425        });
2426
2427        listenersInMainClass = mainclass ? listenersToImplement : null;
2428
2429        if (innerclass) {
2430            String JavaDoc listenerClassName = getListenerClassName();
2431            codeWriter.write("private class "); // NOI18N
2432
codeWriter.write(listenerClassName);
2433            codeWriter.write(" implements "); // NOI18N
2434
for (int i=0; i < listenersToImplement.length; i++) {
2435                codeWriter.write(getSourceClassName(listenersToImplement[i]));
2436                if (i + 1 < listenersToImplement.length)
2437                    codeWriter.write(", "); // NOI18N
2438
}
2439            codeWriter.write(" {\n"); // NOI18N
2440
codeWriter.write(listenerClassName + "() {}\n"); // NOI18N Issue 72346 resp. 15242
2441
}
2442
2443        for (int i=0; i < listenersToImplement.length; i++) {
2444            boolean implementedInSuperclass =
2445                mainclass && listenersToImplement[i].isAssignableFrom(
2446                                          formModel.getFormBaseClass());
2447
2448            Method[] methods = listenersToImplement[i].getMethods();
2449            Arrays.sort(methods, new Comparator() {
2450                public int compare(Object JavaDoc o1, Object JavaDoc o2) {
2451                    return ((Method)o1).getName().compareTo(((Method)o2).getName());
2452                }
2453            });
2454
2455            for (int j=0; j < methods.length; j++) {
2456                Method method = methods[j];
2457                Event[] events = formEvents.getEventsForCEDLMethod(method);
2458                if (implementedInSuperclass && events.length == 0)
2459                    continue;
2460
2461                String JavaDoc[] paramNames =
2462                    generateListenerMethodHeader(null, method, codeWriter);
2463
2464                for (int k=0; k < events.length; k++) {
2465                    Event event = events[k];
2466                    if (k + 1 < events.length
2467                        || method.getReturnType() == Void.TYPE)
2468                    {
2469            String JavaDoc componentParameterString = getComponentParameterString(
2470                                event.getComponent(), false);
2471            
2472            CodeVariable variable = event.getComponent().getCodeExpression().getVariable();
2473            if( variable!= null && ( (variable.getType() & CodeVariable.LOCAL) == CodeVariable.LOCAL) ) {
2474                codeWriter.write(
2475                FormUtils.getFormattedBundleString(
2476                    "MSG_WrongLocalVariableSettingComment", // NOI18N
2477
new Object JavaDoc[] { componentParameterString }));
2478            }
2479            
2480                        codeWriter.write(k == 0 ? "if (" : "else if ("); // NOI18N
2481
codeWriter.write(paramNames[0]);
2482                        codeWriter.write(".getSource() == "); // NOI18N
2483
codeWriter.write(componentParameterString);
2484                        codeWriter.write(") {\n"); // NOI18N
2485

2486                        generateEventHandlerCalls(event, paramNames, codeWriter, false);
2487                        codeWriter.write("}\n"); // NOI18N
2488

2489                    }
2490                    else { // the listener method returns something
2491
if (k > 0)
2492                            codeWriter.write("else {\n"); // NOI18N
2493
generateEventHandlerCalls(event, paramNames, codeWriter, false);
2494                        if (k > 0)
2495                            codeWriter.write("}\n"); // NOI18N
2496
}
2497                }
2498                if (implementedInSuperclass)
2499                    generateSuperListenerCall(method, paramNames, codeWriter);
2500
2501                if (j+1 < methods.length || i+1 < listenersToImplement.length)
2502                    codeWriter.write("}\n\n"); // NOI18N
2503
else if (innerclass)
2504                    codeWriter.write("}\n"); // NOI18N
2505
else
2506                    codeWriter.write("}"); // last char // NOI18N
2507
}
2508        }
2509
2510        if (innerclass)
2511            codeWriter.write("}"); // last char // NOI18N
2512
}
2513
2514    // modifies the form class declaration to implement required listeners
2515
// (when event dispatching code is generated as CEDL_MAINCLASS)
2516
private void ensureMainClassImplementsListeners() {
2517        if (listenersInMainClass == listenersInMainClass_lastSet)
2518            return; // no change from last time
2519

2520        if (listenersInMainClass != null
2521            && listenersInMainClass_lastSet != null
2522            && listenersInMainClass.length == listenersInMainClass_lastSet.length)
2523        {
2524            boolean different = false;
2525            for (int i=0; i < listenersInMainClass.length; i++)
2526                if (listenersInMainClass[i] != listenersInMainClass_lastSet[i]) {
2527                    different = true;
2528                    break;
2529                }
2530            if (!different)
2531                return; // no change from last time
2532
}
2533
2534        final Set<String JavaDoc> toRemove = new HashSet<String JavaDoc>();
2535        if (listenersInMainClass_lastSet != null)
2536            for (int i=0; i < listenersInMainClass_lastSet.length; i++) {
2537                Class JavaDoc cls = listenersInMainClass_lastSet[i];
2538                boolean remains = false;
2539                if (listenersInMainClass != null)
2540                    for (int j=0; j < listenersInMainClass.length; j++)
2541                        if (cls == listenersInMainClass[j]) {
2542                            remains = true;
2543                            break;
2544                        }
2545                if (!remains) {
2546                    toRemove.add(cls.getName());
2547                }
2548            }
2549
2550        
2551        final FileObject fo = formEditorSupport.getFormDataObject().getPrimaryFile();
2552        JavaSource js = JavaSource.forFileObject(fo);
2553        try {
2554            js.runModificationTask(new CancellableTask<WorkingCopy>() {
2555                public void cancel() {
2556                }
2557                public void run(WorkingCopy wcopy) throws Exception JavaDoc {
2558                    wcopy.toPhase(JavaSource.Phase.RESOLVED);
2559                    
2560                    ClassTree mainClassTree = findMainClass(wcopy, fo.getName());
2561                    ClassTree origMainTree = mainClassTree;
2562                    
2563                    TreePath classTreePath = wcopy.getTrees().getPath(wcopy.getCompilationUnit(), mainClassTree);
2564                    Element mainClassElm = wcopy.getTrees().getElement(classTreePath);
2565                            
2566                    if (mainClassElm != null) {
2567                        java.util.List JavaDoc<TypeElement> actualInterfaces = new ArrayList<TypeElement>();
2568                        TreeMaker maker = wcopy.getTreeMaker();
2569                        // first take the current interfaces and exclude the removed ones
2570
int infIndex = 0;
2571                        for (TypeMirror infMirror: ((TypeElement) mainClassElm).getInterfaces()) {
2572                            TypeElement infElm = (TypeElement) wcopy.getTypes().asElement(infMirror);
2573                            actualInterfaces.add(infElm);
2574                            if (toRemove.contains(infElm.getQualifiedName().toString())) {
2575                                mainClassTree = maker.removeClassImplementsClause(mainClassTree, infIndex);
2576                            }
2577                            ++infIndex;
2578                        }
2579
2580                        // then ensure all required interfaces are present
2581
if (listenersInMainClass != null) {
2582                            for (int i=0; i < listenersInMainClass.length; i++) {
2583                                String JavaDoc name = listenersInMainClass[i].getName();
2584                                boolean alreadyIn = false;
2585                                for (TypeElement infElm: actualInterfaces)
2586                                    if (name.equals(infElm.getQualifiedName().toString())) {
2587                                        alreadyIn = true;
2588                                        break;
2589                                    }
2590                                if (!alreadyIn) {
2591                                    TypeElement inf2add = wcopy.getElements().getTypeElement(name);
2592                                    ExpressionTree infTree2add = inf2add != null
2593                                            ? maker.QualIdent(inf2add)
2594                                            : maker.Identifier(name);
2595                                    mainClassTree = maker.addClassImplementsClause(mainClassTree, infTree2add);
2596                                }
2597                            }
2598                        }
2599
2600                        if (origMainTree != mainClassTree) {
2601                            wcopy.rewrite(origMainTree, mainClassTree);
2602                        }
2603
2604                    }
2605                }
2606            }).commit();
2607            
2608            listenersInMainClass_lastSet = listenersInMainClass;
2609        } catch (IOException ex) {
2610            Logger.getLogger(JavaCodeGenerator.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
2611        }
2612    }
2613    
2614    private static ClassTree findMainClass(CompilationController controller, String JavaDoc name) {
2615        for (Tree t: controller.getCompilationUnit().getTypeDecls()) {
2616            if (t.getKind() == Tree.Kind.CLASS &&
2617                    name.equals(((ClassTree) t).getSimpleName().toString())) {
2618
2619                return (ClassTree) t;
2620            }
2621        }
2622        return null;
2623    }
2624
2625    // ---------
2626
// generating general code structure (metadata from codestructure package)
2627

2628    // java code for a statement
2629
private static String JavaDoc getStatementJavaString(CodeStatement statement,
2630                                                 String JavaDoc thisStr)
2631    {
2632        CodeExpression parent = statement.getParentExpression();
2633        String JavaDoc parentStr;
2634        if (parent != null) {
2635            parentStr = getExpressionJavaString(parent, thisStr);
2636            if ("this".equals(parentStr)) // NOI18N
2637
parentStr = thisStr;
2638        }
2639        else parentStr = null;
2640
2641        CodeExpression[] params = statement.getStatementParameters();
2642        String JavaDoc[] paramsStr = new String JavaDoc[params.length];
2643        for (int i=0; i < params.length; i++)
2644            paramsStr[i] = getExpressionJavaString(params[i], thisStr);
2645
2646        return statement.getJavaCodeString(parentStr, paramsStr);
2647    }
2648
2649    // java code for an expression
2650
private static String JavaDoc getExpressionJavaString(CodeExpression exp,
2651                                                  String JavaDoc thisStr)
2652    {
2653        CodeVariable var = exp.getVariable();
2654        if (var != null)
2655            return var.getName();
2656
2657        CodeExpressionOrigin origin = exp.getOrigin();
2658        if (origin == null)
2659            return null;
2660
2661        CodeExpression parent = origin.getParentExpression();
2662        String JavaDoc parentStr;
2663        if (parent != null) {
2664            parentStr = getExpressionJavaString(parent, thisStr);
2665            if ("this".equals(parentStr)) // NOI18N
2666
parentStr = thisStr;
2667        }
2668        else parentStr = null;
2669
2670        CodeExpression[] params = origin.getCreationParameters();
2671        String JavaDoc[] paramsStr = new String JavaDoc[params.length];
2672        for (int i=0; i < params.length; i++)
2673            paramsStr[i] = getExpressionJavaString(params[i], thisStr);
2674
2675        return origin.getJavaCodeString(parentStr, paramsStr);
2676    }
2677
2678    // ---------
2679
// Events
2680

2681    private boolean anyEvents() {
2682        return formModel.getFormEvents().hasEventsInCEDL();
2683    }
2684
2685    private String JavaDoc getListenerClassName() {
2686        if (listenerClassName == null) {
2687            String JavaDoc initText = formEditorSupport.getInitComponentSection().getText();
2688            int index = initText.lastIndexOf("private class "); // NOI18N
2689
if (index >= 0) {
2690                StringBuffer JavaDoc nameBuffer = new StringBuffer JavaDoc(16);
2691                index += "private class ".length(); // NOI18N
2692

2693                int length = initText.length();
2694                while (index < length && initText.charAt(index) == ' ')
2695                    index++;
2696
2697                int i = index;
2698                while (i < length && initText.charAt(i) != ' ')
2699                    nameBuffer.append(initText.charAt(i++));
2700
2701                if (i < length)
2702                    listenerClassName = nameBuffer.toString();
2703            }
2704
2705            if (listenerClassName == null) {
2706                javax.swing.text.Document JavaDoc document = formEditorSupport.getDocument();
2707                try {
2708                    String JavaDoc wholeText = document.getText(0, document.getLength());
2709                    listenerClassName = DEFAULT_LISTENER_CLASS_NAME;
2710                    while (wholeText.indexOf(listenerClassName) >= 0)
2711                        listenerClassName = "_" + listenerClassName; // NOI18N
2712
}
2713                catch (javax.swing.text.BadLocationException JavaDoc ex) {} // ignore
2714
}
2715
2716            if (listenerClassName == null)
2717                listenerClassName = DEFAULT_LISTENER_CLASS_NAME;
2718        }
2719
2720        return listenerClassName;
2721    }
2722
2723    private String JavaDoc getListenerVariableName() {
2724        if (listenerVariableName == null) {
2725            listenerVariableName = "formListener"; // NOI18N
2726
CodeStructure codeStructure = formModel.getCodeStructure();
2727            for (int i=1; codeStructure.isVariableNameReserved(listenerVariableName); i++)
2728                listenerVariableName = "formListener" + i; // NOI18N
2729
}
2730        return listenerVariableName;
2731    }
2732
2733    // -----------------------------------------------------------------------------
2734
// Event handlers
2735

2736    /** Generates the specified event handler.
2737     */

2738    private void generateEventHandler(String JavaDoc handlerName,
2739                                      Method originalMethod,
2740                                      String JavaDoc bodyText)
2741    {
2742        if (!initialized || !canGenerate)
2743            return;
2744
2745        InteriorSection sec = getEventHandlerSection(handlerName);
2746        if (sec != null && bodyText == null)
2747            return; // already exists, no need to generate
2748

2749        IndentEngine engine = IndentEngine.find(formEditorSupport.getDocument());
2750        StringWriter buffer = new StringWriter();
2751        final SimpleSection initComponentsSection = formEditorSupport.getInitComponentSection();
2752        Writer codeWriter = engine.createWriter(
2753                        formEditorSupport.getDocument(),
2754                        initComponentsSection.getEndPosition().getOffset(),
2755                        buffer);
2756
2757        try {
2758            if (sec == null)
2759                sec = formEditorSupport.getGuardedSectionManager().createInteriorSection(
2760                          formEditorSupport.getDocument().createPosition(initComponentsSection.getEndPosition().getOffset() + 1),
2761                          getEventSectionName(handlerName));
2762            int i1, i2;
2763
2764            generateListenerMethodHeader(handlerName, originalMethod, codeWriter);
2765            codeWriter.flush();
2766            i1 = buffer.getBuffer().length();
2767            if (bodyText == null)
2768                bodyText = getDefaultEventBody();
2769            codeWriter.write(bodyText);
2770            codeWriter.flush();
2771            i2 = buffer.getBuffer().length();
2772            codeWriter.write("}\n"); // footer with new line // NOI18N
2773
codeWriter.flush();
2774
2775            sec.setHeader(buffer.getBuffer().substring(0,i1));
2776            sec.setBody(buffer.getBuffer().substring(i1,i2));
2777            sec.setFooter(buffer.getBuffer().substring(i2));
2778
2779            codeWriter.close();
2780        }
2781        catch (javax.swing.text.BadLocationException JavaDoc e) {
2782            return;
2783        }
2784        catch (java.io.IOException JavaDoc ioe) {
2785            return;
2786        }
2787
2788        clearUndo();
2789    }
2790
2791    /** Removes the specified event handler - removes the whole method together with the user code!
2792     * @param handlerName The name of the event handler
2793     */

2794    private boolean deleteEventHandler(String JavaDoc handlerName) {
2795        InteriorSection section = getEventHandlerSection(handlerName);
2796        if (section == null || !initialized || !canGenerate)
2797            return false;
2798
2799        section.deleteSection();
2800        clearUndo();
2801
2802        return true;
2803    }
2804
2805    private String JavaDoc getDefaultEventBody() {
2806        return FormUtils.getBundleString("MSG_EventHandlerBody"); // NOI18N
2807
}
2808
2809    /** Renames the specified event handler to the given new name.
2810     * @param oldHandlerName The old name of the event handler
2811     * @param newHandlerName The new name of the event handler
2812     */

2813    private void renameEventHandler(String JavaDoc oldHandlerName,
2814                                    String JavaDoc newHandlerName)
2815    {
2816        InteriorSection sec = getEventHandlerSection(oldHandlerName);
2817        if (sec == null || !initialized || !canGenerate)
2818            return;
2819
2820        String JavaDoc header = sec.getHeader();
2821
2822        // find the old handler name in the handler method header
2823
int index = header.indexOf('(');
2824        if (index < 0)
2825            return; // should not happen unless the handler code is corrupted
2826
index = header.substring(0, index).lastIndexOf(oldHandlerName);
2827        if (index < 0)
2828            return; // old name not found; should not happen
2829

2830        IndentEngine engine = IndentEngine.find(formEditorSupport.getDocument());
2831        StringWriter buffer = new StringWriter();
2832        Writer codeWriter = engine.createWriter(formEditorSupport.getDocument(),
2833                                                sec.getStartPosition().getOffset(),
2834                                                buffer);
2835        try {
2836            codeWriter.write(header.substring(0, index));
2837            codeWriter.write(newHandlerName);
2838            codeWriter.write(header.substring(index + oldHandlerName.length()));
2839            codeWriter.flush();
2840            int i1 = buffer.getBuffer().length();
2841            codeWriter.write("}\n"); // NOI18N // footer with new line
2842
codeWriter.flush();
2843
2844            sec.setHeader(buffer.getBuffer().substring(0, i1));
2845            sec.setFooter(buffer.getBuffer().substring(i1));
2846            sec.setName(getEventSectionName(newHandlerName));
2847
2848            codeWriter.close();
2849        }
2850        catch (java.beans.PropertyVetoException JavaDoc e) {
2851            return;
2852        }
2853        catch (IOException e) {
2854            return;
2855        }
2856
2857        clearUndo();
2858    }
2859
2860    /** Focuses the specified event handler in the editor. */
2861    private void gotoEventHandler(String JavaDoc handlerName) {
2862        InteriorSection sec = getEventHandlerSection(handlerName);
2863        if (sec != null && initialized)
2864            formEditorSupport.openAt(sec.getCaretPosition());
2865    }
2866
2867    /** Gets the body (text) of event handler of given name. */
2868    String JavaDoc getEventHandlerText(String JavaDoc handlerName) {
2869        InteriorSection section = getEventHandlerSection(handlerName);
2870        if (section != null) {
2871            // XXX try to use section.getBody instead
2872
String JavaDoc tx = section.getText();
2873            tx = tx.substring(tx.indexOf("{")+1, tx.lastIndexOf("}")).trim() + "\n"; // NOI18N
2874
return tx;
2875        }
2876        return null;
2877    }
2878
2879    // ------------------------------------------------------------------------------------------
2880
// Private methods
2881

2882    /** Clears undo buffer after code generation */
2883    private void clearUndo() {
2884        formEditorSupport.discardEditorUndoableEdits();
2885    }
2886
2887    // sections acquirement
2888

2889    private InteriorSection getEventHandlerSection(String JavaDoc eventName) {
2890        return formEditorSupport.getGuardedSectionManager().findInteriorSection(getEventSectionName(eventName));
2891    }
2892
2893    // other
2894

2895    private String JavaDoc getEventSectionName(String JavaDoc handlerName) {
2896        return EVT_SECTION_PREFIX + handlerName;
2897    }
2898
2899    private String JavaDoc[] generateListenerMethodHeader(String JavaDoc methodName,
2900                                                  Method originalMethod,
2901                                                  Writer writer)
2902        throws IOException
2903    {
2904        Class JavaDoc[] paramTypes = originalMethod.getParameterTypes();
2905        String JavaDoc[] paramNames;
2906
2907        if (paramTypes.length == 1
2908            && EventObject.class.isAssignableFrom(paramTypes[0]))
2909        {
2910            paramNames = new String JavaDoc[] { formSettings.getEventVariableName() };
2911        }
2912        else {
2913            paramNames = new String JavaDoc[paramTypes.length];
2914            for (int i=0; i < paramTypes.length; i++)
2915                paramNames[i] = "param" + i; // NOI18N
2916
}
2917
2918        // generate the method
2919
writer.write(methodName != null ? "private " : "public "); // NOI18N
2920
writer.write(getSourceClassName(originalMethod.getReturnType()));
2921        writer.write(" "); // NOI18N
2922
writer.write(methodName != null ? methodName : originalMethod.getName());
2923        writer.write("("); // NOI18N
2924

2925        for (int i=0; i < paramTypes.length; i++) {
2926            writer.write(getSourceClassName(paramTypes[i]));
2927            writer.write(" "); // NOI18N
2928
writer.write(paramNames[i]);
2929            if (i + 1 < paramTypes.length)
2930                writer.write(", "); // NOI18N
2931
}
2932        writer.write(")"); // NOI18N
2933

2934        Class JavaDoc[] exceptions = originalMethod.getExceptionTypes();
2935        if (exceptions.length != 0) {
2936            writer.write("throws "); // NOI18N
2937
for (int i=0; i < exceptions.length; i++) {
2938                writer.write(getSourceClassName(exceptions[i]));
2939                if (i + 1 < exceptions.length)
2940                    writer.write(", "); // NOI18N
2941
}
2942        }
2943
2944        writer.write(" {\n"); // NOI18N
2945

2946        return paramNames;
2947    }
2948
2949    private void generateSuperListenerCall(Method method,
2950                                           String JavaDoc[] paramNames,
2951                                           Writer codeWriter)
2952        throws IOException
2953    {
2954        if (method.getReturnType() != Void.TYPE)
2955            codeWriter.write("return "); // NOI18N
2956

2957        codeWriter.write("super."); // NOI18N
2958
codeWriter.write(method.getName());
2959        codeWriter.write("("); // NOI18N
2960

2961        for (int i=0; i < paramNames.length; i++) {
2962            codeWriter.write(paramNames[i]);
2963            if (i + 1 < paramNames.length)
2964                codeWriter.write(", "); // NOI18N
2965
}
2966
2967        codeWriter.write(");\n"); // NOI18N
2968
}
2969
2970    private void generateEventHandlerCalls(Event event,
2971                                           String JavaDoc[] paramNames,
2972                                           Writer codeWriter,
2973                                           boolean useShortNameIfPossible)
2974        throws IOException
2975    {
2976        String JavaDoc mainClassRef = null;
2977
2978        String JavaDoc[] handlers = event.getEventHandlers();
2979        for (int i=0; i < handlers.length; i++) {
2980            if (i + 1 == handlers.length
2981                    && event.getListenerMethod().getReturnType() != Void.TYPE)
2982                codeWriter.write("return "); // NOI18N
2983

2984            // with anonymous innerclasses, try to avoid generating full names
2985
// (for the reason some old forms might be used as innerclasses)
2986
if (!useShortNameIfPossible
2987                || event.getListenerMethod().getName().equals(handlers[i]))
2988            {
2989                if (mainClassRef == null)
2990                    mainClassRef = formEditorSupport.getFormDataObject().getName()
2991                                   + ".this."; // NOI18N
2992
codeWriter.write(mainClassRef);
2993            }
2994            codeWriter.write(handlers[i]);
2995            codeWriter.write("("); // NOI18N
2996

2997            for (int j=0; j < paramNames.length; j++) {
2998                codeWriter.write(paramNames[j]);
2999                if (j + 1 < paramNames.length)
3000                    codeWriter.write(", "); // NOI18N
3001
}
3002
3003            codeWriter.write(");\n"); // NOI18N
3004
}
3005    }
3006    
3007    void regenerateCode() {
3008        if (!codeUpToDate) {
3009            codeUpToDate = true;
3010            regenerateVariables();
3011            regenerateInitComponents();
3012            ensureMainClassImplementsListeners();
3013            FormModel.t("code regenerated"); // NOI18N
3014
}
3015    }
3016
3017    static CustomCodeData getCodeData(RADComponent metacomp) {
3018        CodeGenerator gen = FormEditor.getCodeGenerator(metacomp.getFormModel());
3019        return gen instanceof JavaCodeGenerator ?
3020            ((JavaCodeGenerator)gen).getCodeData0(metacomp) : null;
3021    }
3022
3023    private CustomCodeData getCodeData0(RADComponent metacomp) {
3024        CustomCodeData codeData = new CustomCodeData();
3025        codeData.setDefaultCategory(CustomCodeData.CodeCategory.CREATE_AND_INIT);
3026        CodeWriter codeWriter = new CodeWriter(new StringWriter(1024), true);
3027        cleanup();
3028
3029        CodeVariable var = metacomp.getCodeExpression().getVariable();
3030
3031        try { // creation & init code
3032
if (var != null && !isFinalFieldVariable(var.getType()))
3033                generateComponentCreate(metacomp, codeWriter, true, codeData);
3034            // with final field variable the creation statement is part of declaration
3035

3036            addInitCode(metacomp, codeWriter, codeData);
3037
3038            if (var != null) { // add declaration
3039
boolean fieldVariable = (var.getType() & CodeVariable.SCOPE_MASK) == CodeVariable.FIELD;
3040                if (fieldVariable) {
3041                    codeData.setDefaultCategory(CustomCodeData.CodeCategory.DECLARATION);
3042                    generateComponentFieldVariable(metacomp, codeWriter, codeData);
3043                }
3044                codeData.setDeclarationData(!fieldVariable, var.getType() & CodeVariable.ALL_MODIF_MASK);
3045            }
3046        }
3047        catch (IOException ex) { // should not happen
3048
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
3049        }
3050
3051        cleanup();
3052
3053        return codeData;
3054    }
3055
3056    private String JavaDoc indentCode(String JavaDoc code) {
3057        return indentCode(code, 0, null);
3058    }
3059
3060    private String JavaDoc indentCode(String JavaDoc code, int minIndentLevel, IndentEngine refEngine) {
3061        int spacesPerTab = 4;
3062        boolean braceOnNewLine = false;
3063        
3064        if (refEngine != null) {
3065            Class JavaDoc engineClass = refEngine.getClass();
3066            try {
3067                Method m = engineClass.getMethod("getSpacesPerTab", // NOI18N
3068
new Class JavaDoc[0]);
3069                spacesPerTab = ((Integer JavaDoc)m.invoke(refEngine, new Object JavaDoc[0]))
3070                .intValue();
3071            } catch (Exception JavaDoc ex) {} // ignore
3072

3073            try {
3074                Method m = engineClass.getMethod("getJavaFormatNewlineBeforeBrace", // NOI18N
3075
new Class JavaDoc[0]);
3076                braceOnNewLine = ((Boolean JavaDoc)m.invoke(refEngine, new Object JavaDoc[0]))
3077                .booleanValue();
3078            } catch (Exception JavaDoc ex) {} // ignore
3079
}
3080        
3081        StringBuffer JavaDoc tab = new StringBuffer JavaDoc(spacesPerTab);
3082        for (int i=0; i < spacesPerTab; i++)
3083            tab.append(" "); // NOI18N
3084

3085        return doIndentation(code, minIndentLevel, tab.toString(), braceOnNewLine);
3086    }
3087    
3088    // simple indentation method
3089
private static String JavaDoc doIndentation(String JavaDoc code,
3090            int minIndentLevel,
3091            String JavaDoc tab,
3092            boolean braceOnNewLine) {
3093
3094        int indentLevel = minIndentLevel;
3095        boolean lastLineEmpty = false;
3096        int codeLength = code.length();
3097        StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(codeLength);
3098        
3099        int i = 0;
3100        while (i < codeLength) {
3101            int lineStart = i;
3102            int lineEnd;
3103            boolean startingSpace = true;
3104            boolean firstClosingBr = false;
3105            boolean closingBr = false;
3106            int lastOpeningBr = -1;
3107            int endingSpace = -1;
3108            boolean insideString = false;
3109            int brackets = 0;
3110            char c;
3111            
3112            do { // go through one line
3113
c = code.charAt(i);
3114                if (!insideString) {
3115                    if (c == '}') {
3116                        lastOpeningBr = -1;
3117                        endingSpace = -1;
3118                        if (startingSpace) { // first non-space char on the line
3119
firstClosingBr = true;
3120                            closingBr = true;
3121                            startingSpace = false;
3122                            lineStart = i;
3123                        } else if (!closingBr)
3124                            brackets--;
3125                    } else if (c == ')') {
3126                        
3127                        int bracketCount = 0;
3128                        int begin = i;
3129                        while (begin < code.length() && (code.charAt(begin) == ')')) {
3130                            bracketCount += 1;
3131                            begin += 1;
3132                        }
3133                        
3134                        lastOpeningBr = -1;
3135                        endingSpace = -1;
3136                        if (startingSpace) { // first non-space char on the line
3137
firstClosingBr = true;
3138                            closingBr = true;
3139                            startingSpace = false;
3140                            lineStart = i;
3141                        } else if (!closingBr)
3142                            brackets -= bracketCount;
3143                        if (bracketCount > 1) {
3144                            i += bracketCount - 1;
3145                        }
3146                    } else if (c == '{' || c == '(') {
3147                        closingBr = false;
3148                        lastOpeningBr = -1;
3149                        endingSpace = -1;
3150                        if (startingSpace) { // first non-space char on the line
3151
startingSpace = false;
3152                            lineStart = i;
3153                        } else if (c == '{') // possible last brace on the line
3154
lastOpeningBr = i;
3155                        brackets++;
3156                    } else if (c == '\"') { // start of String, its content is ignored
3157
insideString = true;
3158                        lastOpeningBr = -1;
3159                        endingSpace = -1;
3160                        if (startingSpace) { // first non-space char on the line
3161
startingSpace = false;
3162                            lineStart = i;
3163                        }
3164                        
3165                    } else if (c == ' ' || c == '\t') {
3166                        if (endingSpace < 0)
3167                            endingSpace = i;
3168                    } else {
3169                        if (startingSpace) { // first non-space char on the line
3170
startingSpace = false;
3171                            lineStart = i;
3172                        }
3173                        if (c != '\n') { // this char is not a whitespace
3174
endingSpace = -1;
3175                            if (lastOpeningBr > -1)
3176                                lastOpeningBr = -1;
3177                        }
3178                    }
3179                } else if (c == '\"' && code.charAt(i-1) != '\\') // end of String
3180
insideString = false;
3181                
3182                i++;
3183            }
3184            while (c != '\n' && i < codeLength);
3185            
3186            if ((i-1 == lineStart && code.charAt(lineStart) == '\n')
3187            || (i-2 == lineStart && code.charAt(lineStart) == '\r')) {
3188                // the line is empty
3189
if (!lastLineEmpty) {
3190                    buffer.append("\n"); // NOI18N
3191
lastLineEmpty = true;
3192                }
3193                continue; // skip second and more empty lines
3194
} else lastLineEmpty = false;
3195            
3196            // adjust indentation level for the line
3197
if (firstClosingBr) { // the line starts with } or )
3198
if (indentLevel > minIndentLevel)
3199                    indentLevel--;
3200                if (brackets < 0)
3201                    brackets = 0; // don't change indentation for the next line
3202
}
3203            
3204            // write indentation space
3205
for (int j=0; j < indentLevel; j++)
3206                buffer.append(tab);
3207            
3208            if (lastOpeningBr > -1 && braceOnNewLine) {
3209                // write the line without last opening brace
3210
// (indentation option "Add New Line Before Brace")
3211
endingSpace = lastOpeningBr;
3212                c = code.charAt(endingSpace-1);
3213                while (c == ' ' || c == '\t') {
3214                    endingSpace--;
3215                    c = code.charAt(endingSpace-1);
3216                }
3217                i = lastOpeningBr;
3218                brackets = 0;
3219            }
3220            
3221            // calculate line end
3222
if (endingSpace < 0) {
3223                if (c == '\n')
3224                    if (code.charAt(i-2) == '\r')
3225                        lineEnd = i-2; // \r\n at the end of the line
3226
else
3227                        lineEnd = i-1; // \n at the end of the line
3228
else
3229                    lineEnd = i; // end of whole code string
3230
} else // skip spaces at the end of the line
3231
lineEnd = endingSpace;
3232            
3233            // write the line
3234
buffer.append(code.substring(lineStart, lineEnd));
3235            buffer.append("\n"); // NOI18N
3236

3237            // calculate indentation level for the next line
3238
if (brackets < 0) {
3239                if (indentLevel > minIndentLevel)
3240                    indentLevel += brackets;
3241                
3242            } else if (brackets > 0)
3243                indentLevel++;
3244        }
3245        return buffer.toString();
3246    }
3247
3248    private String JavaDoc replaceCode(String JavaDoc code, Writer initWriter) throws IOException {
3249        int idx = code.indexOf(RESOURCE_BUNDLE_OPENING_CODE);
3250        if (idx >= 0) {
3251            int endIdx = code.indexOf(RESOURCE_BUNDLE_CLOSING_CODE,
3252                                      idx + RESOURCE_BUNDLE_OPENING_CODE.length());
3253            if (endIdx >= 0) {
3254                String JavaDoc bundleLocation = code.substring(idx + RESOURCE_BUNDLE_OPENING_CODE.length(), endIdx);
3255                if (bundleVariables == null) {
3256                    bundleVariables = new HashMap();
3257                }
3258                String JavaDoc varName = bundleVariables.get(bundleLocation);
3259                if (varName == null) {
3260                    varName = formModel.getCodeStructure().getExternalVariableName(ResourceBundle.class, "bundle", true); // NOI18N
3261
bundleVariables.put(bundleLocation, varName);
3262                    initWriter.write("java.util.ResourceBundle " + varName + " = " // NOI18N
3263
+ code.substring(idx, endIdx + 1) + "; // NOI18N\n"); // NOI18N
3264
}
3265                code = code.substring(0, idx) + varName + code.substring(endIdx + 1);
3266            }
3267        }
3268        return code;
3269    }
3270
3271    /**
3272     * Class for filtering generated code - processing special marks in the code
3273     * (provided by properties/property editors). This way e.g. code for
3274     * ResourceBundle.getBundle is optimized (caching the bundle in a variable)
3275     * or line comments for property setters are placed correctly.
3276     * [In future pre-init and post-init code could be done this way as well
3277     * (and it would work also for nested properties or layout constraints).]
3278     * To work correctly, this class requires to be given complete statements
3279     * (so it can add a preceding or following statement).
3280     */

3281    private class CodeWriter {
3282        private Writer writer;
3283        private boolean inMethod;
3284
3285        CodeWriter(Writer writer, boolean method) {
3286            this.writer = writer;
3287            this.inMethod = method;
3288        }
3289
3290        void write(String JavaDoc str) throws IOException {
3291            int idx = str.indexOf(CODE_MARK);
3292            if (idx >= 0) {
3293                StringBuilder JavaDoc buf = new StringBuilder JavaDoc(str.length());
3294                if (idx > 0) {
3295                    buf.append(str.substring(0, idx));
3296                }
3297                String JavaDoc lineComment = null;
3298
3299                do {
3300                    String JavaDoc part;
3301                    if (str.startsWith(MARKED_PROPERTY_CODE, idx)) {
3302                        int sub = idx + MARKED_PROPERTY_CODE.length();
3303                        idx = str.indexOf(CODE_MARK, sub);
3304                        part = idx < 0 ? str.substring(sub) : str.substring(sub, idx);
3305                        if (inMethod) {
3306                            part = replaceCode(part, writer);
3307                        } // can't replace in field variable init
3308
}
3309                    else if (str.startsWith(PROPERTY_LINE_COMMENT, idx)) {
3310                        int sub = idx + PROPERTY_LINE_COMMENT.length();
3311                        idx = str.indexOf(CODE_MARK, sub);
3312                        String JavaDoc lc = idx < 0 ? str.substring(sub) : str.substring(sub, idx);
3313                        if (lineComment == null)
3314                            lineComment = lc;
3315                        else if (!lineComment.equals(lc))
3316                            lineComment = lineComment + " " + lc; // NOI18N
3317
continue;
3318                    }
3319                    else {
3320                        int sub = idx;
3321                        idx = str.indexOf(CODE_MARK, sub);
3322                        part = idx < 0 ? str.substring(sub) : str.substring(sub, idx);
3323                    }
3324                    if (lineComment != null) {
3325                        int eol = part.indexOf('\n');
3326                        if (eol >= 0) {
3327                            buf.append(part.substring(0, eol));
3328                            buf.append(" // "); // NOI18N
3329
buf.append(lineComment);
3330                            buf.append("\n"); // NOI18N
3331
part = part.substring(eol+1);
3332                            lineComment = null;
3333                        }
3334                    }
3335                    buf.append(part);
3336                }
3337                while (idx >= 0);
3338
3339                if (lineComment != null) {
3340                    buf.append(" // "); // NOI18N
3341
buf.append(lineComment);
3342                }
3343
3344                str = buf.toString();
3345            }
3346            writer.write(str);
3347        }
3348
3349        Writer getWriter() {
3350            return writer;
3351        }
3352
3353        void clearBuffer() {
3354            if (writer instanceof StringWriter) {
3355                StringBuffer JavaDoc buf = ((StringWriter)writer).getBuffer();
3356                buf.delete(0, buf.length());
3357            }
3358        }
3359
3360        public String JavaDoc extractString() {
3361            String JavaDoc str = writer.toString();
3362            clearBuffer();
3363            return str;
3364        }
3365    }
3366
3367    //
3368
// {{{ FormListener
3369
//
3370

3371    private class FormListener implements FormModelListener {
3372
3373        public void formChanged(FormModelEvent[] events) {
3374            if (events == null)
3375                return;
3376
3377            boolean modifying = false;
3378            boolean toBeSaved = false;
3379            boolean toBeClosed = false;
3380
3381            for (int i=0; i < events.length; i++) {
3382                FormModelEvent ev = events[i];
3383
3384                // form loaded
3385
if (ev.getChangeType() == FormModelEvent.FORM_LOADED) {
3386                    if (formModel.getSettings().getListenerGenerationStyle() == CEDL_MAINCLASS)
3387                        listenersInMainClass_lastSet =
3388                            formModel.getFormEvents().getCEDLTypes();
3389                    continue;
3390                }
3391
3392                if (ev.isModifying())
3393                    modifying = true;
3394
3395                if (ev.getChangeType() == FormModelEvent.EVENT_HANDLER_ADDED) {
3396                    String JavaDoc handlerName = ev.getEventHandler();
3397                    String JavaDoc bodyText = ev.getNewEventHandlerContent();
3398                    if ((ev.getCreatedDeleted() || bodyText != null) && ev.getComponent().isInModel()) {
3399                        if (!ev.getCreatedDeleted())
3400                            ev.setOldEventHandlerContent(
3401                                getEventHandlerText(handlerName));
3402
3403                        generateEventHandler(handlerName,
3404                                            (ev.getComponentEvent() == null) ?
3405                                                formModel.getFormEvents().getOriginalListenerMethod(handlerName) :
3406                                                ev.getComponentEvent().getListenerMethod(),
3407                                             bodyText);
3408                    }
3409                    if (events.length == 1 && bodyText == null)
3410                        gotoEventHandler(handlerName);
3411                }
3412                else if (ev.getChangeType() == FormModelEvent.EVENT_HANDLER_REMOVED) {
3413                    if (ev.getCreatedDeleted()) {
3414                        String JavaDoc handlerName = ev.getEventHandler();
3415                        ev.setOldEventHandlerContent(
3416                            getEventHandlerText(handlerName));
3417                        deleteEventHandler(handlerName);
3418                    }
3419                }
3420                else if (ev.getChangeType() == FormModelEvent.EVENT_HANDLER_RENAMED) {
3421                    renameEventHandler(ev.getOldEventHandler(),
3422                                       ev.getNewEventHandler());
3423                }
3424                else if (ev.getChangeType() == FormModelEvent.FORM_TO_BE_SAVED)
3425                    toBeSaved = true;
3426                else if (ev.getChangeType() == FormModelEvent.FORM_TO_BE_CLOSED)
3427                    toBeClosed = true;
3428            }
3429
3430            if (modifying)
3431                codeUpToDate = false;
3432
3433            if ((!codeUpToDate && toBeSaved) || (isJavaEditorDisplayed())) {
3434        regenerateCode();
3435            }
3436
3437            if (toBeSaved) {
3438                RADComponent[] components =
3439                    formModel.getModelContainer().getSubBeans();
3440                for (int i=0; i < components.length; i++)
3441                    serializeComponentsRecursively(components[i]);
3442            }
3443        }
3444        
3445        private boolean isJavaEditorDisplayed() {
3446            boolean showing = false;
3447            if (EventQueue.isDispatchThread()) { // issue 91715
3448
JEditorPane JavaDoc[] jeditPane = FormEditor.getFormDataObject(formModel).getFormEditorSupport().getOpenedPanes();
3449                if (jeditPane != null) {
3450                    for (int i=0; i<jeditPane.length; i++) {
3451                        if (showing = jeditPane[i].isShowing()) {
3452                            break;
3453                        }
3454                    }
3455                }
3456            }
3457            return showing;
3458        }
3459        
3460        private void serializeComponentsRecursively(RADComponent comp) {
3461            Object JavaDoc value = comp.getAuxValue(AUX_CODE_GENERATION);
3462            if (comp.hasHiddenState()
3463                    || (value != null && VALUE_SERIALIZE.equals(value))) {
3464                String JavaDoc serializeTo =(String JavaDoc)comp.getAuxValue(AUX_SERIALIZE_TO);
3465                if (serializeTo != null) {
3466                    try {
3467                        FileObject fo = formEditorSupport.getFormDataObject().getPrimaryFile();
3468                        FileObject serFile = fo.getParent().getFileObject(serializeTo, "ser"); // NOI18N
3469
if (serFile == null) {
3470                            serFile = fo.getParent().createData(serializeTo, "ser"); // NOI18N
3471
}
3472                        if (serFile != null) {
3473                            FileLock lock = null;
3474                            ObjectOutputStream oos = null;
3475                            try {
3476                                lock = serFile.lock();
3477                                oos = new OOS(serFile.getOutputStream(lock));
3478                                if (comp instanceof RADVisualContainer) {
3479                                    // [PENDING - remove temporarily the subcomponents]
3480
}
3481                                oos.writeObject(comp.getBeanInstance());
3482                            } finally {
3483                                if (oos != null) oos.close();
3484                                if (lock != null) lock.releaseLock();
3485                            }
3486                        } else {
3487                            // [PENDING - handle problem]
3488
}
3489                    } catch (java.io.NotSerializableException JavaDoc e) {
3490                        e.printStackTrace();
3491                        // [PENDING - notify error]
3492
} catch (java.io.IOException JavaDoc e) {
3493                        e.printStackTrace();
3494                        // [PENDING - notify error]
3495
} catch (Exception JavaDoc e) {
3496                        e.printStackTrace();
3497                        // [PENDING - notify error]
3498
}
3499                } else {
3500                    // [PENDING - notify error]
3501
}
3502            }
3503            if (comp instanceof ComponentContainer) {
3504                RADComponent[] children =((ComponentContainer)comp).getSubBeans();
3505                for (int i = 0; i < children.length; i++) {
3506                    serializeComponentsRecursively(children[i]);
3507                }
3508            }
3509        }
3510    }
3511
3512    // hacked ObjectOutputStream - to replace special values used by property
3513
// editors (like SuperColor from ColorEditor or NbImageIcon from IconEditor)
3514
private static class OOS extends ObjectOutputStream {
3515        OOS(OutputStream out) throws IOException {
3516            super(out);
3517            enableReplaceObject(true);
3518        }
3519
3520        protected Object JavaDoc replaceObject(Object JavaDoc obj) throws IOException {
3521            if (obj.getClass().getName().startsWith("org.netbeans.") // NOI18N
3522
|| obj.getClass().getName().startsWith("org.openide.")) // NOI18N
3523
{
3524                if (obj instanceof java.awt.Color JavaDoc)
3525                    return new java.awt.Color JavaDoc(((java.awt.Color JavaDoc)obj).getRGB());
3526                if (obj instanceof javax.swing.ImageIcon JavaDoc)
3527                    return new javax.swing.ImageIcon JavaDoc(
3528                        ((javax.swing.ImageIcon JavaDoc)obj).getImage());
3529            }
3530            return obj;
3531        }
3532    }
3533
3534    //
3535
// {{{ CodeGenerateEditor
3536
//
3537

3538    final public static class CodeGenerateEditor extends PropertyEditorSupport
3539    {
3540        private RADComponent component;
3541
3542        /** Display Names for alignment. */
3543        private static final String JavaDoc generateName =
3544            FormUtils.getBundleString("VALUE_codeGen_generate"); // NOI18N
3545
private static final String JavaDoc serializeName =
3546            FormUtils.getBundleString("VALUE_codeGen_serialize"); // NOI18N
3547

3548        public CodeGenerateEditor(RADComponent component) {
3549            this.component = component;
3550        }
3551
3552        /** @return names of the possible directions */
3553        public String JavaDoc[] getTags() {
3554            if (component.hasHiddenState()) {
3555                return new String JavaDoc[] { serializeName } ;
3556            } else {
3557                return new String JavaDoc[] { generateName, serializeName } ;
3558            }
3559        }
3560
3561        /** @return text for the current value */
3562        public String JavaDoc getAsText() {
3563            Integer JavaDoc value =(Integer JavaDoc)getValue();
3564            if (value.equals(VALUE_SERIALIZE)) return serializeName;
3565            else return generateName;
3566        }
3567
3568        /** Setter.
3569         * @param str string equal to one value from directions array
3570         */

3571        public void setAsText(String JavaDoc str) {
3572            if (component.hasHiddenState()) {
3573                setValue(VALUE_SERIALIZE);
3574            } else {
3575                if (serializeName.equals(str)) {
3576                    setValue(VALUE_SERIALIZE);
3577                } else if (generateName.equals(str)) {
3578                    setValue(VALUE_GENERATE_CODE);
3579                }
3580            }
3581        }
3582    }
3583
3584    // }}}
3585

3586    //
3587
// {{{ CodeProperty
3588
//
3589

3590    private class CodeProperty extends FormProperty {
3591        // using FormProperty to be able to disable change firing for temporary
3592
// changes in CodeCustomizer
3593
private String JavaDoc auxKey;
3594        private RADComponent component;
3595        
3596        CodeProperty(RADComponent metacomp,
3597                     String JavaDoc propertyName, String JavaDoc auxKey ,
3598                     String JavaDoc displayName, String JavaDoc shortDescription)
3599        {
3600            super(propertyName, String JavaDoc.class, displayName, null);
3601            setShortDescription(shortDescription); // FormProperty adds the type to the tooltip
3602
this.auxKey = auxKey;
3603            component = metacomp;
3604            try {
3605                reinstateProperty();
3606            }
3607            catch (Exception JavaDoc ex) { // should not happen
3608
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
3609            }
3610        }
3611
3612        public void setTargetValue(Object JavaDoc value) {
3613            if (value != null && !(value instanceof String JavaDoc))
3614                throw new IllegalArgumentException JavaDoc();
3615
3616            Object JavaDoc oldValue = getTargetValue();
3617
3618            if (value != null && !value.equals("")) // NOI18N
3619
component.setAuxValue(auxKey, value);
3620            else if (component.getAuxValue(auxKey) != null) {
3621                component.getAuxValues().remove(auxKey);
3622            }
3623        }
3624
3625        public Object JavaDoc getTargetValue() {
3626            Object JavaDoc value = component.getAuxValue(auxKey);
3627            if (value == null)
3628                value = ""; // NOI18N
3629
return value;
3630        }
3631
3632        public boolean supportsDefaultValue () {
3633            return true;
3634        }
3635
3636        public Object JavaDoc getDefaultValue() {
3637            return ""; // NOI18N
3638
}
3639
3640        protected void propertyValueChanged(Object JavaDoc old, Object JavaDoc current) {
3641            super.propertyValueChanged(old, current);
3642            if (isChangeFiring()) {
3643                formModel.fireSyntheticPropertyChanged(
3644                    component, getName(), old, current);
3645                if (component.getNodeReference() != null) {
3646                    component.getNodeReference().firePropertyChangeHelper(
3647                        getName(), null, null);
3648                }
3649            }
3650        }
3651
3652        public PropertyEditor getExpliciteEditor() {
3653            return new PropertyEditorSupport() {
3654                public Component getCustomEditor() {
3655                    return new CustomCodeEditor(CodeProperty.this,
3656                                                FormEditor.createCodeEditorPane(formModel));
3657                }
3658
3659                public boolean supportsCustomEditor() {
3660                    return true;
3661                }
3662            };
3663        }
3664
3665        public boolean canWrite() {
3666            return JavaCodeGenerator.this.canGenerate && !formModel.isReadOnly();
3667        }
3668    }
3669
3670    // }}}
3671

3672    // Properties
3673

3674    private class VariablesModifierProperty extends PropertySupport.ReadWrite {
3675        
3676        private VariablesModifierProperty() {
3677            super(PROP_VARIABLE_MODIFIER,
3678                Integer JavaDoc.class,
3679                FormUtils.getBundleString("PROP_VARIABLES_MODIFIER"), // NOI18N
3680
FormUtils.getBundleString("HINT_VARIABLES_MODIFIER")); // NOI18N
3681
}
3682            
3683        public void setValue(Object JavaDoc value) {
3684            if (!(value instanceof Integer JavaDoc))
3685                throw new IllegalArgumentException JavaDoc();
3686            
3687            Integer JavaDoc oldValue = (Integer JavaDoc)getValue();
3688            Integer JavaDoc newValue = (Integer JavaDoc)value;
3689            int varType;
3690            int variablesModifier = newValue.intValue();
3691            if (formModel.getSettings().getVariablesLocal()) {
3692                varType = CodeVariable.LOCAL | (variablesModifier & CodeVariable.FINAL); // | CodeVariable.EXPLICIT_DECLARATION;
3693
} else varType = CodeVariable.FIELD | variablesModifier;
3694
3695            formModel.getCodeStructure().setDefaultVariableType(varType);
3696            formModel.getSettings().setVariablesModifier(variablesModifier);
3697            formModel.fireSyntheticPropertyChanged(null, PROP_VARIABLE_MODIFIER, oldValue, newValue);
3698            FormEditor formEditor = FormEditor.getFormEditor(formModel);
3699            formEditor.getFormRootNode().firePropertyChangeHelper(
3700                PROP_VARIABLE_MODIFIER, oldValue, newValue);
3701        }
3702        
3703        public Object JavaDoc getValue() {
3704            return new Integer JavaDoc(formModel.getSettings().getVariablesModifier());
3705        }
3706
3707        public boolean supportsDefaultValue() {
3708            return true;
3709        }
3710        
3711        public void restoreDefaultValue() {
3712            setValue(new Integer JavaDoc(FormLoaderSettings.getInstance().getVariablesModifier()));
3713        }
3714        
3715        public boolean isDefaultValue() {
3716            return (formModel.getSettings().getVariablesModifier() ==
3717                FormLoaderSettings.getInstance().getVariablesModifier());
3718        }
3719        
3720        public boolean canWrite() {
3721            return JavaCodeGenerator.this.canGenerate && !JavaCodeGenerator.this.formModel.isReadOnly();
3722        }
3723        
3724        public PropertyEditor getPropertyEditor() {
3725            boolean local = formModel.getSettings().getVariablesLocal();
3726            return local ? new ModifierEditor(Modifier.FINAL) :
3727                new ModifierEditor(Modifier.PUBLIC
3728                    | Modifier.PROTECTED
3729                    | Modifier.PRIVATE
3730                    | Modifier.STATIC
3731                    | Modifier.FINAL
3732                    | Modifier.TRANSIENT
3733                    | Modifier.VOLATILE);
3734        }
3735        
3736    }
3737    
3738    private class LocalVariablesProperty extends PropertySupport.ReadWrite {
3739
3740        private LocalVariablesProperty() {
3741            super(PROP_VARIABLE_LOCAL,
3742                Boolean.TYPE,
3743                FormUtils.getBundleString("PROP_VARIABLES_LOCAL"), // NOI18N
3744
FormUtils.getBundleString("HINT_VARIABLES_LOCAL")); // NOI18N
3745
}
3746        
3747        public void setValue(Object JavaDoc value) {
3748            if (!(value instanceof Boolean JavaDoc))
3749                throw new IllegalArgumentException JavaDoc();
3750            if (value.equals(getValue())) return;
3751            
3752            Boolean JavaDoc oldValue = (Boolean JavaDoc)getValue();
3753            Boolean JavaDoc newValue = (Boolean JavaDoc)value;
3754            FormSettings formSettings = formModel.getSettings();
3755            boolean variablesLocal = newValue.booleanValue();
3756            int variablesModifier = variablesLocal ? (formSettings.getVariablesModifier() & CodeVariable.FINAL)
3757                : formSettings.getVariablesModifier();
3758            Integer JavaDoc oldModif = new Integer JavaDoc(formModel.getSettings().getVariablesModifier());
3759            Integer JavaDoc newModif = new Integer JavaDoc(variablesModifier);
3760            int varType = variablesLocal ?
3761                CodeVariable.LOCAL | variablesModifier // | CodeVariable.EXPLICIT_DECLARATION
3762
: CodeVariable.FIELD | variablesModifier;
3763
3764            formModel.getCodeStructure().setDefaultVariableType(varType);
3765            formSettings.setVariablesLocal(variablesLocal);
3766            formSettings.setVariablesModifier(variablesModifier);
3767            formModel.fireSyntheticPropertyChanged(null, PROP_VARIABLE_LOCAL, oldValue, newValue);
3768            formModel.fireSyntheticPropertyChanged(null, PROP_VARIABLE_MODIFIER, oldModif, newModif);
3769            FormEditor formEditor = FormEditor.getFormEditor(formModel);
3770            FormNode formRootNode = formEditor.getFormRootNode();
3771            formRootNode.firePropertyChangeHelper(
3772                PROP_VARIABLE_LOCAL, oldValue, newValue);
3773            formRootNode.firePropertyChangeHelper(
3774                PROP_VARIABLE_MODIFIER, oldModif, newModif);
3775        }
3776        
3777        public Object JavaDoc getValue() {
3778            return Boolean.valueOf(formModel.getSettings().getVariablesLocal());
3779        }
3780        
3781        public boolean supportsDefaultValue() {
3782            return true;
3783        }
3784        
3785        public void restoreDefaultValue() {
3786            setValue(Boolean.valueOf(FormLoaderSettings.getInstance().getVariablesLocal()));
3787        }
3788        
3789        public boolean isDefaultValue() {
3790            return (formModel.getSettings().getVariablesLocal() ==
3791                FormLoaderSettings.getInstance().getVariablesLocal());
3792        }
3793        
3794        public boolean canWrite() {
3795            return JavaCodeGenerator.this.canGenerate && !JavaCodeGenerator.this.formModel.isReadOnly();
3796        }
3797        
3798    }
3799    
3800    private class GenerateMnemonicsCodeProperty extends PropertySupport.ReadWrite {
3801        
3802        private GenerateMnemonicsCodeProperty() {
3803            super(PROP_GENERATE_MNEMONICS,
3804                Boolean.TYPE,
3805                FormUtils.getBundleString("PROP_GENERATE_MNEMONICS"), // NOI18N
3806
FormUtils.getBundleString("HINT_GENERATE_MNEMONICS2")); // NOI18N
3807
}
3808            
3809        public void setValue(Object JavaDoc value) {
3810            if (!(value instanceof Boolean JavaDoc))
3811                throw new IllegalArgumentException JavaDoc();
3812            
3813            Boolean JavaDoc oldValue = (Boolean JavaDoc)getValue();
3814            Boolean JavaDoc newValue = (Boolean JavaDoc)value;
3815            formModel.getSettings().setGenerateMnemonicsCode(newValue.booleanValue());
3816            formModel.fireSyntheticPropertyChanged(null, PROP_GENERATE_MNEMONICS, oldValue, newValue);
3817            FormEditor formEditor = FormEditor.getFormEditor(formModel);
3818            formEditor.getFormRootNode().firePropertyChangeHelper(
3819                PROP_GENERATE_MNEMONICS, oldValue, newValue);
3820        }
3821        
3822        public Object JavaDoc getValue() {
3823            return Boolean.valueOf(formModel.getSettings().getGenerateMnemonicsCode());
3824        }
3825        
3826        public boolean canWrite() {
3827            return JavaCodeGenerator.this.canGenerate && !JavaCodeGenerator.this.formModel.isReadOnly();
3828        }
3829        
3830        public boolean supportsDefaultValue() {
3831            return true;
3832        }
3833        
3834        public void restoreDefaultValue() {
3835            setValue(Boolean.valueOf(FormLoaderSettings.getInstance().getGenerateMnemonicsCode()));
3836        }
3837        
3838        public boolean isDefaultValue() {
3839            return (formModel.getSettings().getGenerateMnemonicsCode() ==
3840                FormLoaderSettings.getInstance().getGenerateMnemonicsCode());
3841        }
3842        
3843    }
3844
3845    private class ListenerGenerationStyleProperty extends PropertySupport.ReadWrite {
3846        
3847        private ListenerGenerationStyleProperty() {
3848            super(PROP_LISTENER_GENERATION_STYLE,
3849                Integer JavaDoc.class,
3850                FormUtils.getBundleString("PROP_LISTENER_GENERATION_STYLE"), // NOI18N
3851
FormUtils.getBundleString("HINT_LISTENER_GENERATION_STYLE")); // NOI18N
3852
}
3853            
3854        public void setValue(Object JavaDoc value) {
3855            if (!(value instanceof Integer JavaDoc))
3856                throw new IllegalArgumentException JavaDoc();
3857            
3858            Integer JavaDoc oldValue = (Integer JavaDoc)getValue();
3859            Integer JavaDoc newValue = (Integer JavaDoc)value;
3860            formModel.getSettings().setListenerGenerationStyle(newValue.intValue());
3861            formModel.fireSyntheticPropertyChanged(null, PROP_LISTENER_GENERATION_STYLE, oldValue, newValue);
3862            FormEditor formEditor = FormEditor.getFormEditor(formModel);
3863            formEditor.getFormRootNode().firePropertyChangeHelper(
3864                PROP_LISTENER_GENERATION_STYLE, oldValue, newValue);
3865        }
3866        
3867        public Object JavaDoc getValue() {
3868            return new Integer JavaDoc(formModel.getSettings().getListenerGenerationStyle());
3869        }
3870
3871        public boolean supportsDefaultValue() {
3872            return true;
3873        }
3874        
3875        public void restoreDefaultValue() {
3876            setValue(new Integer JavaDoc(FormLoaderSettings.getInstance().getListenerGenerationStyle()));
3877        }
3878        
3879        public boolean isDefaultValue() {
3880            return (formModel.getSettings().getListenerGenerationStyle() ==
3881                FormLoaderSettings.getInstance().getListenerGenerationStyle());
3882        }
3883        
3884        public boolean canWrite() {
3885            return JavaCodeGenerator.this.canGenerate && !JavaCodeGenerator.this.formModel.isReadOnly();
3886        }
3887        
3888        public PropertyEditor getPropertyEditor() {
3889            return new FormLoaderSettingsBeanInfo.ListenerGenerationStyleEditor();
3890        }
3891        
3892    }
3893
3894    // analogical to ListenerGenerationStyleProperty ...
3895
private class LayoutCodeTargetProperty extends PropertySupport.ReadWrite {
3896        
3897        private LayoutCodeTargetProperty() {
3898            super(FormLoaderSettings.PROP_LAYOUT_CODE_TARGET,
3899                Integer JavaDoc.class,
3900                FormUtils.getBundleString("PROP_LAYOUT_CODE_TARGET"), // NOI18N
3901
FormUtils.getBundleString("HINT_LAYOUT_CODE_TARGET")); // NOI18N
3902
}
3903            
3904        public void setValue(Object JavaDoc value) {
3905            if (!(value instanceof Integer JavaDoc))
3906                throw new IllegalArgumentException JavaDoc();
3907            
3908            Integer JavaDoc oldValue = (Integer JavaDoc)getValue();
3909            Integer JavaDoc newValue = (Integer JavaDoc)value;
3910            formModel.getSettings().setLayoutCodeTarget(newValue.intValue());
3911            FormEditor formEditor = FormEditor.getFormEditor(formModel);
3912            formEditor.updateProjectForNaturalLayout();
3913            formModel.fireSyntheticPropertyChanged(null, FormLoaderSettings.PROP_LAYOUT_CODE_TARGET, oldValue, newValue);
3914            formEditor.getFormRootNode().firePropertyChangeHelper(
3915                FormLoaderSettings.PROP_LAYOUT_CODE_TARGET, oldValue, newValue);
3916        }
3917
3918        public Object JavaDoc getValue() {
3919            return new Integer JavaDoc(formModel.getSettings().getLayoutCodeTarget());
3920        }
3921
3922        public boolean supportsDefaultValue() {
3923            return true;
3924        }
3925
3926        public void restoreDefaultValue() {
3927            setValue(new Integer JavaDoc(FormLoaderSettings.getInstance().getLayoutCodeTarget()));
3928        }
3929
3930        public boolean isDefaultValue() {
3931            return (formModel.getSettings().getLayoutCodeTarget() ==
3932                    FormLoaderSettings.getInstance().getLayoutCodeTarget());
3933        }
3934
3935        public boolean canWrite() {
3936            return JavaCodeGenerator.this.canGenerate && !JavaCodeGenerator.this.formModel.isReadOnly();
3937        }
3938
3939        public PropertyEditor getPropertyEditor() {
3940            return new FormLoaderSettingsBeanInfo.LayoutCodeTargetEditor(true);
3941        }
3942
3943    }
3944}
3945
Popular Tags