0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.form;
0043:
0044: import org.openide.*;
0045: import org.openide.filesystems.*;
0046: import org.openide.nodes.*;
0047: import org.openide.text.IndentEngine;
0048:
0049: import org.netbeans.api.editor.fold.*;
0050:
0051: import org.netbeans.api.java.classpath.ClassPath;
0052:
0053: import com.sun.source.tree.ClassTree;
0054: import com.sun.source.tree.ExpressionTree;
0055: import com.sun.source.tree.Tree;
0056: import com.sun.source.util.TreePath;
0057: import java.util.logging.Level;
0058: import java.util.logging.Logger;
0059: import javax.lang.model.element.Element;
0060: import javax.lang.model.element.TypeElement;
0061: import javax.lang.model.type.TypeMirror;
0062: import javax.swing.JEditorPane;
0063: import org.netbeans.api.editor.guards.InteriorSection;
0064: import org.netbeans.api.editor.guards.SimpleSection;
0065: import org.netbeans.api.java.source.CancellableTask;
0066: import org.netbeans.api.java.source.CompilationController;
0067: import org.netbeans.api.java.source.JavaSource;
0068: import org.netbeans.api.java.source.TreeMaker;
0069: import org.netbeans.api.java.source.WorkingCopy;
0070:
0071: import org.netbeans.modules.form.editors.ModifierEditor;
0072: import org.netbeans.modules.form.editors.CustomCodeEditor;
0073: import org.netbeans.modules.form.codestructure.*;
0074: import org.netbeans.modules.form.layoutsupport.LayoutSupportManager;
0075: import org.netbeans.modules.form.layoutdesign.LayoutComponent;
0076: import org.netbeans.modules.form.layoutdesign.support.SwingLayoutCodeGenerator;
0077:
0078: import java.awt.*;
0079: import java.beans.*;
0080: import java.io.*;
0081: import java.lang.reflect.*;
0082: import java.util.*;
0083: import org.netbeans.api.editor.guards.GuardedSection;
0084: import org.openide.explorer.propertysheet.ExPropertyEditor;
0085: import org.openide.explorer.propertysheet.PropertyEnv;
0086:
0087: /**
0088: * JavaCodeGenerator is the default code generator which produces a Java source
0089: * for the form.
0090: *
0091: * @author Ian Formanek, Jan Stola
0092: */
0093:
0094: class JavaCodeGenerator extends CodeGenerator {
0095:
0096: static final String PROP_VARIABLE_MODIFIER = "modifiers"; // NOI18N
0097: static final String PROP_TYPE_PARAMETERS = "typeParameters"; // NOI18N
0098: static final String PROP_VARIABLE_LOCAL = "useLocalVariable"; // NOI18N
0099: static final String PROP_SERIALIZE_TO = "serializeTo"; // NOI18N
0100: static final String PROP_CODE_GENERATION = "codeGeneration"; // NOI18N
0101: static final String PROP_CREATE_CODE_PRE = "creationCodePre"; // NOI18N
0102: static final String PROP_CREATE_CODE_POST = "creationCodePost"; // NOI18N
0103: static final String PROP_CREATE_CODE_CUSTOM = "creationCodeCustom"; // NOI18N
0104: static final String PROP_INIT_CODE_PRE = "initCodePre"; // NOI18N
0105: static final String PROP_INIT_CODE_POST = "initCodePost"; // NOI18N
0106: static final String PROP_LISTENERS_POST = "listenersCodePost"; // NOI18N
0107: static final String PROP_ADDING_PRE = "addingCodePre"; // NOI18N
0108: static final String PROP_ADDING_POST = "addingCodePost"; // NOI18N
0109: static final String PROP_LAYOUT_PRE = "layoutCodePre"; // NOI18N
0110: static final String PROP_LAYOUT_POST = "layoutCodePost"; // NOI18N
0111: static final String PROP_ALL_SET_POST = "allCodePost"; // NOI18N
0112: static final String PROP_DECLARATION_PRE = "declarationPre"; // NOI18N
0113: static final String PROP_DECLARATION_POST = "declarationPost"; // NOI18N
0114: static final String PROP_GENERATE_MNEMONICS = "generateMnemonicsCode"; // Mnemonics support // NOI18N
0115: static final String PROP_LISTENER_GENERATION_STYLE = "listenerGenerationStyle"; // NOI18N
0116:
0117: static final String AUX_VARIABLE_MODIFIER = "JavaCodeGenerator_VariableModifier"; // NOI18N
0118: static final String AUX_TYPE_PARAMETERS = "JavaCodeGenerator_TypeParameters"; // NOI18N
0119: static final String AUX_VARIABLE_LOCAL = "JavaCodeGenerator_VariableLocal"; // NOI18N
0120: static final String AUX_SERIALIZE_TO = "JavaCodeGenerator_SerializeTo"; // NOI18N
0121: static final String AUX_CODE_GENERATION = "JavaCodeGenerator_CodeGeneration"; // NOI18N
0122: static final String AUX_CREATE_CODE_PRE = "JavaCodeGenerator_CreateCodePre"; // NOI18N
0123: static final String AUX_CREATE_CODE_POST = "JavaCodeGenerator_CreateCodePost"; // NOI18N
0124: static final String AUX_CREATE_CODE_CUSTOM = "JavaCodeGenerator_CreateCodeCustom"; // NOI18N
0125: static final String AUX_INIT_CODE_PRE = "JavaCodeGenerator_InitCodePre"; // NOI18N
0126: static final String AUX_INIT_CODE_POST = "JavaCodeGenerator_InitCodePost"; // NOI18N
0127: static final String AUX_LISTENERS_POST = "JavaCodeGenerator_ListenersCodePost"; // NOI18N
0128: static final String AUX_ADDING_PRE = "JavaCodeGenerator_AddingCodePre"; // NOI18N
0129: static final String AUX_ADDING_POST = "JavaCodeGenerator_AddingCodePost"; // NOI18N
0130: static final String AUX_LAYOUT_PRE = "JavaCodeGenerator_LayoutCodePre"; // NOI18N
0131: static final String AUX_LAYOUT_POST = "JavaCodeGenerator_LayoutCodePost"; // NOI18N
0132: static final String AUX_ALL_SET_POST = "JavaCodeGenerator_allCodePost"; // NOI18N
0133: static final String AUX_DECLARATION_PRE = "JavaCodeGenerator_DeclarationPre"; // NOI18N
0134: static final String AUX_DECLARATION_POST = "JavaCodeGenerator_DeclarationPost"; // NOI18N
0135:
0136: static final Integer VALUE_GENERATE_CODE = new Integer(0);
0137: static final Integer VALUE_SERIALIZE = new Integer(1);
0138:
0139: // types of code generation of event listeners
0140: static final int ANONYMOUS_INNERCLASSES = 0;
0141: static final int CEDL_INNERCLASS = 1;
0142: static final int CEDL_MAINCLASS = 2;
0143:
0144: // types of code generation of layout code
0145: static final int LAYOUT_CODE_AUTO = 0;
0146: static final int LAYOUT_CODE_JDK6 = 1;
0147: static final int LAYOUT_CODE_LIBRARY = 2;
0148:
0149: private static final String EVT_SECTION_PREFIX = "event_"; // NOI18N
0150:
0151: private static final String DEFAULT_LISTENER_CLASS_NAME = "FormListener"; // NOI18N
0152:
0153: static final String CUSTOM_CODE_MARK = "\u001F"; // NOI18N
0154: private static final String CODE_MARK = "*/\n\\"; // NOI18N
0155: private static final String CODE_MARK_END = "*/\n\\0"; // NOI18N
0156: private static final String CODE_MARK_LINE_COMMENT = "*/\n\\1"; // NOI18N
0157: private static final String CODE_MARK_VARIABLE_SUBST = "*/\n\\2"; // NOI18N
0158:
0159: private Map<String, String> repeatedCodeVariables;
0160:
0161: private static Class bindingGroupClass = org.jdesktop.beansbinding.BindingGroup.class;
0162: private String bindingGroupVariable;
0163: private Map<String, String> bindingVariables;
0164: private static String variablesHeader;
0165: private static String variablesFooter;
0166: private static String eventDispatchCodeComment;
0167:
0168: /** The FormLoaderSettings instance */
0169: private static FormLoaderSettings formSettings = FormLoaderSettings
0170: .getInstance();
0171:
0172: private FormModel formModel;
0173: private FormEditorSupport formEditorSupport;
0174:
0175: private boolean initialized = false;
0176: private boolean canGenerate = true;
0177: private boolean codeUpToDate = true;
0178:
0179: private String listenerClassName;
0180: private String listenerVariableName;
0181:
0182: // data needed when listener generation style is CEDL_MAINCLASS
0183: private Class[] listenersInMainClass;
0184: private Class[] listenersInMainClass_lastSet;
0185:
0186: private int emptyLineCounter;
0187: private int emptyLineRequest;
0188:
0189: private Map<RADComponent, java.util.List<FormProperty>> constructorProperties;
0190: private Map<RADComponent, java.util.List<FormProperty>> parentDependentProperties;
0191: private Map<RADComponent, java.util.List<FormProperty>> childrenDependentProperties;
0192:
0193: private SwingLayoutCodeGenerator swingGenerator;
0194:
0195: private static class PropertiesFilter implements
0196: FormProperty.Filter {
0197:
0198: private final java.util.List<FormProperty> properties;
0199:
0200: public PropertiesFilter(java.util.List<FormProperty> properties) {
0201: this .properties = properties;
0202: }
0203:
0204: public boolean accept(FormProperty property) {
0205: return (property.isChanged()
0206: && !ResourceSupport.isInjectedProperty(property) && (properties == null || !properties
0207: .contains(property)))
0208: || property.getPreCode() != null
0209: || property.getPostCode() != null;
0210: }
0211: };
0212:
0213: /** Creates new JavaCodeGenerator */
0214:
0215: // public JavaCodeGenerator() {
0216: // }
0217: public void initialize(FormModel formModel) {
0218: if (!initialized) {
0219: this .formModel = formModel;
0220: FormDataObject formDO = FormEditor
0221: .getFormDataObject(formModel);
0222: formEditorSupport = formDO.getFormEditorSupport();
0223:
0224: if (formDO.getPrimaryFile().canWrite()) {
0225: canGenerate = true;
0226: formModel.addFormModelListener(new FormListener());
0227: } else
0228: canGenerate = false;
0229:
0230: SimpleSection initComponentsSection = formEditorSupport
0231: .getInitComponentSection();
0232: SimpleSection variablesSection = formEditorSupport
0233: .getVariablesSection();
0234:
0235: if (initComponentsSection == null
0236: || variablesSection == null) {
0237: System.err
0238: .println("ERROR: Cannot initialize guarded sections... code generation is disabled."); // NOI18N
0239: canGenerate = false;
0240: }
0241:
0242: initialized = true;
0243: }
0244: }
0245:
0246: /**
0247: * Alows the code generator to provide synthetic properties for specified
0248: * component which are specific to the code generation method. E.g. a
0249: * JavaCodeGenerator will return variableName property, as it generates
0250: * global Java variable for every component
0251: * @param component The RADComponent for which the properties are to be obtained
0252: */
0253: @Override
0254: public Node.Property[] getSyntheticProperties(
0255: final RADComponent component) {
0256: ResourceBundle bundle = FormUtils.getBundle();
0257: java.util.List<Node.Property> propList = new ArrayList<Node.Property>();
0258: if (component == null) {
0259: propList.add(new VariablesModifierProperty());
0260: propList.add(new LocalVariablesProperty());
0261: propList.add(new GenerateMnemonicsCodeProperty());
0262: propList.add(new ListenerGenerationStyleProperty());
0263: propList.add(new LayoutCodeTargetProperty());
0264: } else if (component != formModel.getTopRADComponent()) {
0265:
0266: propList.add(createBeanClassNameProperty(component));
0267:
0268: propList.add(new PropertySupport.ReadWrite(
0269: RADComponent.PROP_NAME, String.class, bundle
0270: .getString("MSG_JC_VariableName"), // NOI18N
0271: bundle.getString("MSG_JC_VariableDesc")) // NOI18N
0272: {
0273: public void setValue(Object value) {
0274: if (!(value instanceof String))
0275: throw new IllegalArgumentException();
0276:
0277: component.rename((String) value);
0278: component.getNodeReference()
0279: .firePropertyChangeHelper(
0280: RADComponent.PROP_NAME,
0281: null, null); // NOI18N
0282: }
0283:
0284: public Object getValue() {
0285: return component.getName();
0286: }
0287:
0288: @Override
0289: public boolean canWrite() {
0290: return JavaCodeGenerator.this .canGenerate
0291: && !component.isReadOnly();
0292: }
0293: });
0294:
0295: final FormProperty modifProp = new FormProperty(
0296: PROP_VARIABLE_MODIFIER, Integer.class, bundle
0297: .getString("MSG_JC_VariableModifiers"), // NOI18N
0298: null) {
0299: public void setTargetValue(Object value) {
0300: if (!(value instanceof Integer))
0301: throw new IllegalArgumentException();
0302:
0303: Object oldValue = getTargetValue();
0304:
0305: CodeStructure codeStructure = formModel
0306: .getCodeStructure();
0307: CodeExpression exp = component.getCodeExpression();
0308: int varType = exp.getVariable().getType();
0309: String varName = component.getName();
0310:
0311: varType &= ~CodeVariable.ALL_MODIF_MASK;
0312: varType |= ((Integer) value).intValue()
0313: & CodeVariable.ALL_MODIF_MASK;
0314:
0315: if ((varType & CodeVariable.ALL_MODIF_MASK) != (formModel
0316: .getSettings().getVariablesModifier() & CodeVariable.ALL_MODIF_MASK)) { // non-default value
0317: component.setAuxValue(AUX_VARIABLE_MODIFIER,
0318: new Integer(varType
0319: & CodeVariable.ALL_MODIF_MASK)); // value
0320: } else { // default value
0321: varType = 0x30DF; // default
0322: if (component
0323: .getAuxValue(AUX_VARIABLE_MODIFIER) != null) {
0324: component.getAuxValues().remove(
0325: AUX_VARIABLE_MODIFIER);
0326: }
0327: }
0328:
0329: String typeParameters = exp.getVariable()
0330: .getDeclaredTypeParameters();
0331: codeStructure.removeExpressionFromVariable(exp);
0332: codeStructure.createVariableForExpression(exp,
0333: varType, typeParameters, varName);
0334: }
0335:
0336: public Object getTargetValue() {
0337: Object val = component
0338: .getAuxValue(AUX_VARIABLE_MODIFIER);
0339: if (val != null)
0340: return val;
0341:
0342: return new Integer(formModel.getSettings()
0343: .getVariablesModifier());
0344: }
0345:
0346: @Override
0347: public boolean supportsDefaultValue() {
0348: return component.getAuxValue(AUX_VARIABLE_LOCAL) == null;
0349: }
0350:
0351: @Override
0352: public Object getDefaultValue() {
0353: return component.getAuxValue(AUX_VARIABLE_LOCAL) == null ? new Integer(
0354: formModel.getSettings()
0355: .getVariablesModifier())
0356: : null;
0357: }
0358:
0359: @Override
0360: protected void propertyValueChanged(Object old,
0361: Object current) {
0362: super .propertyValueChanged(old, current);
0363: if (isChangeFiring()) {
0364: formModel.fireSyntheticPropertyChanged(
0365: component, getName(), old, current);
0366: if (component.getNodeReference() != null) {
0367: component.getNodeReference()
0368: .firePropertyChangeHelper(
0369: getName(), null, null);
0370: }
0371: }
0372: }
0373:
0374: @Override
0375: public boolean canWrite() {
0376: return JavaCodeGenerator.this .canGenerate
0377: && !component.isReadOnly();
0378: }
0379:
0380: @Override
0381: public PropertyEditor getExpliciteEditor() { // getPropertyEditor
0382: Boolean local = (Boolean) component
0383: .getAuxValue(AUX_VARIABLE_LOCAL);
0384: if (local == null)
0385: local = Boolean.valueOf(formModel.getSettings()
0386: .getVariablesLocal());
0387: return Boolean.TRUE.equals(local) ? new ModifierEditor(
0388: Modifier.FINAL)
0389: : new ModifierEditor(Modifier.PUBLIC
0390: | Modifier.PROTECTED
0391: | Modifier.PRIVATE
0392: | Modifier.STATIC | Modifier.FINAL
0393: | Modifier.TRANSIENT
0394: | Modifier.VOLATILE);
0395: }
0396: };
0397: modifProp.setShortDescription(bundle
0398: .getString("MSG_JC_VariableModifiersDesc")); // NOI18N
0399: propList.add(modifProp);
0400:
0401: final FormProperty paramTypesProp = new FormProperty(
0402: PROP_TYPE_PARAMETERS, String.class, bundle
0403: .getString("MSG_JC_TypeParameters"), // NOI18N
0404: null) {
0405: public void setTargetValue(Object value) {
0406: if ((value != null) && !(value instanceof String))
0407: throw new IllegalArgumentException();
0408:
0409: // PENDING check for syntax of the value
0410:
0411: component.setAuxValue(AUX_TYPE_PARAMETERS, value);
0412:
0413: CodeStructure codeStructure = formModel
0414: .getCodeStructure();
0415: CodeExpression exp = component.getCodeExpression();
0416: int varType = exp.getVariable().getType();
0417: String varName = component.getName();
0418:
0419: codeStructure.removeExpressionFromVariable(exp);
0420: codeStructure.createVariableForExpression(exp,
0421: varType, (String) value, varName);
0422: }
0423:
0424: public Object getTargetValue() {
0425: Object value = component
0426: .getAuxValue(AUX_TYPE_PARAMETERS);
0427: return (value == null) ? "" : value; // NOI18N
0428: }
0429:
0430: @Override
0431: public boolean supportsDefaultValue() {
0432: return true;
0433: }
0434:
0435: @Override
0436: public Object getDefaultValue() {
0437: return ""; // NOI18N
0438: }
0439:
0440: @Override
0441: protected void propertyValueChanged(Object old,
0442: Object current) {
0443: super .propertyValueChanged(old, current);
0444: if (isChangeFiring()) {
0445: formModel.fireSyntheticPropertyChanged(
0446: component, getName(), old, current);
0447: if (component.getNodeReference() != null) {
0448: component.getNodeReference()
0449: .firePropertyChangeHelper(
0450: getName(), null, null);
0451: }
0452: }
0453: }
0454:
0455: @Override
0456: public boolean canWrite() {
0457: return JavaCodeGenerator.this .canGenerate
0458: && !component.isReadOnly();
0459: }
0460:
0461: @Override
0462: public PropertyEditor getExpliciteEditor() {
0463: // PENDING replace by property editor that is able to determine
0464: // formal type parameters of this class and can offer you
0465: // a nice visual customizer
0466: return super .getExpliciteEditor();
0467: }
0468: };
0469: paramTypesProp.setShortDescription(bundle
0470: .getString("MSG_JC_TypeParametersDesc")); // NOI18N
0471: propList.add(paramTypesProp);
0472:
0473: FormProperty localProp = new FormProperty(
0474: PROP_VARIABLE_LOCAL, Boolean.TYPE, bundle
0475: .getString("MSG_JC_UseLocalVar"), // NOI18N
0476: null) {
0477: public void setTargetValue(Object value) {
0478: if (!(value instanceof Boolean))
0479: throw new IllegalArgumentException();
0480:
0481: Boolean oldValue = (Boolean) getTargetValue();
0482: // if (value.equals(oldValue)) return;
0483:
0484: CodeStructure codeStructure = formModel
0485: .getCodeStructure();
0486: CodeExpression exp = component.getCodeExpression();
0487: int varType = exp.getVariable().getType();
0488: String varName = component.getName();
0489:
0490: varType &= CodeVariable.FINAL
0491: | ~(CodeVariable.ALL_MODIF_MASK | CodeVariable.SCOPE_MASK);
0492: if (Boolean.TRUE.equals(value))
0493: varType |= CodeVariable.LOCAL;
0494: else
0495: varType |= CodeVariable.FIELD
0496: | formModel.getSettings()
0497: .getVariablesModifier();
0498:
0499: if (((varType & CodeVariable.LOCAL) != 0) != (formModel
0500: .getSettings().getVariablesLocal())) { // non-default value
0501: component
0502: .setAuxValue(AUX_VARIABLE_LOCAL, value);
0503: try {
0504: modifProp.setValue(new Integer(varType
0505: & CodeVariable.ALL_MODIF_MASK));
0506: } catch (Exception ex) { // should not happen
0507: ErrorManager.getDefault().notify(
0508: ErrorManager.INFORMATIONAL, ex);
0509: }
0510: } else { // default value
0511: varType = 0x30DF; // default
0512: if (component.getAuxValue(AUX_VARIABLE_LOCAL) != null) {
0513: component.getAuxValues().remove(
0514: AUX_VARIABLE_LOCAL);
0515: }
0516: try {
0517: modifProp.restoreDefaultValue();
0518: } catch (Exception ex) { // should not happen
0519: ErrorManager.getDefault().notify(
0520: ErrorManager.INFORMATIONAL, ex);
0521: }
0522: }
0523:
0524: String typeParameters = exp.getVariable()
0525: .getDeclaredTypeParameters();
0526: codeStructure.removeExpressionFromVariable(exp);
0527: codeStructure.createVariableForExpression(exp,
0528: varType, typeParameters, varName);
0529: }
0530:
0531: public Object getTargetValue() {
0532: Object val = component
0533: .getAuxValue(AUX_VARIABLE_LOCAL);
0534: if (val != null)
0535: return val;
0536:
0537: return Boolean.valueOf(formModel.getSettings()
0538: .getVariablesLocal());
0539: }
0540:
0541: @Override
0542: public boolean supportsDefaultValue() {
0543: return true;
0544: }
0545:
0546: @Override
0547: public Object getDefaultValue() {
0548: return Boolean.valueOf(formModel.getSettings()
0549: .getVariablesLocal());
0550: }
0551:
0552: @Override
0553: protected void propertyValueChanged(Object old,
0554: Object current) {
0555: super .propertyValueChanged(old, current);
0556: if (isChangeFiring()) {
0557: formModel.fireSyntheticPropertyChanged(
0558: component, getName(), old, current);
0559: if (component.getNodeReference() != null) {
0560: component.getNodeReference()
0561: .firePropertyChangeHelper(
0562: getName(), null, null);
0563: }
0564: }
0565: }
0566:
0567: @Override
0568: public boolean canWrite() {
0569: return JavaCodeGenerator.this .canGenerate
0570: && !component.isReadOnly();
0571: }
0572: };
0573: localProp.setShortDescription(bundle
0574: .getString("MSG_JC_UseLocalVarDesc")); // NOI18N
0575: propList.add(localProp);
0576:
0577: // Mnemonics support - start -
0578: if (javax.swing.JLabel.class.isAssignableFrom(component
0579: .getBeanClass())
0580: || javax.swing.AbstractButton.class
0581: .isAssignableFrom(component.getBeanClass()))
0582: propList.add(new PropertySupport.ReadWrite(
0583: PROP_GENERATE_MNEMONICS, Boolean.TYPE, bundle
0584: .getString("PROP_GENERATE_MNEMONICS"), // NOI18N
0585: bundle.getString("HINT_GENERATE_MNEMONICS2")) // NOI18N
0586: {
0587: public void setValue(Object value) {
0588: Object oldValue = getValue();
0589: component.setAuxValue(
0590: PROP_GENERATE_MNEMONICS, value);
0591: formModel.fireSyntheticPropertyChanged(
0592: component,
0593: PROP_GENERATE_MNEMONICS,
0594: oldValue, value);
0595: component
0596: .getNodeReference()
0597: .firePropertyChangeHelper(
0598: PROP_GENERATE_MNEMONICS,
0599: null, null); // NOI18N
0600: }
0601:
0602: public Object getValue() {
0603: return isUsingMnemonics(component) ? Boolean.TRUE
0604: : Boolean.FALSE;
0605: }
0606:
0607: @Override
0608: public boolean canWrite() {
0609: return JavaCodeGenerator.this .canGenerate
0610: && !component.isReadOnly();
0611: }
0612:
0613: @Override
0614: public boolean supportsDefaultValue() {
0615: return true;
0616: }
0617:
0618: @Override
0619: public void restoreDefaultValue() {
0620: setValue(null);
0621: }
0622: });
0623: // Mnemonics support - end -
0624:
0625: propList.add(new CodeProperty(component,
0626: PROP_CREATE_CODE_CUSTOM, AUX_CREATE_CODE_CUSTOM,
0627: bundle.getString("MSG_JC_CustomCreationCode"), // NOI18N
0628: bundle.getString("MSG_JC_CustomCreationCodeDesc"), // NOI18N
0629: FormModel.FormVersion.BASIC));
0630:
0631: propList.add(new CodeProperty(component,
0632: PROP_CREATE_CODE_PRE, AUX_CREATE_CODE_PRE, bundle
0633: .getString("MSG_JC_PreCreationCode"), // NOI18N
0634: bundle.getString("MSG_JC_PreCreationCodeDesc"), // NOI18N
0635: FormModel.FormVersion.BASIC));
0636: propList.add(new CodeProperty(component,
0637: PROP_CREATE_CODE_POST, AUX_CREATE_CODE_POST, bundle
0638: .getString("MSG_JC_PostCreationCode"), // NOI18N
0639: bundle.getString("MSG_JC_PostCreationCodeDesc"), // NOI18N
0640: FormModel.FormVersion.BASIC));
0641:
0642: propList.add(new CodeProperty(component,
0643: PROP_INIT_CODE_PRE, AUX_INIT_CODE_PRE, bundle
0644: .getString("MSG_JC_PreInitCode"), // NOI18N
0645: bundle.getString("MSG_JC_PreInitCodeDesc"), // NOI18N
0646: FormModel.FormVersion.BASIC));
0647: propList.add(new CodeProperty(component,
0648: PROP_INIT_CODE_POST, AUX_INIT_CODE_POST, bundle
0649: .getString("MSG_JC_PostInitCode"), // NOI18N
0650: bundle.getString("MSG_JC_PostInitCodeDesc"), // NOI18N
0651: FormModel.FormVersion.BASIC));
0652:
0653: propList.add(new CodeProperty(component,
0654: PROP_LISTENERS_POST, AUX_LISTENERS_POST, bundle
0655: .getString("MSG_JC_PostListenersCode"), // NOI18N
0656: bundle.getString("MSG_JC_PostListenersCodeDesc"), // NOI18N
0657: FormModel.FormVersion.NB60));
0658:
0659: if (component.getParentComponent() != null) {
0660: propList.add(new CodeProperty(component,
0661: PROP_ADDING_PRE, AUX_ADDING_PRE, bundle
0662: .getString("MSG_JC_PreAddCode"), // NOI18N
0663: bundle.getString("MSG_JC_PreAddCodeDesc"), // NOI18N
0664: FormModel.FormVersion.NB60));
0665: propList.add(new CodeProperty(component,
0666: PROP_ADDING_POST, AUX_ADDING_POST, bundle
0667: .getString("MSG_JC_PostAddCode"), // NOI18N
0668: bundle.getString("MSG_JC_PostAddCodeDesc"), // NOI18N
0669: FormModel.FormVersion.NB60));
0670: }
0671:
0672: if (component instanceof ComponentContainer) {
0673: propList
0674: .add(new CodeProperty(
0675: component,
0676: PROP_LAYOUT_PRE,
0677: AUX_LAYOUT_PRE,
0678: bundle
0679: .getString("MSG_JC_PrePopulationCode"), // NOI18N
0680: bundle
0681: .getString("MSG_JC_PrePopulationCodeDesc"), // NOI18N
0682: FormModel.FormVersion.NB60));
0683: propList
0684: .add(new CodeProperty(
0685: component,
0686: PROP_LAYOUT_POST,
0687: AUX_LAYOUT_POST,
0688: bundle
0689: .getString("MSG_JC_PostPopulationCode"), // NOI18N
0690: bundle
0691: .getString("MSG_JC_PostPopulationCodeDesc"), // NOI18N
0692: FormModel.FormVersion.NB60));
0693: }
0694:
0695: propList.add(new CodeProperty(component, PROP_ALL_SET_POST,
0696: AUX_ALL_SET_POST, bundle
0697: .getString("MSG_JC_AfterAllSetCode"), // NOI18N
0698: bundle.getString("MSG_JC_AfterAllSetCodeDesc"), // NOI18N
0699: FormModel.FormVersion.NB60));
0700:
0701: propList.add(new CodeProperty(component,
0702: PROP_DECLARATION_PRE, AUX_DECLARATION_PRE, bundle
0703: .getString("MSG_JC_PreDeclaration"), // NOI18N
0704: bundle.getString("MSG_JC_PreDeclarationDesc"), // NOI18N
0705: FormModel.FormVersion.NB60_PRE));
0706: propList.add(new CodeProperty(component,
0707: PROP_DECLARATION_POST, AUX_DECLARATION_POST, bundle
0708: .getString("MSG_JC_PostDeclaration"), // NOI18N
0709: bundle.getString("MSG_JC_PostDeclarationDesc"), // NOI18N
0710: FormModel.FormVersion.NB60_PRE));
0711:
0712: propList.add(new PropertySupport.ReadWrite(
0713: PROP_CODE_GENERATION, Integer.TYPE, bundle
0714: .getString("MSG_JC_CodeGeneration"), // NOI18N
0715: bundle.getString("MSG_JC_CodeGenerationDesc")) // NOI18N
0716: {
0717: public void setValue(Object value) {
0718: if (!(value instanceof Integer))
0719: throw new IllegalArgumentException();
0720:
0721: Object oldValue = getValue();
0722:
0723: if (!getDefaultValue().equals(value))
0724: component.setAuxValue(
0725: AUX_CODE_GENERATION, value);
0726: else if (component
0727: .getAuxValue(AUX_CODE_GENERATION) != null) {
0728: component.getAuxValues().remove(
0729: AUX_CODE_GENERATION);
0730: }
0731:
0732: if (value.equals(VALUE_SERIALIZE)
0733: && component
0734: .getAuxValue(AUX_SERIALIZE_TO) == null)
0735: component
0736: .setAuxValue(
0737: AUX_SERIALIZE_TO,
0738: getDefaultSerializedName(component));
0739:
0740: formModel.fireSyntheticPropertyChanged(
0741: component, PROP_CODE_GENERATION,
0742: oldValue, value);
0743: component.getNodeReference()
0744: .firePropertyChangeHelper(
0745: PROP_CODE_GENERATION, null,
0746: null); // NOI18N
0747: }
0748:
0749: public Object getValue() {
0750: Object value = component
0751: .getAuxValue(AUX_CODE_GENERATION);
0752: if (value == null)
0753: value = getDefaultValue();
0754: return value;
0755: }
0756:
0757: @Override
0758: public boolean canWrite() {
0759: return JavaCodeGenerator.this .canGenerate
0760: && !component.isReadOnly();
0761: }
0762:
0763: @Override
0764: public PropertyEditor getPropertyEditor() {
0765: return new CodeGenerateEditor(component);
0766: }
0767:
0768: private Object getDefaultValue() {
0769: return component.hasHiddenState() ? VALUE_SERIALIZE
0770: : VALUE_GENERATE_CODE;
0771: }
0772: });
0773:
0774: propList.add(new PropertySupport.ReadWrite(
0775: PROP_SERIALIZE_TO, String.class, bundle
0776: .getString("MSG_JC_SerializeTo"), // NOI18N
0777: bundle.getString("MSG_JC_SerializeToDesc")) // NOI18N
0778: {
0779: public void setValue(Object value) {
0780: if (!(value instanceof String))
0781: throw new IllegalArgumentException();
0782:
0783: Object oldValue = getValue();
0784:
0785: if (!"".equals(value)) // NOI18N
0786: component.setAuxValue(AUX_SERIALIZE_TO,
0787: value);
0788: else if (component
0789: .getAuxValue(AUX_SERIALIZE_TO) != null) {
0790: component.getAuxValues().remove(
0791: AUX_SERIALIZE_TO);
0792: }
0793:
0794: formModel.fireSyntheticPropertyChanged(
0795: component, PROP_SERIALIZE_TO,
0796: oldValue, value);
0797: component.getNodeReference()
0798: .firePropertyChangeHelper(
0799: PROP_SERIALIZE_TO, null,
0800: null); // NOI18N
0801: }
0802:
0803: public Object getValue() {
0804: Object value = component
0805: .getAuxValue(AUX_SERIALIZE_TO);
0806: if (value == null)
0807: value = getDefaultSerializedName(component);
0808: return value;
0809: }
0810:
0811: @Override
0812: public boolean canWrite() {
0813: return JavaCodeGenerator.this .canGenerate
0814: && !component.isReadOnly();
0815: }
0816: });
0817: } else if (component instanceof RADVisualComponent) {
0818: propList.add(new PropertySupport.ReadOnly(
0819: FormDesigner.PROP_DESIGNER_SIZE, Dimension.class,
0820: bundle.getString("MSG_DesignerSize"), // NOI18N
0821: bundle.getString("HINT_DesignerSize")) // NOI18N
0822: {
0823: @Override
0824: public void setValue(Object value) {
0825: if (!(value instanceof Dimension))
0826: throw new IllegalArgumentException();
0827: if (!getDefaultValue().equals(value))
0828: component
0829: .setAuxValue(
0830: FormDesigner.PROP_DESIGNER_SIZE,
0831: value);
0832: else if (component
0833: .getAuxValue(FormDesigner.PROP_DESIGNER_SIZE) != null) {
0834: component
0835: .getAuxValues()
0836: .remove(
0837: FormDesigner.PROP_DESIGNER_SIZE);
0838: }
0839: }
0840:
0841: public Object getValue() {
0842: Object value = component
0843: .getAuxValue(FormDesigner.PROP_DESIGNER_SIZE);
0844: if (value == null)
0845: value = getDefaultValue();
0846: return value;
0847: }
0848:
0849: private Object getDefaultValue() {
0850: return new Dimension(400, 300);
0851: }
0852: });
0853: }
0854:
0855: Node.Property[] props = new Node.Property[propList.size()];
0856: propList.toArray(props);
0857: return props;
0858: }
0859:
0860: public static PropertySupport createBeanClassNameProperty(
0861: final RADComponent component) {
0862: final ResourceBundle bundle = FormUtils.getBundle();
0863:
0864: return new PropertySupport.ReadOnly("beanClass", // NOI18N
0865: String.class, bundle.getString("MSG_JC_BeanClass"), // NOI18N
0866: bundle.getString("MSG_JC_BeanClassDesc")) // NOI18N
0867: {
0868: String invalid = null;
0869:
0870: public Object getValue() {
0871: if (!component.isValid()) {
0872: if (invalid == null) {
0873: invalid = bundle
0874: .getString("CTL_LB_InvalidComponent"); // NOI18N
0875: }
0876: return component.getMissingClassName() + ": ["
0877: + invalid + "]"; // NOI18N
0878: }
0879: Class beanClass = component.getBeanClass();
0880: if (beanClass != null) {
0881: return beanClass.toString();
0882: }
0883: return ""; // NOI18N
0884: }
0885:
0886: @Override
0887: public boolean canWrite() {
0888: return false;
0889: }
0890:
0891: @Override
0892: public PropertyEditor getPropertyEditor() {
0893: return new PropertyEditorSupport() {
0894: };
0895: }
0896: };
0897: }
0898:
0899: static void setupComponentFromAuxValues(RADComponent comp) {
0900: Object val = comp
0901: .getAuxValue(JavaCodeGenerator.AUX_VARIABLE_MODIFIER);
0902: int newType = val instanceof Integer ? ((Integer) val)
0903: .intValue() : -1;
0904:
0905: val = comp.getAuxValue(JavaCodeGenerator.AUX_VARIABLE_LOCAL);
0906: if (val instanceof Boolean) {
0907: if (newType == -1) {
0908: newType = 0;
0909: }
0910: newType |= Boolean.TRUE.equals(val) ? CodeVariable.LOCAL
0911: | CodeVariable.EXPLICIT_DECLARATION
0912: : CodeVariable.FIELD;
0913: }
0914:
0915: val = comp.getAuxValue(JavaCodeGenerator.AUX_TYPE_PARAMETERS);
0916: String typeParameters = null;
0917: if (val instanceof String) {
0918: typeParameters = (String) val;
0919: }
0920:
0921: if ((newType > -1) || (typeParameters != null)) { // set variable type
0922: CodeExpression exp = comp.getCodeExpression();
0923: int varType = exp.getVariable().getType();
0924:
0925: if (newType > -1) {
0926: varType &= ~CodeVariable.ALL_MODIF_MASK;
0927: varType |= newType & CodeVariable.ALL_MODIF_MASK;
0928:
0929: if ((newType & CodeVariable.SCOPE_MASK) != 0) {
0930: varType &= ~CodeVariable.SCOPE_MASK;
0931: varType |= newType & CodeVariable.SCOPE_MASK;
0932: }
0933:
0934: if ((newType & CodeVariable.DECLARATION_MASK) != 0) {
0935: varType &= ~CodeVariable.DECLARATION_MASK;
0936: varType |= newType & CodeVariable.DECLARATION_MASK;
0937: }
0938: }
0939:
0940: CodeStructure codeStructure = comp.getFormModel()
0941: .getCodeStructure();
0942: String varName = comp.getName(); // get the original name
0943: codeStructure.removeExpressionFromVariable(exp);
0944: codeStructure.createVariableForExpression(exp, varType,
0945: typeParameters, varName);
0946: }
0947: }
0948:
0949: //
0950: // Private Methods
0951: //
0952:
0953: private String getDefaultSerializedName(RADComponent component) {
0954: return component.getFormModel().getName() + "_"
0955: + component.getName(); // NOI18N
0956: }
0957:
0958: void regenerateInitComponents() {
0959: if (!initialized || !canGenerate)
0960: return;
0961:
0962: // find indent engine to use or imitate
0963: IndentEngine indentEngine = IndentEngine.find(formEditorSupport
0964: .getDocument());
0965:
0966: final SimpleSection initComponentsSection = formEditorSupport
0967: .getInitComponentSection();
0968: int initComponentsOffset = initComponentsSection
0969: .getCaretPosition().getOffset();
0970:
0971: // create Writer for writing the generated code in
0972: StringWriter initCodeBuffer = new StringWriter(1024);
0973: CodeWriter initCodeWriter;
0974: if (formSettings.getUseIndentEngine()) { // use original indent engine
0975: initCodeWriter = new CodeWriter(indentEngine.createWriter(
0976: formEditorSupport.getDocument(),
0977: initComponentsOffset, initCodeBuffer), true);
0978: } else {
0979: initCodeWriter = new CodeWriter(initCodeBuffer, true);
0980: }
0981: // optimization - only properties need to go through CodeWriter
0982: Writer writer = initCodeWriter.getWriter();
0983:
0984: cleanup();
0985:
0986: try {
0987: boolean expandInitComponents = false;
0988: boolean foldGeneratedCode = formSettings
0989: .getFoldGeneratedCode();
0990: if (foldGeneratedCode) {
0991: String foldDescription = FormUtils
0992: .getBundleString("MSG_GeneratedCode"); // NOI18N
0993: javax.swing.JEditorPane editorPane = formEditorSupport
0994: .getEditorPane();
0995: if (editorPane != null) {
0996: FoldHierarchy foldHierarchy = FoldHierarchy
0997: .get(editorPane);
0998: Fold fold = FoldUtilities.findNearestFold(
0999: foldHierarchy, initComponentsOffset);
1000: expandInitComponents = (fold != null)
1001: && foldDescription.equals(fold
1002: .getDescription())
1003: && !fold.isCollapsed();
1004: }
1005: writer
1006: .write("// <editor-fold defaultstate=\"collapsed\" desc=\""); // NOI18N
1007: writer.write(foldDescription);
1008: writer.write("\">\n"); // NOI18N
1009: }
1010:
1011: writer.write("private void initComponents() {\n"); // NOI18N
1012:
1013: addLocalVariables(writer);
1014:
1015: if (bindingGroupVariable != null) {
1016: initCodeWriter.write(bindingGroupVariable + " = new "
1017: + bindingGroupClass.getName() + "();\n\n"); // NOI18N
1018: }
1019:
1020: emptyLineRequest++;
1021: Collection<RADComponent> otherComps = formModel
1022: .getOtherComponents();
1023: for (RADComponent metacomp : otherComps) {
1024: addCreateCode(metacomp, initCodeWriter);
1025: }
1026: RADComponent top = formModel.getTopRADComponent();
1027: addCreateCode(top, initCodeWriter);
1028:
1029: if (formModel.getSettings().getListenerGenerationStyle() == CEDL_INNERCLASS
1030: && anyEvents()) {
1031: emptyLineRequest++;
1032: addDispatchListenerDeclaration(writer);
1033: }
1034:
1035: for (RADComponent metacomp : otherComps) {
1036: addInitCode(metacomp, initCodeWriter, null);
1037: }
1038: addInitCode(top, initCodeWriter, null);
1039:
1040: if (bindingGroupVariable != null) {
1041: initCodeWriter.write("\n" + bindingGroupVariable
1042: + ".bind();\n"); // NOI18N
1043: }
1044:
1045: generateFormSizeCode(writer);
1046:
1047: writer.write("}"); // no new line because of fold footer // NOI18N
1048:
1049: int listenerCodeStyle = formModel.getSettings()
1050: .getListenerGenerationStyle();
1051: if ((listenerCodeStyle == CEDL_INNERCLASS || listenerCodeStyle == CEDL_MAINCLASS)
1052: && anyEvents()) {
1053: writer.write("\n\n"); // NOI18N
1054: writer.write(getEventDispatchCodeComment());
1055: writer.write("\n"); // NOI18N
1056:
1057: generateDispatchListenerCode(writer);
1058: } else
1059: listenersInMainClass = null;
1060:
1061: if (foldGeneratedCode) {
1062: writer.write("// </editor-fold>\n"); // NOI18N
1063: } else {
1064: writer.write("\n"); // NOI18N
1065: }
1066: writer.close();
1067:
1068: // set the text into the guarded block
1069: String newText = initCodeBuffer.toString();
1070: if (!formSettings.getUseIndentEngine()) {
1071: newText = indentCode(newText, 1, indentEngine);
1072: }
1073: initComponentsSection.setText(newText);
1074:
1075: if (expandInitComponents) {
1076: FoldHierarchy foldHierarchy = FoldHierarchy
1077: .get(formEditorSupport.getEditorPane());
1078: Fold fold = FoldUtilities.findNearestFold(
1079: foldHierarchy, initComponentsOffset);
1080: if (fold != null) {
1081: foldHierarchy.expand(fold);
1082: }
1083: }
1084: clearUndo();
1085: } catch (IOException e) { // should not happen
1086: ErrorManager.getDefault().notify(
1087: ErrorManager.INFORMATIONAL, e);
1088: }
1089:
1090: cleanup();
1091: }
1092:
1093: private void cleanup() {
1094: emptyLineCounter = 0;
1095: emptyLineRequest = 0;
1096: if (constructorProperties != null)
1097: constructorProperties.clear();
1098: if (parentDependentProperties != null)
1099: parentDependentProperties.clear();
1100: if (childrenDependentProperties != null)
1101: childrenDependentProperties.clear();
1102: formModel.getCodeStructure().clearExternalVariableNames();
1103: repeatedCodeVariables = null;
1104: // preventive cleanup
1105: bindingVariables = null;
1106: if (bindingGroupVariable != null) { // we need to keep this variable registered
1107: bindingGroupVariable = formModel.getCodeStructure()
1108: .getExternalVariableName(bindingGroupClass,
1109: bindingGroupVariable, true);
1110: }
1111: }
1112:
1113: private void regenerateVariables() {
1114: if (!initialized || !canGenerate)
1115: return;
1116:
1117: IndentEngine indentEngine = IndentEngine.find(formEditorSupport
1118: .getDocument());
1119:
1120: StringWriter variablesBuffer = new StringWriter(1024);
1121: CodeWriter variablesWriter;
1122: final SimpleSection variablesSection = formEditorSupport
1123: .getVariablesSection();
1124:
1125: if (formSettings.getUseIndentEngine()) {
1126: variablesWriter = new CodeWriter(indentEngine.createWriter(
1127: formEditorSupport.getDocument(), variablesSection
1128: .getCaretPosition().getOffset(),
1129: variablesBuffer), false);
1130: } else {
1131: variablesWriter = new CodeWriter(variablesBuffer, false);
1132: }
1133:
1134: try {
1135: variablesWriter.write(getVariablesHeaderComment());
1136: variablesWriter.write("\n"); // NOI18N
1137:
1138: addFieldVariables(variablesWriter);
1139:
1140: variablesWriter.write(getVariablesFooterComment());
1141: variablesWriter.write("\n"); // NOI18N
1142: variablesWriter.getWriter().close();
1143:
1144: String newText = variablesBuffer.toString();
1145: if (!formSettings.getUseIndentEngine())
1146: newText = indentCode(newText, 1, indentEngine);
1147:
1148: variablesSection.setText(newText);
1149: clearUndo();
1150: } catch (IOException e) { // should not happen
1151: e.printStackTrace();
1152: }
1153: }
1154:
1155: private void addCreateCode(RADComponent comp,
1156: CodeWriter initCodeWriter) throws IOException {
1157: if (comp == null)
1158: return;
1159:
1160: if (comp != formModel.getTopRADComponent()) {
1161: generateComponentCreate(comp, initCodeWriter, true, null);
1162: }
1163: if (comp instanceof ComponentContainer) {
1164: RADComponent[] children = ((ComponentContainer) comp)
1165: .getSubBeans();
1166: for (int i = 0; i < children.length; i++) {
1167: addCreateCode(children[i], initCodeWriter);
1168: }
1169: }
1170: }
1171:
1172: private void addInitCode(RADComponent comp,
1173: CodeWriter initCodeWriter, CustomCodeData codeData)
1174: throws IOException {
1175: if (comp == null)
1176: return;
1177:
1178: Writer writer = initCodeWriter.getWriter();
1179:
1180: int counter0 = emptyLineCounter;
1181: int request0 = emptyLineRequest;
1182: emptyLineRequest++;
1183:
1184: generateComponentProperties(comp, initCodeWriter, codeData);
1185: generateComponentEvents(comp, initCodeWriter, codeData);
1186:
1187: if (comp instanceof ComponentContainer) {
1188: boolean freeDesign = RADVisualContainer
1189: .isFreeDesignContainer(comp);
1190: ComponentContainer cont = (ComponentContainer) comp;
1191: if (!freeDesign) // layout and pre-population code before sub-components
1192: generateOldLayout(cont, initCodeWriter, codeData);
1193:
1194: if (codeData == null) { // normal code generation
1195: // generate code of sub-components
1196: RADComponent[] subBeans = cont.getSubBeans();
1197: for (RADComponent subcomp : subBeans) {
1198: addInitCode(subcomp, initCodeWriter, null);
1199: }
1200: if (freeDesign) { // generate complete layout code
1201: // GroupLayout setup code also adds all sub-components
1202: RADVisualContainer visualCont = (RADVisualContainer) cont;
1203: emptyLineRequest++;
1204: generatePrePopulationCode(visualCont, writer, null);
1205: emptyLineRequest++;
1206: for (RADComponent subcomp : visualCont
1207: .getSubComponents()) {
1208: generateComponentAddPre(subcomp, writer, null);
1209: }
1210: emptyLineRequest++;
1211: generateFreeDesignLayoutCode(visualCont,
1212: initCodeWriter); // this always generates something
1213: emptyLineRequest++;
1214: // some code of sub-components is generated after adding
1215: // them to the container (a11y, after-all-set)
1216: for (RADComponent subcomp : visualCont
1217: .getSubComponents()) { // excluding menu
1218: generateComponentAddPost(subcomp,
1219: initCodeWriter, null);
1220: generateAccessibilityCode(subcomp,
1221: initCodeWriter, null);
1222: generateInjectionCode(subcomp, initCodeWriter,
1223: null);
1224: generateAfterAllSetCode(subcomp, writer, null);
1225: }
1226: emptyLineRequest++;
1227: } else if (subBeans.length > 0)
1228: emptyLineRequest++; // empty line after sub-components
1229: } else { // build code data for editing
1230: if (RADVisualContainer.isFreeDesignContainer(comp)) {
1231: String substCode = "// "
1232: + FormUtils
1233: .getBundleString("CustomCode-SubstSub"); // NOI18N
1234: codeData.addGuardedBlock(substCode);
1235: generatePrePopulationCode(comp, writer, codeData);
1236: substCode = "// "
1237: + FormUtils
1238: .getBundleString("CustomCode-SubstLayout"); // NOI18N
1239: codeData.addGuardedBlock(substCode);
1240: } else { // with LM, the pre-layout code is elsewhere (before properties)
1241: String substCode = "// "
1242: + FormUtils
1243: .getBundleString("CustomCode-SubstSubAndLayout"); // NOI18N
1244: codeData.addGuardedBlock(substCode);
1245: }
1246: }
1247:
1248: int counter1 = emptyLineCounter;
1249: emptyLineRequest++;
1250: generatePostPopulationCode(comp, initCodeWriter, codeData);
1251: if (emptyLineCounter == counter1)
1252: emptyLineRequest--; // no post-population code, don't force empty line
1253: else
1254: emptyLineRequest++; // force empty line after post-population
1255: }
1256:
1257: if (emptyLineCounter == counter0)
1258: emptyLineRequest = request0; // no code was generated, don't force empty line
1259:
1260: if (!RADVisualContainer.isInFreeDesign(comp)) { // in container with LM, or menu component
1261: // add to parent container (if not root itself)
1262: generateComponentAddCode(comp, initCodeWriter, codeData);
1263: boolean endingCode = false;
1264: if (generateAccessibilityCode(comp, initCodeWriter,
1265: codeData))
1266: endingCode = true;
1267: if (generateInjectionCode(comp, initCodeWriter, codeData))
1268: endingCode = true;
1269: if (generateAfterAllSetCode(comp, writer, codeData))
1270: endingCode = true;
1271: if (endingCode)
1272: emptyLineRequest++; // force empty line after
1273: } else if (codeData != null) { // build code data for editing
1274: // In free design this is generated with parent container (see above).
1275: // But building code data is invoked only for the component itself,
1276: // not for its parent, so we must do it here.
1277: generateComponentAddPre(comp, writer, codeData);
1278: String substCode = "// "
1279: + FormUtils
1280: .getBundleString("CustomCode-SubstAdding"); // NOI18N
1281: codeData.addGuardedBlock(substCode);
1282: generateComponentAddPost(comp, initCodeWriter, codeData);
1283: generateAccessibilityCode(comp, initCodeWriter, codeData);
1284: generateInjectionCode(comp, initCodeWriter, codeData);
1285: generateAfterAllSetCode(comp, writer, codeData);
1286: }
1287: }
1288:
1289: private void generateOldLayout(ComponentContainer cont,
1290: CodeWriter initCodeWriter, CustomCodeData codeData)
1291: throws IOException {
1292: RADVisualContainer visualCont = cont instanceof RADVisualContainer ? (RADVisualContainer) cont
1293: : null;
1294: LayoutSupportManager layoutSupport = visualCont != null ? visualCont
1295: .getLayoutSupport()
1296: : null;
1297:
1298: if (layoutSupport != null) { // setLayout code for old layout support
1299: if (layoutSupport.isLayoutChanged()) {
1300: Iterator it = layoutSupport.getLayoutCode()
1301: .getStatementsIterator();
1302: if (codeData == null && it.hasNext())
1303: generateEmptyLineIfNeeded(initCodeWriter
1304: .getWriter());
1305: while (it.hasNext()) {
1306: CodeStatement statement = (CodeStatement) it.next();
1307: initCodeWriter.write(getStatementJavaString(
1308: statement, "")); // NOI18N
1309: initCodeWriter.write("\n"); // NOI18N
1310: }
1311:
1312: if (codeData != null) { // build code data for editing
1313: String code = indentCode(initCodeWriter
1314: .extractString());
1315: codeData.addGuardedBlock(code);
1316: }
1317: }
1318: }
1319:
1320: generatePrePopulationCode((RADComponent) cont, initCodeWriter
1321: .getWriter(), codeData);
1322: }
1323:
1324: private boolean generateAfterAllSetCode(RADComponent comp,
1325: Writer writer, CustomCodeData codeData) throws IOException {
1326: boolean generated = false;
1327:
1328: String postCode = (String) comp.getAuxValue(AUX_ALL_SET_POST);
1329: if (codeData != null) { // build code data for editing
1330: codeData
1331: .addEditableBlock(
1332: postCode,
1333: (FormProperty) comp
1334: .getSyntheticProperty(PROP_ALL_SET_POST),
1335: 0,
1336: FormUtils
1337: .getBundleString("CustomCode-AfterAllSet"), // NOI18N
1338: FormUtils
1339: .getBundleString("MSG_JC_PostPopulationCodeDesc")); // NOI18N
1340: }
1341: // normal code generation
1342: else if (postCode != null && !postCode.equals("")) { // NOI18N
1343: generateEmptyLineIfNeeded(writer);
1344: writer.write(postCode);
1345: if (!postCode.endsWith("\n")) // NOI18N
1346: writer.write("\n"); // NOI18N
1347: generated = true;
1348: }
1349:
1350: return generated;
1351: }
1352:
1353: private void generateComponentCreate(RADComponent comp,
1354: CodeWriter initCodeWriter, boolean insideMethod, // if this for initComponents
1355: CustomCodeData codeData) throws IOException {
1356: if (comp instanceof RADMenuItemComponent
1357: && ((RADMenuItemComponent) comp).getMenuItemType() == RADMenuItemComponent.T_SEPARATOR) { // do not generate anything for AWT separator as it is not a real component
1358: return;
1359: }
1360:
1361: // optimization - only properties need to go through CodeWriter
1362: Writer writer = initCodeWriter.getWriter();
1363:
1364: CodeVariable var = comp.getCodeExpression().getVariable();
1365: int varType = var.getType();
1366: boolean localVariable = (varType & CodeVariable.SCOPE_MASK) == CodeVariable.LOCAL;
1367:
1368: if (insideMethod) {
1369: if (isFinalFieldVariable(varType))
1370: return; // is generated in field variables (here we are in initComponents)
1371:
1372: String preCode = (String) comp
1373: .getAuxValue(AUX_CREATE_CODE_PRE);
1374: if (codeData != null) { // build code data for editing
1375: codeData
1376: .addEditableBlock(
1377: preCode,
1378: (FormProperty) comp
1379: .getSyntheticProperty(PROP_CREATE_CODE_PRE),
1380: 2, // preference index
1381: FormUtils
1382: .getBundleString("CustomCode-PreCreation"), // NOI18N
1383: FormUtils
1384: .getBundleString("MSG_JC_PreCreationCodeDesc")); // NOI18N
1385: } else if (preCode != null && !preCode.equals("")) { // NOI18N
1386: // normal generation of custom pre-creation code
1387: generateEmptyLineIfNeeded(writer);
1388: writer.write(preCode);
1389: if (!preCode.endsWith("\n")) // NOI18N
1390: writer.write("\n"); // NOI18N
1391: }
1392: }
1393:
1394: Integer generationType = (Integer) comp
1395: .getAuxValue(AUX_CODE_GENERATION);
1396: if (comp.hasHiddenState()
1397: || VALUE_SERIALIZE.equals(generationType)) {
1398: // generate code for restoring serialized component [only works for field variables]
1399: if (!insideMethod)
1400: return;
1401:
1402: String serializeTo = (String) comp
1403: .getAuxValue(AUX_SERIALIZE_TO);
1404: if (serializeTo == null) {
1405: serializeTo = getDefaultSerializedName(comp);
1406: comp.setAuxValue(AUX_SERIALIZE_TO, serializeTo);
1407: }
1408: if (codeData == null)
1409: generateEmptyLineIfNeeded(writer);
1410: writer.write("try {\n"); // NOI18N
1411: writer.write(comp.getName());
1412: writer.write(" =("); // NOI18N
1413: writer.write(getSourceClassName(comp.getBeanClass()));
1414: writer
1415: .write(")java.beans.Beans.instantiate(getClass().getClassLoader(), \""); // NOI18N
1416:
1417: // write package name
1418: FileObject fo = formEditorSupport.getFormDataObject()
1419: .getPrimaryFile();
1420: ClassPath cp = ClassPath.getClassPath(fo, ClassPath.SOURCE);
1421: String packageName = cp.getResourceName(fo.getParent());
1422: if (!"".equals(packageName)) { // NOI18N
1423: writer.write(packageName + "."); // NOI18N
1424: }
1425: writer.write(serializeTo);
1426: writer.write("\");\n"); // NOI18N
1427: writer.write("} catch (ClassNotFoundException e) {\n"); // NOI18N
1428: writer.write("e.printStackTrace();\n"); // NOI18N
1429: writer.write("} catch (java.io.IOException e) {\n"); // NOI18N
1430: writer.write("e.printStackTrace();\n"); // NOI18N
1431: writer.write("}\n"); // NOI18N
1432: if (codeData != null) {
1433: codeData.addGuardedBlock(indentCode(initCodeWriter
1434: .extractString()));
1435: }
1436: } else { // generate standard component creation code
1437: if (codeData == null)
1438: generateEmptyLineIfNeeded(writer);
1439:
1440: StringBuffer buf = new StringBuffer(); // we need the entire creation statement written at once
1441:
1442: if (localVariable || isFinalFieldVariable(varType)) { // also generate declaration
1443: generateDeclarationPre(comp, writer, codeData);
1444: buf.append(Modifier.toString(varType
1445: & CodeVariable.ALL_MODIF_MASK));
1446: buf.append(" "); // NOI18N
1447: buf.append(getSourceClassName(comp.getBeanClass()));
1448: String typeParameters = var.getDeclaredTypeParameters();
1449: if ((typeParameters != null)
1450: && !"".equals(typeParameters)) { // NOI18N
1451: buf.append(typeParameters);
1452: }
1453: buf.append(" "); // NOI18N
1454: }
1455:
1456: buf.append(var.getName()); // now buf contains variable code, more code added later
1457:
1458: // only for code data editing
1459: String customCode = null;
1460: boolean codeCustomized = false;
1461: String variableCode = buf.toString();
1462:
1463: String customCreationCode = (String) comp
1464: .getAuxValue(AUX_CREATE_CODE_CUSTOM);
1465: if (customCreationCode != null
1466: && !customCreationCode.equals("")) { // NOI18N
1467: // there is a custom creation code provided
1468: if (customCreationCode.endsWith(";")) { // NOI18N
1469: customCreationCode = customCreationCode.substring(
1470: 0, customCreationCode.length() - 1);
1471: }
1472: if (codeData == null) { // normal code generation
1473: buf.append(" = ").append(customCreationCode)
1474: .append(";\n"); // NOI18N
1475: initCodeWriter.write(buf.toString());
1476: // and we are done
1477: } else { // build code data for editing
1478: customCode = composeCustomCreationCode(
1479: variableCode, customCreationCode);
1480: codeCustomized = true;
1481: }
1482: }
1483: if (customCreationCode == null
1484: || customCreationCode.equals("")
1485: || codeData != null) { // NOI18N
1486: // compose default creation code (if building code data for editing
1487: // we need both custom and default creation code)
1488: CreationDescriptor desc = CreationFactory
1489: .getDescriptor(comp.getBeanClass());
1490: if (desc == null)
1491: desc = new CreationDescriptor(comp.getBeanClass());
1492:
1493: CreationDescriptor.Creator creator = desc
1494: .findBestCreator(comp.getKnownBeanProperties(),
1495: CreationDescriptor.CHANGED_ONLY);
1496: if (creator == null) // known properties are not enough...
1497: creator = desc.findBestCreator(comp
1498: .getAllBeanProperties(),
1499: CreationDescriptor.CHANGED_ONLY);
1500:
1501: Class[] exceptions = creator.getExceptionTypes();
1502: if (insideMethod && needTryCode(exceptions)) {
1503: if (localVariable) { // separate the declaration statement
1504: buf.append(";\n"); // NOI18N
1505: writer.write(buf.toString());
1506: buf.delete(0, buf.length());
1507: buf.append(var.getName());
1508: }
1509: writer.write("try {\n"); // NOI18N
1510: } else {
1511: exceptions = null;
1512: }
1513:
1514: String[] propNames = creator.getPropertyNames();
1515: FormProperty[] props;
1516: if (propNames.length > 0) {
1517: if (constructorProperties == null)
1518: constructorProperties = new HashMap<RADComponent, java.util.List<FormProperty>>();
1519:
1520: java.util.List<FormProperty> usedProperties = new ArrayList<FormProperty>(
1521: propNames.length);
1522: props = new FormProperty[propNames.length];
1523:
1524: for (int i = 0; i < propNames.length; i++) {
1525: FormProperty prop = comp
1526: .getBeanProperty(propNames[i]);
1527: props[i] = prop;
1528: usedProperties.add(prop);
1529: }
1530: constructorProperties.put(comp, usedProperties);
1531: } else {
1532: props = RADComponent.NO_PROPERTIES;
1533: }
1534: String typeParams = (String) comp
1535: .getAuxValue(AUX_TYPE_PARAMETERS);
1536:
1537: String defaultCreationCode = creator
1538: .getJavaCreationCode(props, null, typeParams);
1539: buf.append(" = ").append(defaultCreationCode).append(
1540: ";\n"); // NOI18N
1541: initCodeWriter.write(buf.toString());
1542:
1543: if (codeData != null && !codeCustomized) { // get default code for custom editing (without try/catch)
1544: customCode = composeCustomCreationCode(
1545: variableCode, defaultCreationCode);
1546: // TODO: the default creation code might contain code marks from property editor - should be filtered out
1547: }
1548:
1549: if (exceptions != null) {
1550: generateCatchCode(exceptions, writer);
1551: }
1552: }
1553:
1554: if (codeData != null) { // code data for creation code
1555: String defaultCode = indentCode(initCodeWriter
1556: .extractString());
1557: codeData
1558: .addGuardedBlock(
1559: defaultCode,
1560: customCode,
1561: CUSTOM_CODE_MARK,
1562: codeCustomized,
1563: (FormProperty) comp
1564: .getSyntheticProperty(PROP_CREATE_CODE_CUSTOM),
1565: FormUtils
1566: .getBundleString("CustomCode-Creation"), // NOI18N
1567: FormUtils
1568: .getBundleString("CustomCode-Creation_Hint")); // NOI18N
1569: }
1570:
1571: if (localVariable || isFinalFieldVariable(varType)) { // declaration generated
1572: generateDeclarationPost(comp, writer, codeData);
1573: }
1574: }
1575:
1576: if (insideMethod) {
1577: String postCode = (String) comp
1578: .getAuxValue(AUX_CREATE_CODE_POST);
1579: if (codeData != null) { // build code data for editing
1580: codeData
1581: .addEditableBlock(
1582: postCode,
1583: (FormProperty) comp
1584: .getSyntheticProperty(PROP_CREATE_CODE_POST),
1585: 0, // preference index
1586: FormUtils
1587: .getBundleString("CustomCode-PostCreation"), // NOI18N
1588: FormUtils
1589: .getBundleString("MSG_JC_PostCreationCodeDesc")); // NOI18N
1590: } else if (postCode != null && !postCode.equals("")) { // NOI18N
1591: // normal generation of post-creation code
1592: writer.write(postCode);
1593: if (!postCode.endsWith("\n")) // NOI18N
1594: writer.write("\n"); // NOI18N
1595: }
1596: }
1597: }
1598:
1599: // used only when building "code data" for editing
1600: private String composeCustomCreationCode(String variableCode,
1601: String creationCode) {
1602: return indentCode(variableCode + " = " + CUSTOM_CODE_MARK
1603: + creationCode + CUSTOM_CODE_MARK + ";\n"); // NOI18N
1604: }
1605:
1606: private void generateComponentProperties(RADComponent comp,
1607: CodeWriter initCodeWriter, CustomCodeData codeData)
1608: throws IOException {
1609: Writer writer = initCodeWriter.getWriter();
1610:
1611: String preCode = (String) comp.getAuxValue(AUX_INIT_CODE_PRE);
1612: if (codeData != null) { // build code data for editing
1613: codeData
1614: .addEditableBlock(
1615: preCode,
1616: (FormProperty) comp
1617: .getSyntheticProperty(PROP_INIT_CODE_PRE),
1618: 10, // preference index
1619: FormUtils
1620: .getBundleString("CustomCode-PreInit"), // NOI18N
1621: FormUtils
1622: .getBundleString("MSG_JC_PreInitCodeDesc")); // NOI18N
1623: } else if (preCode != null && !preCode.equals("")) { // NOI18N
1624: generateEmptyLineIfNeeded(writer);
1625: writer.write(preCode);
1626: if (!preCode.endsWith("\n")) // NOI18N
1627: writer.write("\n"); // NOI18N
1628: }
1629:
1630: Object genType = comp.getAuxValue(AUX_CODE_GENERATION);
1631: if (!comp.hasHiddenState()
1632: && (genType == null || VALUE_GENERATE_CODE
1633: .equals(genType))) { // not serialized, generate properties
1634: java.util.List<FormProperty> usedProperties = constructorProperties != null ? constructorProperties
1635: .get(comp)
1636: : null;
1637: Iterator<? extends FormProperty> it = comp
1638: .getBeanPropertiesIterator(new PropertiesFilter(
1639: usedProperties), false);
1640: while (it.hasNext()) {
1641: FormProperty prop = it.next();
1642:
1643: java.util.List<FormProperty> depPropList = null;
1644: if (FormUtils.isMarkedParentDependentProperty(prop)) {
1645: // needs to be generated after the component is added to the parent container
1646: if (parentDependentProperties != null)
1647: depPropList = parentDependentProperties
1648: .get(comp);
1649: else {
1650: parentDependentProperties = new HashMap<RADComponent, java.util.List<FormProperty>>();
1651: depPropList = null;
1652: }
1653: if (depPropList == null) {
1654: depPropList = new LinkedList<FormProperty>();
1655: parentDependentProperties
1656: .put(comp, depPropList);
1657: }
1658: depPropList.add(prop);
1659: }
1660: if (FormUtils.isMarkedChildrenDependentProperty(prop)) {
1661: // needs to be added after all sub-components are added to this container
1662: if (childrenDependentProperties != null)
1663: depPropList = childrenDependentProperties
1664: .get(comp);
1665: else {
1666: childrenDependentProperties = new HashMap<RADComponent, java.util.List<FormProperty>>();
1667: depPropList = null;
1668: }
1669: if (depPropList == null) {
1670: depPropList = new LinkedList<FormProperty>();
1671: childrenDependentProperties.put(comp,
1672: depPropList);
1673: }
1674: depPropList.add(prop);
1675: }
1676:
1677: if (depPropList == null) { // independent property, generate here directly
1678: generateProperty(prop, comp, null, initCodeWriter,
1679: codeData);
1680: }
1681: }
1682: }
1683:
1684: generateComponentBindings(comp, initCodeWriter);
1685:
1686: String postCode = (String) comp.getAuxValue(AUX_INIT_CODE_POST);
1687: if (codeData != null) { // build code data for editing
1688: codeData
1689: .addEditableBlock(
1690: postCode,
1691: (FormProperty) comp
1692: .getSyntheticProperty(PROP_INIT_CODE_POST),
1693: 7, // preference index
1694: FormUtils
1695: .getBundleString("CustomCode-PostInit"), // NOI18N
1696: FormUtils
1697: .getBundleString("MSG_JC_PostInitCodeDesc")); // NOI18N
1698: } else if (postCode != null && !postCode.equals("")) { // NOI18N
1699: generateEmptyLineIfNeeded(writer);
1700: writer.write(postCode);
1701: if (!postCode.endsWith("\n")) // NOI18N
1702: writer.write("\n"); // NOI18N
1703: }
1704: }
1705:
1706: private void generateComponentBindings(RADComponent comp,
1707: CodeWriter initCodeWriter) throws IOException {
1708: boolean anyBinding = false;
1709: for (BindingProperty prop : comp.getKnownBindingProperties()) {
1710: MetaBinding bindingDef = prop.getValue();
1711: if (bindingDef != null) {
1712: if (!anyBinding) {
1713: initCodeWriter.write("\n"); // NOI18N
1714: anyBinding = true;
1715: if (bindingGroupVariable == null) { // Should happen only for Code Customizer
1716: bindingGroupVariable = formModel
1717: .getCodeStructure()
1718: .getExternalVariableName(
1719: bindingGroupClass,
1720: "bindingGroup", true); // NOI18N
1721: }
1722: }
1723: StringBuilder buf = new StringBuilder();
1724: String variable = BindingDesignSupport.generateBinding(
1725: prop, buf);
1726: initCodeWriter.write(buf.toString());
1727:
1728: if (bindingDef.isNullValueSpecified()) {
1729: generateComponentBinding0(initCodeWriter, prop
1730: .getNullValueProperty(), variable
1731: + ".setSourceNullValue"); // NOI18N
1732: }
1733: if (bindingDef.isIncompletePathValueSpecified()) {
1734: generateComponentBinding0(initCodeWriter, prop
1735: .getIncompleteValueProperty(), variable
1736: + ".setSourceUnreadableValue"); // NOI18N
1737: }
1738: if (bindingDef.isConverterSpecified()) {
1739: generateComponentBinding0(initCodeWriter, prop
1740: .getConverterProperty(), variable
1741: + ".setConverter"); // NOI18N
1742: }
1743: if (bindingDef.isValidatorSpecified()) {
1744: generateComponentBinding0(initCodeWriter, prop
1745: .getValidatorProperty(), variable
1746: + ".setValidator"); // NOI18N
1747: }
1748: initCodeWriter.write(bindingGroupVariable
1749: + ".addBinding(" + variable + ");\n"); // NOI18N
1750: if (bindingDef.isBindImmediately()) {
1751: initCodeWriter.write(variable + ".bind();"); // NOI18N
1752: }
1753: }
1754: }
1755: if (anyBinding) {
1756: initCodeWriter.write("\n"); // NOI18N
1757: }
1758: }
1759:
1760: private void generateComponentBinding0(CodeWriter initCodeWriter,
1761: FormProperty property, String method) throws IOException {
1762: initCodeWriter.write(method + "("
1763: + property.getJavaInitializationString() + ");\n"); // NOI18N
1764: }
1765:
1766: String getBindingDescriptionVariable(Class descriptionType,
1767: StringBuilder buf, boolean create) {
1768: String variable = null;
1769: if (bindingVariables == null) {
1770: bindingVariables = new HashMap<String, String>();
1771: } else {
1772: variable = bindingVariables.get(descriptionType.getName());
1773: }
1774:
1775: if (create && (variable == null)) {
1776: String name = descriptionType.getSimpleName();
1777: name = Character.toLowerCase(name.charAt(0))
1778: + name.substring(1);
1779: variable = formModel.getCodeStructure()
1780: .getExternalVariableName(descriptionType, name,
1781: true);
1782: bindingVariables.put(descriptionType.getName(), variable);
1783:
1784: String typeName = descriptionType.getName();
1785: typeName = typeName.replace("$", "."); // NOI18N innerclasses
1786: buf.append(typeName);
1787: }
1788: return variable;
1789: }
1790:
1791: private boolean generateAccessibilityCode(RADComponent comp,
1792: CodeWriter initCodeWriter, CustomCodeData codeData)
1793: throws IOException {
1794: boolean generated = false;
1795: Object genType = comp.getAuxValue(AUX_CODE_GENERATION);
1796: if (!comp.hasHiddenState()
1797: && (genType == null || VALUE_GENERATE_CODE
1798: .equals(genType))) { // not serialized
1799: FormProperty[] props;
1800: if (comp instanceof RADVisualComponent)
1801: props = ((RADVisualComponent) comp)
1802: .getAccessibilityProperties();
1803: else
1804: return false;
1805:
1806: for (int i = 0; i < props.length; i++) {
1807: boolean gen = generateProperty(props[i], comp, null,
1808: initCodeWriter, codeData);
1809: if (gen)
1810: generated = true;
1811: }
1812: }
1813: return generated;
1814: }
1815:
1816: private boolean generateInjectionCode(RADComponent metacomp,
1817: CodeWriter initCodeWriter, CustomCodeData codeData)
1818: throws IOException {
1819: String injectionCode = ResourceSupport.getInjectionCode(
1820: metacomp, getComponentParameterString(metacomp, true));
1821: if (injectionCode != null) {
1822: if (!injectionCode.endsWith("\n")) { // NOI18N
1823: injectionCode = injectionCode + "\n"; // NOI18N
1824: }
1825: initCodeWriter.write(injectionCode);
1826: if (codeData != null) { // build code data for editing
1827: String code = indentCode(initCodeWriter.extractString());
1828: codeData.addGuardedBlock(code);
1829: }
1830: return true;
1831: } else
1832: return false;
1833: }
1834:
1835: private void generateComponentAddCode(RADComponent comp,
1836: CodeWriter initCodeWriter, CustomCodeData codeData)
1837: throws IOException {
1838: RADComponent parent = comp.getParentComponent();
1839: if (parent == null)
1840: return;
1841:
1842: // optimization - only properties need to go through CodeWriter
1843: Writer writer = initCodeWriter.getWriter();
1844:
1845: generateComponentAddPre(comp, initCodeWriter.getWriter(),
1846: codeData);
1847:
1848: if (comp instanceof RADVisualComponent) {
1849: if (comp == ((RADVisualContainer) parent)
1850: .getContainerMenu()) { //
1851: assert comp.getBeanInstance() instanceof javax.swing.JMenuBar
1852: && parent.getBeanInstance() instanceof javax.swing.RootPaneContainer;
1853: if (codeData == null) {
1854: generateEmptyLineIfNeeded(writer);
1855: }
1856: writer.write(getComponentInvokeString(parent, true));
1857: writer.write("setJMenuBar("); // NOI18N
1858: writer.write(getComponentParameterString(comp, true));
1859: writer.write(");\n"); // NOI18N
1860: } else { // adding visual component to container with old layout support
1861: LayoutSupportManager laysup = ((RADVisualComponent) comp)
1862: .getParentLayoutSupport();
1863: CodeGroup componentCode = laysup != null ? laysup
1864: .getComponentCode((RADVisualComponent) comp)
1865: : null;
1866: if (componentCode != null) {
1867: Iterator it = componentCode.getStatementsIterator();
1868: if (codeData == null && it.hasNext())
1869: generateEmptyLineIfNeeded(writer);
1870: while (it.hasNext()) {
1871: CodeStatement statement = (CodeStatement) it
1872: .next();
1873: initCodeWriter.write(getStatementJavaString(
1874: statement, "")); // NOI18N
1875: initCodeWriter.write("\n"); // NOI18N
1876: }
1877: }
1878: } // this method is not called for visual components in freee design
1879: } else if (comp instanceof RADMenuItemComponent) { // AWT menu
1880: if (parent instanceof RADVisualContainer) { // menu bar to visual container
1881: assert comp.getBeanInstance() instanceof java.awt.MenuBar //getMenuItemType() == RADMenuItemComponent.T_MENUBAR
1882: && parent.getBeanInstance() instanceof java.awt.Frame;
1883: if (codeData == null) {
1884: generateEmptyLineIfNeeded(writer);
1885: }
1886: writer.write(getComponentInvokeString(parent, true));
1887: writer.write("setMenuBar("); // NOI18N
1888: writer.write(getComponentParameterString(comp, true));
1889: writer.write(");\n"); // NOI18N
1890: } else { // menu component to another component
1891: assert parent instanceof RADMenuComponent;
1892: RADMenuItemComponent menuComp = (RADMenuItemComponent) comp;
1893: if (codeData == null) {
1894: generateEmptyLineIfNeeded(writer);
1895: }
1896: if (menuComp.getMenuItemType() == RADMenuItemComponent.T_SEPARATOR) {
1897: // treat AWT Separator specially - it is not a regular component
1898: writer
1899: .write(getComponentInvokeString(parent,
1900: true));
1901: writer.write("addSeparator();"); // NOI18N
1902: } else {
1903: writer
1904: .write(getComponentInvokeString(parent,
1905: true));
1906: writer.write("add("); // NOI18N
1907: writer
1908: .write(getComponentParameterString(comp,
1909: true));
1910: writer.write(");\n"); // NOI18N
1911: }
1912: }
1913: }
1914: // no other type of adding supported [assert false ?]
1915:
1916: if (codeData != null) { // build code data for editing
1917: String code = initCodeWriter.extractString();
1918: if (code != null && !code.equals("")) // NOI18N
1919: codeData.addGuardedBlock(indentCode(code));
1920: }
1921:
1922: generateComponentAddPost(comp, initCodeWriter, codeData);
1923: }
1924:
1925: private void generateComponentAddPre(RADComponent comp,
1926: Writer writer, CustomCodeData codeData) throws IOException {
1927: String preCode = (String) comp.getAuxValue(AUX_ADDING_PRE);
1928: if (codeData != null) { // build code data for editing
1929: codeData.addEditableBlock(preCode, (FormProperty) comp
1930: .getSyntheticProperty(PROP_ADDING_PRE), 0, // preference index
1931: FormUtils.getBundleString("CustomCode-PreAdding"), // NOI18N
1932: FormUtils.getBundleString("MSG_JC_PreAddCodeDesc")); // NOI18N
1933: } else if (preCode != null && !preCode.equals("")) { // NOI18N
1934: generateEmptyLineIfNeeded(writer);
1935: writer.write(preCode);
1936: if (!preCode.endsWith("\n")) // NOI18N
1937: writer.write("\n"); // NOI18N
1938: }
1939: }
1940:
1941: private void generateComponentAddPost(RADComponent comp,
1942: CodeWriter initCodeWriter, CustomCodeData codeData)
1943: throws IOException {
1944: // some known (i.e. hardcoded) properties need to be set after
1945: // the component is added to the parent container
1946: java.util.List<FormProperty> postProps;
1947: if (parentDependentProperties != null
1948: && (postProps = parentDependentProperties.get(comp)) != null) {
1949: for (FormProperty prop : postProps) {
1950: generateProperty(prop, comp, null, initCodeWriter,
1951: codeData);
1952: }
1953: }
1954:
1955: String postCode = (String) comp.getAuxValue(AUX_ADDING_POST);
1956: if (codeData != null) { // build code data for editing
1957: codeData
1958: .addEditableBlock(
1959: postCode,
1960: (FormProperty) comp
1961: .getSyntheticProperty(PROP_ADDING_POST),
1962: 0, // preference index
1963: FormUtils
1964: .getBundleString("CustomCode-PostAdding"), // NOI18N
1965: FormUtils
1966: .getBundleString("MSG_JC_PostAddCodeDesc")); // NOI18N
1967: } else if (postCode != null && !postCode.equals("")) { // NOI18N
1968: generateEmptyLineIfNeeded(initCodeWriter.getWriter());
1969: initCodeWriter.getWriter().write(postCode);
1970: if (!postCode.endsWith("\n")) // NOI18N
1971: initCodeWriter.getWriter().write("\n"); // NOI18N
1972: }
1973: }
1974:
1975: private void generateFreeDesignLayoutCode(RADVisualContainer cont,
1976: CodeWriter initCodeWriter) throws IOException {
1977: LayoutComponent layoutCont = formModel.getLayoutModel()
1978: .getLayoutComponent(cont.getId());
1979: if (layoutCont == null)
1980: return;
1981:
1982: // optimization - only properties need to go through CodeWriter
1983: Writer writer = initCodeWriter.getWriter();
1984:
1985: RADVisualComponent[] comps = cont.getSubComponents();
1986:
1987: // layout code and adding sub-components
1988: generateEmptyLineIfNeeded(writer);
1989: SwingLayoutCodeGenerator.ComponentInfo[] infos = new SwingLayoutCodeGenerator.ComponentInfo[comps.length];
1990: for (int i = 0; i < comps.length; i++) {
1991: RADVisualComponent subComp = comps[i];
1992: SwingLayoutCodeGenerator.ComponentInfo info = new SwingLayoutCodeGenerator.ComponentInfo();
1993: info.id = subComp.getId();
1994: info.variableName = getExpressionJavaString(subComp
1995: .getCodeExpression(), ""); // NOI18N
1996: info.clazz = subComp.getBeanClass();
1997: Node.Property minProp = subComp
1998: .getPropertyByName("minimumSize"); // NOI18N
1999: Node.Property prefProp = subComp
2000: .getPropertyByName("preferredSize"); // NOI18N
2001: Node.Property maxProp = subComp
2002: .getPropertyByName("maximumSize"); // NOI18N
2003: info.sizingChanged = !(((minProp == null) || minProp
2004: .isDefaultValue())
2005: && ((prefProp == null) || prefProp.isDefaultValue()) && ((maxProp == null) || maxProp
2006: .isDefaultValue()));
2007: info.minSize = ((Component) subComp.getBeanInstance())
2008: .getMinimumSize();
2009: infos[i] = info;
2010: }
2011: CodeExpression contExpr = LayoutSupportManager
2012: .containerDelegateCodeExpression(cont, formModel
2013: .getCodeStructure());
2014: String contExprStr = getExpressionJavaString(contExpr, ""); // NOI18N
2015: CodeVariable contVar = cont.getCodeExpression().getVariable();
2016: String contVarName = (contVar == null) ? null : contVar
2017: .getName();
2018: getSwingGenerator()
2019: .generateContainerLayout(
2020: writer,
2021: layoutCont,
2022: contExprStr,
2023: contVarName,
2024: infos,
2025: formModel.getSettings().getLayoutCodeTarget() == LAYOUT_CODE_LIBRARY);
2026: }
2027:
2028: private SwingLayoutCodeGenerator getSwingGenerator() {
2029: if (swingGenerator == null) {
2030: swingGenerator = new SwingLayoutCodeGenerator(formModel
2031: .getLayoutModel());
2032: }
2033: return swingGenerator;
2034: }
2035:
2036: private void generatePrePopulationCode(RADComponent cont,
2037: Writer writer, CustomCodeData codeData) throws IOException {
2038: String preCode = (String) cont.getAuxValue(AUX_LAYOUT_PRE);
2039: if (codeData != null) { // build code data for editing
2040: codeData
2041: .addEditableBlock(
2042: preCode,
2043: (FormProperty) cont
2044: .getSyntheticProperty(PROP_LAYOUT_PRE),
2045: 2, // preference index
2046: FormUtils
2047: .getBundleString("CustomCode-PrePopulation"), // NOI18N
2048: FormUtils
2049: .getBundleString("MSG_JC_PrePopulationCodeDesc")); // NOI18N
2050: } else if (preCode != null && !preCode.equals("")) { // NOI18N
2051: generateEmptyLineIfNeeded(writer);
2052: writer.write(preCode);
2053: if (!preCode.endsWith("\n")) // NOI18N
2054: writer.write("\n"); // NOI18N
2055: }
2056: }
2057:
2058: private void generatePostPopulationCode(RADComponent cont,
2059: CodeWriter initCodeWriter, CustomCodeData codeData)
2060: throws IOException {
2061: // some known (i.e. hardcoded) container properties need to be set after
2062: // all sub-components are added
2063: java.util.List<FormProperty> postProps;
2064: if (childrenDependentProperties != null
2065: && (postProps = childrenDependentProperties.get(cont)) != null) {
2066: for (FormProperty prop : postProps) {
2067: generateProperty(prop, cont, null, initCodeWriter,
2068: codeData);
2069: }
2070: }
2071:
2072: // custom post-layout (post-population) code
2073: String postCode = (String) cont.getAuxValue(AUX_LAYOUT_POST);
2074: if (codeData != null) { // build code data for editing
2075: codeData
2076: .addEditableBlock(
2077: postCode,
2078: (FormProperty) cont
2079: .getSyntheticProperty(PROP_LAYOUT_POST),
2080: 4, // preference index
2081: FormUtils
2082: .getBundleString("CustomCode-PostPopulation"), // NOI18N
2083: FormUtils
2084: .getBundleString("MSG_JC_PostPopulationCodeDesc")); // NOI18N
2085: } else if (postCode != null && !postCode.equals("")) { // NOI18N
2086: generateEmptyLineIfNeeded(initCodeWriter.getWriter());
2087: initCodeWriter.getWriter().write(postCode);
2088: if (!postCode.endsWith("\n")) // NOI18N
2089: initCodeWriter.getWriter().write("\n"); // NOI18N
2090: }
2091: }
2092:
2093: private void generateFormSizeCode(Writer writer) throws IOException {
2094: if (formModel.getTopRADComponent() instanceof RADVisualFormContainer) {
2095: RADVisualFormContainer visualForm = (RADVisualFormContainer) formModel
2096: .getTopRADComponent();
2097:
2098: // generate size code according to form size policy
2099: int formPolicy = visualForm.getFormSizePolicy();
2100: boolean genSize = visualForm.getGenerateSize();
2101: boolean genPosition = visualForm.getGeneratePosition();
2102: boolean genCenter = visualForm.getGenerateCenter();
2103: Dimension formSize = visualForm.getFormSize();
2104: Point formPosition = visualForm.getFormPosition();
2105:
2106: String sizeText = ""; // NOI18N
2107:
2108: if (formPolicy == RADVisualFormContainer.GEN_PACK)
2109: sizeText = "pack();\n"; // NOI18N
2110: else if (formPolicy == RADVisualFormContainer.GEN_BOUNDS) {
2111: if (genCenter) {
2112: StringBuffer sizeBuffer = new StringBuffer();
2113: if (genSize) {
2114: // sizeBuffer.append("pack();\n"); // NOI18N
2115: sizeBuffer
2116: .append("java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();\n"); // NOI18N
2117: sizeBuffer
2118: .append("setBounds((screenSize.width-"
2119: + formSize.width
2120: + ")/2, (screenSize.height-"
2121: + formSize.height + ")/2, "
2122: + formSize.width + ", "
2123: + formSize.height + ");\n"); // NOI18N
2124: // sizeBuffer.append("setSize(new java.awt.Dimension("+formSize.width + ", " + formSize.height + "));\n"); // NOI18N
2125: // sizeBuffer.append("setLocation((screenSize.width-"+formSize.width+")/2,(screenSize.height-"+formSize.height+")/2);\n"); // NOI18N
2126: } else {
2127: sizeBuffer.append("pack();\n"); // NOI18N
2128: sizeBuffer
2129: .append("java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();\n"); // NOI18N
2130: sizeBuffer
2131: .append("java.awt.Dimension dialogSize = getSize();\n"); // NOI18N
2132: sizeBuffer
2133: .append("setLocation((screenSize.width-dialogSize.width)/2,(screenSize.height-dialogSize.height)/2);\n"); // NOI18N
2134: }
2135: sizeText = sizeBuffer.toString();
2136: } else if (genPosition && genSize) // both size and position
2137: sizeText = "setBounds(" + formPosition.x + ", " // NOI18N
2138: + formPosition.y + ", " // NOI18N
2139: + formSize.width + ", " // NOI18N
2140: + formSize.height + ");\n"; // NOI18N
2141: else if (genPosition) // position only
2142: sizeText = "setLocation(new java.awt.Point(" // NOI18N
2143: + formPosition.x + ", " // NOI18N
2144: + formPosition.y + "));\n"; // NOI18N
2145: else if (genSize) // size only
2146: sizeText = "setSize(new java.awt.Dimension(" // NOI18N
2147: + formSize.width + ", " // NOI18N
2148: + formSize.height + "));\n"; // NOI18N
2149: }
2150:
2151: if (!sizeText.equals("")) { // NOI18N
2152: emptyLineRequest++;
2153: generateEmptyLineIfNeeded(writer);
2154: writer.write(sizeText);
2155: }
2156: }
2157: }
2158:
2159: private boolean generateProperty(FormProperty prop,
2160: RADComponent comp, String setterVariable,
2161: CodeWriter initCodeWriter, CustomCodeData codeData)
2162: throws IOException {
2163: String preCode = prop.getPreCode();
2164: String postCode = prop.getPostCode();
2165: boolean valueSet = prop.isChanged();
2166:
2167: if ((preCode == null || preCode.equals("")) // NOI18N
2168: && (postCode == null || postCode.equals("")) // NOI18N
2169: && !valueSet)
2170: return false; // nothing set
2171:
2172: if (codeData == null)
2173: generateEmptyLineIfNeeded(initCodeWriter.getWriter());
2174:
2175: // 1. pre-initialization code
2176: if (codeData != null) { // build code data for editing
2177: String name;
2178: if (prop.getWriteMethod() != null)
2179: name = prop.getWriteMethod().getName();
2180: else {
2181: name = prop.getName();
2182: if (name.indexOf('.') >= 0)
2183: name = name.substring(name.lastIndexOf('.') + 1);
2184: }
2185: codeData
2186: .addEditableBlock(preCode,
2187: prop,
2188: 0, // preference index
2189: FormUtils.getFormattedBundleString(
2190: "CustomCode-PreProperty_Format", // NOI18N
2191: new Object[] { name }),
2192: FormUtils
2193: .getBundleString("CustomCode-PreProperty_Hint"), // NOI18N
2194: true, false);
2195: } else if (preCode != null && !preCode.equals("")) { // NOI18N
2196: initCodeWriter.getWriter().write(preCode);
2197: if (!preCode.endsWith("\n")) // NOI18N
2198: initCodeWriter.getWriter().write("\n"); // NOI18N
2199: }
2200:
2201: // 2. property setter code
2202: if (valueSet && !ResourceSupport.isInjectedProperty(prop)) {
2203: if (setterVariable == null)
2204: setterVariable = getComponentInvokeString(comp, true);
2205:
2206: generatePropertySetter(prop, comp, setterVariable,
2207: initCodeWriter, codeData);
2208:
2209: if (codeData != null) { // build code data for editing
2210: String customCode = indentCode(initCodeWriter
2211: .extractString());
2212: String defaultCode;
2213: boolean codeCustomized = isPropertyWithCustomCode(prop);
2214: if (codeCustomized)
2215: defaultCode = "// "
2216: + FormUtils
2217: .getBundleString("CustomCode-SubstNoValue"); // NOI18N
2218: else {
2219: generatePropertySetter(prop, comp, setterVariable,
2220: initCodeWriter, null);
2221: defaultCode = indentCode(initCodeWriter
2222: .extractString());
2223: }
2224: codeData
2225: .addGuardedBlock(
2226: defaultCode,
2227: customCode,
2228: CUSTOM_CODE_MARK,
2229: codeCustomized,
2230: prop,
2231: FormUtils
2232: .getBundleString("CustomCode-Property"), // NOI18N
2233: FormUtils
2234: .getBundleString("CustomCode-Property_Hint")); // NOI18N
2235: }
2236: }
2237:
2238: // 3. post-initialization code
2239: if (codeData != null) { // build code data for editing
2240: String name;
2241: if (prop.getWriteMethod() != null)
2242: name = prop.getWriteMethod().getName();
2243: else {
2244: name = prop.getName();
2245: if (name.indexOf('.') >= 0)
2246: name = name.substring(name.lastIndexOf('.') + 1);
2247: }
2248: codeData
2249: .addEditableBlock(postCode,
2250: prop,
2251: 0, // preference index
2252: FormUtils.getFormattedBundleString(
2253: "CustomCode-PostProperty_Format", // NOI18N
2254: new Object[] { name }),
2255: FormUtils
2256: .getBundleString("CustomCode-PostProperty_Hint"), // NOI18N
2257: false, true);
2258: } else if (postCode != null && !postCode.equals("")) { // NOI18N
2259: initCodeWriter.getWriter().write(postCode);
2260: if (!postCode.endsWith("\n")) // NOI18N
2261: initCodeWriter.getWriter().write("\n"); // NOI18N
2262: }
2263:
2264: return true;
2265: }
2266:
2267: static boolean isPropertyWithCustomCode(Node.Property prop) {
2268: try {
2269: Object value = prop.getValue();
2270: return value instanceof RADConnectionPropertyEditor.RADConnectionDesignValue
2271: && ((RADConnectionPropertyEditor.RADConnectionDesignValue) value)
2272: .getType() == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_CODE;
2273: } catch (Exception ex) {
2274: } // should not happen
2275: return false;
2276: }
2277:
2278: private void generatePropertySetter(FormProperty prop,
2279: RADComponent comp, String setterVariable,
2280: CodeWriter initCodeWriter, CustomCodeData codeData)
2281: throws IOException {
2282: Object value = null;
2283: try {
2284: value = prop.getValue();
2285: } catch (Exception ex) { // should not happen
2286: ErrorManager.getDefault().notify(
2287: ErrorManager.INFORMATIONAL, ex);
2288: return;
2289: }
2290:
2291: PropertyEditor currentEditor = prop.getCurrentEditor();
2292: if (currentEditor instanceof BeanPropertyEditor
2293: && value != null) {
2294: generatePropertyBeanSetterCode(prop, value, setterVariable,
2295: initCodeWriter, codeData);
2296: } else if (currentEditor instanceof FormCodeAwareEditor) {
2297: if (currentEditor.getValue() != value) {
2298: currentEditor.setValue(value);
2299: }
2300: String code = ((FormCodeAwareEditor) currentEditor)
2301: .getSourceCode();
2302: if (code != null) {
2303: initCodeWriter.write(code);
2304: }
2305: } else {
2306: String propValueCode = prop.getJavaInitializationString();
2307: if (codeData != null) // building code data for editing
2308: propValueCode = CUSTOM_CODE_MARK + propValueCode
2309: + CUSTOM_CODE_MARK;
2310: String javaStr = null;
2311:
2312: if ((javaStr = prop.getWholeSetterCode(propValueCode)) != null) { // button group property
2313: initCodeWriter.write(javaStr);
2314: if (!javaStr.endsWith("\n")) // NOI18N
2315: initCodeWriter.write("\n"); // NOI18N
2316: }
2317: // Mnemonics support - start -
2318: else if (comp != null && "text".equals(prop.getName()) // NOI18N
2319: && canUseMnemonics(comp) && isUsingMnemonics(comp)) {
2320: if (propValueCode != null) {
2321: initCodeWriter
2322: .write("org.openide.awt.Mnemonics.setLocalizedText(" // NOI18N
2323: + comp.getName()
2324: + ", "
2325: + propValueCode + ");\n"); // NOI18N
2326: }
2327: }
2328: // Mnemonics support - end -
2329: else if ((javaStr = prop
2330: .getPartialSetterCode(propValueCode)) != null) {
2331: // this is a normal property
2332: generateSimpleSetterCode(prop, javaStr, setterVariable,
2333: initCodeWriter);
2334: }
2335: }
2336: }
2337:
2338: private void generatePropertyBeanSetterCode(FormProperty prop,
2339: Object value, String setterVariable,
2340: CodeWriter initCodeWriter, CustomCodeData codeData)
2341: throws IOException {
2342:
2343: FormProperty[] properties = null;
2344: Class propertyType = null;
2345: Object realValue = prop.getRealValue(value);
2346: propertyType = realValue.getClass();
2347:
2348: prop.getCurrentEditor().setValue(value);
2349: BeanPropertyEditor beanPropertyEditor = (BeanPropertyEditor) prop
2350: .getCurrentEditor();
2351: properties = (FormProperty[]) beanPropertyEditor
2352: .getProperties();
2353: if (properties == null)
2354: return;
2355:
2356: CreationDescriptor.Creator creator = getPropertyCreator(
2357: propertyType, properties);
2358: java.util.List<FormProperty> creatorProperties = getCreatorProperties(
2359: creator, properties);
2360:
2361: java.util.List<FormProperty> remainingProperties = new ArrayList<FormProperty>();
2362: if (properties != null) {
2363: for (int i = 0; i < properties.length; i++) {
2364: if (properties[i].isChanged()
2365: && !creatorProperties.contains(properties[i])) {
2366: remainingProperties.add(properties[i]);
2367: }
2368: }
2369: }
2370:
2371: String propertyInitializationString = creator
2372: .getJavaCreationCode(creatorProperties
2373: .toArray(new FormProperty[creatorProperties
2374: .size()]), prop.getValueType(), null);
2375: if (codeData != null)
2376: propertyInitializationString = CUSTOM_CODE_MARK
2377: + propertyInitializationString + CUSTOM_CODE_MARK;
2378:
2379: if (remainingProperties.size() == 0) {
2380: generateSimpleSetterCode(
2381: prop,
2382: prop
2383: .getPartialSetterCode(propertyInitializationString),
2384: setterVariable, initCodeWriter);
2385: } else if (remainingProperties.size() > 0) {
2386: generateWholePropertyInitialization(prop, propertyType,
2387: setterVariable, propertyInitializationString,
2388: remainingProperties, initCodeWriter);
2389: }
2390: }
2391:
2392: private java.util.List<FormProperty> getCreatorProperties(
2393: CreationDescriptor.Creator creator,
2394: FormProperty[] properties) {
2395: String[] propNames = creator.getPropertyNames();
2396: java.util.List<FormProperty> creatorProperties;
2397: if (propNames.length > 0) {
2398: creatorProperties = new ArrayList<FormProperty>(
2399: propNames.length);
2400: for (int i = 0; i < propNames.length; i++) {
2401: for (int j = 0; j < properties.length; j++) {
2402: if (properties[j].getName().equals(propNames[i])) {
2403: creatorProperties.add(properties[j]);
2404: break;
2405: }
2406: }
2407: }
2408: } else {
2409: creatorProperties = new ArrayList<FormProperty>(0);
2410: }
2411: return creatorProperties;
2412: }
2413:
2414: private CreationDescriptor.Creator getPropertyCreator(Class clazz,
2415: FormProperty[] properties) {
2416: CreationDescriptor creationDesc = CreationFactory
2417: .getDescriptor(clazz);
2418: return creationDesc.findBestCreator(properties,
2419: // XXX CHANGED_ONLY ???
2420: CreationDescriptor.CHANGED_ONLY
2421: | CreationDescriptor.PLACE_ALL);
2422: }
2423:
2424: private void generateWholePropertyInitialization(FormProperty prop,
2425: Class propertyType, String setterVariable,
2426: String propertyInitializationString,
2427: java.util.List<FormProperty> remainingProperties,
2428: CodeWriter initCodeWriter) throws IOException {
2429: String variableName = formModel.getCodeStructure()
2430: .getExternalVariableName(propertyType, null, true);
2431:
2432: String javaStr = propertyType.getName() + " " + variableName
2433: + " = " + propertyInitializationString; // NOI18N
2434: initCodeWriter.write(javaStr);
2435: initCodeWriter.write(";\n"); // NOI18N
2436:
2437: for (Iterator<FormProperty> it = remainingProperties.iterator(); it
2438: .hasNext();) {
2439: generateProperty(it.next(), null, variableName + ".",
2440: initCodeWriter, null); // NOI18N
2441: }
2442:
2443: generateSimpleSetterCode(prop, prop.getWriteMethod().getName()
2444: + "(" + variableName + ")", // NOI18N
2445: setterVariable, initCodeWriter);
2446: }
2447:
2448: private void generateSimpleSetterCode(FormProperty prop,
2449: String partialSetterCode, String setterVariable,
2450: CodeWriter initCodeWriter) throws IOException {
2451:
2452: // if the setter throws checked exceptions,
2453: // we must generate try/catch block around it.
2454: Class[] exceptions = null;
2455: Method writeMethod = prop.getWriteMethod();
2456: if (writeMethod != null) {
2457: exceptions = writeMethod.getExceptionTypes();
2458: if (needTryCode(exceptions))
2459: initCodeWriter.write("try {\n"); // NOI18N
2460: else
2461: exceptions = null;
2462: }
2463:
2464: initCodeWriter
2465: .write(setterVariable + partialSetterCode + ";\n"); // NOI18N
2466:
2467: // add the catch code if needed
2468: if (exceptions != null)
2469: generateCatchCode(exceptions, initCodeWriter.getWriter());
2470: }
2471:
2472: // generates code for handling events of one component
2473: // (all component.addXXXListener() calls)
2474: private void generateComponentEvents(RADComponent component,
2475: CodeWriter initCodeWriter, CustomCodeData codeData)
2476: throws IOException {
2477: Writer writer = initCodeWriter.getWriter();
2478:
2479: EventSetDescriptor lastEventSetDesc = null;
2480: java.util.List<Event> listenerEvents = null;
2481:
2482: // we must deal somehow with the fact that for some (pathological)
2483: // events only anonymous innerclass listener can be generated
2484: // (CEDL cannot be used)
2485: int defaultMode = formModel.getSettings()
2486: .getListenerGenerationStyle();
2487: int mode = defaultMode;
2488: boolean mixedMode = false;
2489:
2490: Event[] events = component.getKnownEvents();
2491: for (int i = 0; i < events.length; i++) {
2492: Event event = events[i];
2493: if (!event.hasEventHandlers())
2494: continue;
2495:
2496: EventSetDescriptor eventSetDesc = event
2497: .getEventSetDescriptor();
2498: if (eventSetDesc != lastEventSetDesc) {
2499: if (lastEventSetDesc != null) {
2500: // new listener encountered, generate the previous one
2501: if (codeData == null)
2502: generateEmptyLineIfNeeded(writer);
2503: generateListenerAddCode(component,
2504: lastEventSetDesc, listenerEvents, mode,
2505: writer);
2506: if (mixedMode)
2507: generateListenerAddCode(component,
2508: lastEventSetDesc, listenerEvents,
2509: defaultMode, writer);
2510: if (listenerEvents != null)
2511: listenerEvents.clear();
2512: }
2513:
2514: lastEventSetDesc = eventSetDesc;
2515: }
2516:
2517: if (defaultMode != ANONYMOUS_INNERCLASSES)
2518: if (mode == defaultMode) {
2519: if (!event.isInCEDL())
2520: mode = ANONYMOUS_INNERCLASSES;
2521: } else if (event.isInCEDL())
2522: mixedMode = true;
2523:
2524: if (defaultMode == ANONYMOUS_INNERCLASSES
2525: || !event.isInCEDL()) {
2526: if (listenerEvents == null)
2527: listenerEvents = new ArrayList<Event>();
2528: listenerEvents.add(event);
2529: }
2530: }
2531:
2532: if (lastEventSetDesc != null) {
2533: // generate the last listener
2534: if (codeData == null)
2535: generateEmptyLineIfNeeded(writer);
2536: generateListenerAddCode(component, lastEventSetDesc,
2537: listenerEvents, mode, writer);
2538: if (mixedMode)
2539: generateListenerAddCode(component, lastEventSetDesc,
2540: listenerEvents, defaultMode, writer);
2541: }
2542:
2543: String postCode = (String) component
2544: .getAuxValue(AUX_LISTENERS_POST);
2545: if (codeData != null) { // build code data for editing
2546: String code = initCodeWriter.extractString();
2547: if (code != null && !code.equals("")) // NOI18N
2548: codeData.addGuardedBlock(indentCode(code));
2549: codeData
2550: .addEditableBlock(
2551: postCode,
2552: (FormProperty) component
2553: .getSyntheticProperty(PROP_LISTENERS_POST),
2554: 0, // preference index
2555: FormUtils
2556: .getBundleString("CustomCode-PostListeners"), // NOI18N
2557: FormUtils
2558: .getBundleString("MSG_JC_PostListenersCodeDesc")); // NOI18N
2559: } else if (postCode != null && !postCode.equals("")) { // NOI18N
2560: generateEmptyLineIfNeeded(writer);
2561: writer.write(postCode);
2562: if (!postCode.endsWith("\n")) // NOI18N
2563: writer.write("\n"); // NOI18N
2564: }
2565: }
2566:
2567: // generates complete code for handling one listener
2568: // (one component.addXXXListener() call)
2569: private void generateListenerAddCode(RADComponent comp,
2570: EventSetDescriptor eventSetDesc,
2571: java.util.List<Event> eventList, int mode, Writer codeWriter)
2572: throws IOException {
2573: Method addListenerMethod = eventSetDesc.getAddListenerMethod();
2574: Class[] exceptions = addListenerMethod.getExceptionTypes();
2575: if (needTryCode(exceptions))
2576: codeWriter.write("try {\n"); // NOI18N
2577: else
2578: exceptions = null;
2579:
2580: codeWriter.write(getComponentInvokeString(comp, true));
2581: codeWriter.write(addListenerMethod.getName());
2582: codeWriter.write("("); // NOI18N
2583:
2584: switch (mode) {
2585: case ANONYMOUS_INNERCLASSES:
2586: codeWriter.write("new "); // NOI18N
2587:
2588: // try to find adpater to use instead of full listener impl
2589: Class listenerType = eventSetDesc.getListenerType();
2590: Class adapterClass = BeanSupport
2591: .getAdapterForListener(listenerType);
2592: if (adapterClass != null) { // use listener adapter class
2593: codeWriter.write(getSourceClassName(adapterClass)
2594: + "() {\n"); // NOI18N
2595:
2596: for (int i = 0; i < eventList.size(); i++) {
2597: Event event = eventList.get(i);
2598: String[] paramNames = generateListenerMethodHeader(
2599: null, event.getListenerMethod(), codeWriter);
2600: generateEventHandlerCalls(event, paramNames,
2601: codeWriter, true);
2602: codeWriter.write("}\n"); // NOI18N
2603: }
2604: } else { // generate full listener implementation (all methods)
2605: codeWriter.write(getSourceClassName(listenerType)
2606: + "() {\n"); // NOI18N
2607:
2608: Method[] methods = eventSetDesc.getListenerMethods();
2609: for (int i = 0; i < methods.length; i++) {
2610: Method m = methods[i];
2611: Event event = null;
2612: for (int j = 0; j < eventList.size(); j++) {
2613: Event e = eventList.get(j);
2614: if (m.equals(e.getListenerMethod())) {
2615: event = e;
2616: break;
2617: }
2618: }
2619: String[] paramNames = generateListenerMethodHeader(
2620: null, m, codeWriter);
2621: if (event != null)
2622: generateEventHandlerCalls(event, paramNames,
2623: codeWriter, true);
2624: codeWriter.write("}\n"); // NOI18N
2625: }
2626: }
2627:
2628: codeWriter.write("}"); // NOI18N
2629: break;
2630:
2631: case CEDL_INNERCLASS:
2632: codeWriter.write(getListenerVariableName());
2633: break;
2634:
2635: case CEDL_MAINCLASS:
2636: codeWriter.write("this"); // NOI18N
2637: break;
2638: }
2639:
2640: codeWriter.write(");\n"); // NOI18N
2641:
2642: if (exceptions != null)
2643: generateCatchCode(exceptions, codeWriter);
2644: }
2645:
2646: private RADComponent codeVariableToRADComponent(CodeVariable var) {
2647: RADComponent metacomp = null;
2648: Iterator iter = var.getAttachedExpressions().iterator();
2649: if (iter.hasNext()) {
2650: Object metaobject = ((CodeExpression) iter.next())
2651: .getOrigin().getMetaObject();
2652: if (metaobject instanceof RADComponent) {
2653: metacomp = (RADComponent) metaobject;
2654: }
2655: }
2656: return metacomp;
2657: }
2658:
2659: private void addFieldVariables(CodeWriter variablesWriter)
2660: throws IOException {
2661: Iterator<CodeVariable> it = getSortedVariables(
2662: CodeVariable.FIELD, CodeVariable.SCOPE_MASK);
2663:
2664: while (it.hasNext()) {
2665: CodeVariable var = it.next();
2666: RADComponent metacomp = codeVariableToRADComponent(var);
2667: if (metacomp != null)
2668: generateComponentFieldVariable(metacomp,
2669: variablesWriter, null);
2670: // there should not be other than component variables as fields
2671: }
2672:
2673: // is there any binding?
2674: boolean anyBinding = false;
2675: for (RADComponent metacomp : formModel.getAllComponents()) {
2676: if (metacomp.hasBindings()) {
2677: anyBinding = true;
2678: if (bindingGroupVariable == null) {
2679: bindingGroupVariable = formModel.getCodeStructure()
2680: .getExternalVariableName(bindingGroupClass,
2681: "bindingGroup", true); // NOI18N
2682: }
2683: variablesWriter.write("private "
2684: + bindingGroupClass.getName() + " "
2685: + bindingGroupVariable + ";\n"); // NOI18N
2686: break;
2687: }
2688: }
2689: if (!anyBinding) {
2690: bindingGroupVariable = null;
2691: }
2692: }
2693:
2694: private void addLocalVariables(Writer writer) throws IOException {
2695: Iterator<CodeVariable> it = getSortedVariables(
2696: CodeVariable.LOCAL | CodeVariable.EXPLICIT_DECLARATION,
2697: CodeVariable.SCOPE_MASK | CodeVariable.DECLARATION_MASK);
2698:
2699: if (it.hasNext())
2700: generateEmptyLineIfNeeded(writer);
2701:
2702: while (it.hasNext()) {
2703: CodeVariable var = it.next();
2704: if (codeVariableToRADComponent(var) == null) {
2705: // other than component variable (e.g. GridBagConstraints)
2706: writer.write(var.getDeclaration().getJavaCodeString(
2707: null, null));
2708: writer.write("\n"); // NOI18N
2709: }
2710: }
2711: }
2712:
2713: private void generateComponentFieldVariable(RADComponent metacomp,
2714: CodeWriter codeWriter, CustomCodeData codeData)
2715: throws IOException {
2716: // optimization - only properties need to go through CodeWriter
2717: Writer writer = codeWriter.getWriter();
2718:
2719: CodeVariable var = metacomp.getCodeExpression().getVariable();
2720: if (isFinalFieldVariable(var.getType())) { // add also creation assignment
2721: generateComponentCreate(metacomp, codeWriter, false,
2722: codeData);
2723: } else { // simple declaration
2724: generateDeclarationPre(metacomp, writer, codeData);
2725: writer.write(var.getDeclaration().getJavaCodeString(null,
2726: null));
2727: writer.write("\n"); // NOI18N
2728:
2729: if (codeData != null) { // build code data for editing
2730: String code = indentCode(codeWriter.extractString());
2731: codeData.addGuardedBlock(code);
2732: }
2733: generateDeclarationPost(metacomp, writer, codeData);
2734: }
2735: }
2736:
2737: private static boolean isFinalFieldVariable(int varType) {
2738: return (varType & (CodeVariable.FINAL | CodeVariable.SCOPE_MASK)) == (CodeVariable.FINAL | CodeVariable.FIELD);
2739: }
2740:
2741: private static void generateDeclarationPre(RADComponent metacomp,
2742: Writer writer, CustomCodeData codeData) throws IOException {
2743: String preCode = (String) metacomp
2744: .getAuxValue(AUX_DECLARATION_PRE);
2745: if (codeData != null) { // build code data for editing
2746: codeData
2747: .addEditableBlock(
2748: preCode,
2749: (FormProperty) metacomp
2750: .getSyntheticProperty(PROP_DECLARATION_PRE),
2751: 0, // preference index
2752: FormUtils
2753: .getBundleString("CustomCode-PreDeclaration"), // NOI18N
2754: FormUtils
2755: .getBundleString("MSG_JC_PreDeclarationDesc")); // NOI18N
2756: } else if (preCode != null && !preCode.equals("")) { // NOI18N
2757: writer.write(preCode);
2758: if (!preCode.endsWith("\n")) // NOI18N
2759: writer.write("\n"); // NOI18N
2760: }
2761: }
2762:
2763: private static void generateDeclarationPost(RADComponent metacomp,
2764: Writer writer, CustomCodeData codeData) throws IOException {
2765: String postCode = (String) metacomp
2766: .getAuxValue(AUX_DECLARATION_POST);
2767: if (codeData != null) { // build code data for editing
2768: codeData
2769: .addEditableBlock(
2770: postCode,
2771: (FormProperty) metacomp
2772: .getSyntheticProperty(PROP_DECLARATION_POST),
2773: 0, // preference index
2774: FormUtils
2775: .getBundleString("CustomCode-PostDeclaration"), // NOI18N
2776: FormUtils
2777: .getBundleString("MSG_JC_PostDeclarationDesc")); // NOI18N
2778: } else if (postCode != null && !postCode.equals("")) { // NOI18N
2779: writer.write(postCode);
2780: if (!postCode.endsWith("\n")) // NOI18N
2781: writer.write("\n"); // NOI18N
2782: }
2783: }
2784:
2785: /** Adds new empty line if currentAreaNumber has raised from last time.
2786: * Should never be called when building "code data" for editing.
2787: */
2788: private void generateEmptyLineIfNeeded(Writer writer)
2789: throws IOException {
2790: if (emptyLineCounter != emptyLineRequest) {
2791: writer.write("\n"); // NOI18N
2792: }
2793: emptyLineCounter = emptyLineRequest;
2794: }
2795:
2796: private Iterator<CodeVariable> getSortedVariables(int type,
2797: int typeMask) {
2798: Collection allVariables = formModel.getCodeStructure()
2799: .getAllVariables();
2800: java.util.List<CodeVariable> variables = new ArrayList<CodeVariable>(
2801: allVariables.size());
2802: Iterator it = allVariables.iterator();
2803: while (it.hasNext()) {
2804: CodeVariable var = (CodeVariable) it.next();
2805: if (var.getDeclaredType() == org.netbeans.modules.form.Separator.class)
2806: continue; // treat AWT Separator specially - it is not a component
2807: if ((var.getType() & typeMask) == (type & typeMask))
2808: variables.add(var);
2809: }
2810: Collections.sort(variables, new Comparator<CodeVariable>() {
2811: public int compare(CodeVariable o1, CodeVariable o2) {
2812: return o1.getName().compareTo(o2.getName());
2813: }
2814: });
2815: return variables.iterator();
2816: }
2817:
2818: // Mnemonics support - start -
2819: static boolean canUseMnemonics(RADComponent comp) {
2820: return javax.swing.JLabel.class.isAssignableFrom(comp
2821: .getBeanClass())
2822: || javax.swing.AbstractButton.class
2823: .isAssignableFrom(comp.getBeanClass());
2824: }
2825:
2826: static boolean isUsingMnemonics(RADComponent comp) {
2827: Object mnem = comp.getAuxValue(PROP_GENERATE_MNEMONICS);
2828: if (mnem != null)
2829: return Boolean.TRUE.equals(mnem);
2830:
2831: return comp.getFormModel().getSettings()
2832: .getGenerateMnemonicsCode();
2833: }
2834:
2835: // Mnemonics support - end -
2836:
2837: private String getComponentParameterString(RADComponent component,
2838: boolean inMainClass) {
2839: if (component == formModel.getTopRADComponent())
2840: return inMainClass ? "this" : // NOI18N
2841: formEditorSupport.getFormDataObject().getName()
2842: + ".this"; // NOI18N
2843: else
2844: return component.getName();
2845: }
2846:
2847: private String getComponentInvokeString(RADComponent component,
2848: boolean inMainClass) {
2849: if (component == formModel.getTopRADComponent())
2850: return inMainClass ? "" : // NOI18N
2851: formEditorSupport.getFormDataObject().getName()
2852: + ".this."; // NOI18N
2853: else
2854: return component.getName() + "."; // NOI18N
2855: }
2856:
2857: static String getSourceClassName(Class cls) {
2858: return cls.getName().replace('$', '.').replace('+', '.')
2859: .replace('/', '.'); // NOI18N
2860: }
2861:
2862: private static String getVariablesHeaderComment() {
2863: if (variablesHeader == null)
2864: variablesHeader = FormUtils
2865: .getBundleString("MSG_VariablesBegin"); // NOI18N
2866: return variablesHeader;
2867: }
2868:
2869: private static String getVariablesFooterComment() {
2870: if (variablesFooter == null)
2871: variablesFooter = FormUtils
2872: .getBundleString("MSG_VariablesEnd"); // NOI18N
2873: return variablesFooter;
2874: }
2875:
2876: private static String getEventDispatchCodeComment() {
2877: if (eventDispatchCodeComment == null)
2878: eventDispatchCodeComment = FormUtils
2879: .getBundleString("MSG_EventDispatchCodeComment"); // NOI18N
2880: return eventDispatchCodeComment;
2881: }
2882:
2883: private boolean needTryCode(Class[] exceptions) {
2884: if (exceptions != null)
2885: for (int i = 0; i < exceptions.length; i++)
2886: if (Exception.class.isAssignableFrom(exceptions[i])
2887: && !RuntimeException.class
2888: .isAssignableFrom(exceptions[i])) {
2889: return true;
2890: }
2891:
2892: return false;
2893: }
2894:
2895: private void generateCatchCode(Class[] exceptions,
2896: Writer initCodeWriter) throws IOException {
2897: initCodeWriter.write("}"); // NOI18N
2898: for (int i = 0, exCount = 0; i < exceptions.length; i++) {
2899: Class exception = exceptions[i];
2900: if (!Exception.class.isAssignableFrom(exception)
2901: || RuntimeException.class
2902: .isAssignableFrom(exception))
2903: continue; // need not be caught
2904:
2905: if (i > 0) {
2906: int j;
2907: for (j = 0; j < i; j++)
2908: if (exceptions[j].isAssignableFrom(exception))
2909: break;
2910: if (j < i)
2911: continue; // a subclass of this exception already caught
2912: }
2913:
2914: initCodeWriter.write(" catch ("); // NOI18N
2915: initCodeWriter.write(getSourceClassName(exception));
2916: initCodeWriter.write(" "); // NOI18N
2917:
2918: String varName = "e" + ++exCount; // NOI18N
2919:
2920: initCodeWriter.write(varName);
2921: initCodeWriter.write(") {\n"); // NOI18N
2922: initCodeWriter.write(varName);
2923: initCodeWriter.write(".printStackTrace();\n"); // NOI18N
2924: // [shouldn't return be generated here?]
2925: initCodeWriter.write("}"); // NOI18N
2926: }
2927: initCodeWriter.write("\n"); // NOI18N
2928: }
2929:
2930: private void addDispatchListenerDeclaration(Writer codeWriter)
2931: throws IOException {
2932: generateEmptyLineIfNeeded(codeWriter);
2933:
2934: listenerVariableName = null;
2935: codeWriter.write(getListenerClassName());
2936: codeWriter.write(" "); // NOI18N
2937: codeWriter.write(getListenerVariableName());
2938: codeWriter.write(" = new "); // NOI18N
2939: codeWriter.write(getListenerClassName());
2940: codeWriter.write("();\n"); // NOI18N
2941: }
2942:
2943: private void generateDispatchListenerCode(Writer codeWriter)
2944: throws IOException { // always ends up with } as last character (no new line - because of fold footer)
2945: FormEvents formEvents = formModel.getFormEvents();
2946: boolean innerclass = formModel.getSettings()
2947: .getListenerGenerationStyle() == CEDL_INNERCLASS;
2948: boolean mainclass = formModel.getSettings()
2949: .getListenerGenerationStyle() == CEDL_MAINCLASS;
2950:
2951: Class[] listenersToImplement = formEvents.getCEDLTypes();
2952: Arrays.sort(listenersToImplement, new Comparator<Class>() {
2953: public int compare(Class o1, Class o2) {
2954: return o1.getName().compareTo(o2.getName());
2955: }
2956: });
2957:
2958: listenersInMainClass = mainclass ? listenersToImplement : null;
2959:
2960: if (innerclass) {
2961: String lClassName = getListenerClassName();
2962: codeWriter.write("private class "); // NOI18N
2963: codeWriter.write(lClassName);
2964: codeWriter.write(" implements "); // NOI18N
2965: for (int i = 0; i < listenersToImplement.length; i++) {
2966: codeWriter
2967: .write(getSourceClassName(listenersToImplement[i]));
2968: if (i + 1 < listenersToImplement.length)
2969: codeWriter.write(", "); // NOI18N
2970: }
2971: codeWriter.write(" {\n"); // NOI18N
2972: codeWriter.write(lClassName + "() {}\n"); // NOI18N Issue 72346 resp. 15242
2973: }
2974:
2975: for (int i = 0; i < listenersToImplement.length; i++) {
2976: boolean implementedInSuperclass = mainclass
2977: && listenersToImplement[i]
2978: .isAssignableFrom(formModel
2979: .getFormBaseClass());
2980:
2981: Method[] methods = listenersToImplement[i].getMethods();
2982: Arrays.sort(methods, new Comparator<Method>() {
2983: public int compare(Method o1, Method o2) {
2984: return o1.getName().compareTo(o2.getName());
2985: }
2986: });
2987:
2988: for (int j = 0; j < methods.length; j++) {
2989: Method method = methods[j];
2990: Event[] events = formEvents
2991: .getEventsForCEDLMethod(method);
2992: if (implementedInSuperclass && events.length == 0)
2993: continue;
2994:
2995: String[] paramNames = generateListenerMethodHeader(
2996: null, method, codeWriter);
2997:
2998: for (int k = 0; k < events.length; k++) {
2999: Event event = events[k];
3000: if (k + 1 < events.length
3001: || method.getReturnType() == Void.TYPE) {
3002: String componentParameterString = getComponentParameterString(
3003: event.getComponent(), false);
3004:
3005: CodeVariable variable = event.getComponent()
3006: .getCodeExpression().getVariable();
3007: if (variable != null
3008: && ((variable.getType() & CodeVariable.LOCAL) == CodeVariable.LOCAL)) {
3009: codeWriter
3010: .write(FormUtils
3011: .getFormattedBundleString(
3012: "MSG_WrongLocalVariableSettingComment", // NOI18N
3013: new Object[] { componentParameterString }));
3014: }
3015:
3016: codeWriter.write(k == 0 ? "if (" : "else if ("); // NOI18N
3017: codeWriter.write(paramNames[0]);
3018: codeWriter.write(".getSource() == "); // NOI18N
3019: codeWriter.write(componentParameterString);
3020: codeWriter.write(") {\n"); // NOI18N
3021:
3022: generateEventHandlerCalls(event, paramNames,
3023: codeWriter, false);
3024: codeWriter.write("}\n"); // NOI18N
3025:
3026: } else { // the listener method returns something
3027: if (k > 0)
3028: codeWriter.write("else {\n"); // NOI18N
3029: generateEventHandlerCalls(event, paramNames,
3030: codeWriter, false);
3031: if (k > 0)
3032: codeWriter.write("}\n"); // NOI18N
3033: }
3034: }
3035: if (implementedInSuperclass)
3036: generateSuperListenerCall(method, paramNames,
3037: codeWriter);
3038:
3039: if (j + 1 < methods.length
3040: || i + 1 < listenersToImplement.length)
3041: codeWriter.write("}\n\n"); // NOI18N
3042: else if (innerclass)
3043: codeWriter.write("}\n"); // NOI18N
3044: else
3045: codeWriter.write("}"); // last char // NOI18N
3046: }
3047: }
3048:
3049: if (innerclass)
3050: codeWriter.write("}"); // last char // NOI18N
3051: }
3052:
3053: // modifies the form class declaration to implement required listeners
3054: // (when event dispatching code is generated as CEDL_MAINCLASS)
3055: private void ensureMainClassImplementsListeners() {
3056: if (listenersInMainClass == listenersInMainClass_lastSet)
3057: return; // no change from last time
3058:
3059: if (listenersInMainClass != null
3060: && listenersInMainClass_lastSet != null
3061: && listenersInMainClass.length == listenersInMainClass_lastSet.length) {
3062: boolean different = false;
3063: for (int i = 0; i < listenersInMainClass.length; i++)
3064: if (listenersInMainClass[i] != listenersInMainClass_lastSet[i]) {
3065: different = true;
3066: break;
3067: }
3068: if (!different)
3069: return; // no change from last time
3070: }
3071:
3072: final Set<String> toRemove = new HashSet<String>();
3073: if (listenersInMainClass_lastSet != null) {
3074: for (int i = 0; i < listenersInMainClass_lastSet.length; i++) {
3075: Class cls = listenersInMainClass_lastSet[i];
3076: boolean remains = false;
3077: if (listenersInMainClass != null)
3078: for (int j = 0; j < listenersInMainClass.length; j++)
3079: if (cls == listenersInMainClass[j]) {
3080: remains = true;
3081: break;
3082: }
3083: if (!remains) {
3084: toRemove.add(cls.getName());
3085: }
3086: }
3087: }
3088:
3089: final FileObject fo = formEditorSupport.getFormDataObject()
3090: .getPrimaryFile();
3091: JavaSource js = JavaSource.forFileObject(fo);
3092: try {
3093: js.runModificationTask(new CancellableTask<WorkingCopy>() {
3094: public void cancel() {
3095: }
3096:
3097: public void run(WorkingCopy wcopy) throws Exception {
3098: wcopy.toPhase(JavaSource.Phase.RESOLVED);
3099:
3100: ClassTree mainClassTree = findMainClass(wcopy, fo
3101: .getName());
3102: ClassTree origMainTree = mainClassTree;
3103:
3104: TreePath classTreePath = wcopy.getTrees().getPath(
3105: wcopy.getCompilationUnit(), mainClassTree);
3106: Element mainClassElm = wcopy.getTrees().getElement(
3107: classTreePath);
3108:
3109: if (mainClassElm != null) {
3110: java.util.List<TypeElement> actualInterfaces = new ArrayList<TypeElement>();
3111: TreeMaker maker = wcopy.getTreeMaker();
3112: // first take the current interfaces and exclude the removed ones
3113: int infIndex = 0;
3114: for (TypeMirror infMirror : ((TypeElement) mainClassElm)
3115: .getInterfaces()) {
3116: TypeElement infElm = (TypeElement) wcopy
3117: .getTypes().asElement(infMirror);
3118: actualInterfaces.add(infElm);
3119: if (toRemove.contains(infElm
3120: .getQualifiedName().toString())) {
3121: mainClassTree = maker
3122: .removeClassImplementsClause(
3123: mainClassTree, infIndex);
3124: }
3125: ++infIndex;
3126: }
3127:
3128: // then ensure all required interfaces are present
3129: if (listenersInMainClass != null) {
3130: for (int i = 0; i < listenersInMainClass.length; i++) {
3131: String name = listenersInMainClass[i]
3132: .getName();
3133: boolean alreadyIn = false;
3134: for (TypeElement infElm : actualInterfaces)
3135: if (name.equals(infElm
3136: .getQualifiedName()
3137: .toString())) {
3138: alreadyIn = true;
3139: break;
3140: }
3141: if (!alreadyIn) {
3142: TypeElement inf2add = wcopy
3143: .getElements()
3144: .getTypeElement(name);
3145: ExpressionTree infTree2add = inf2add != null ? maker
3146: .QualIdent(inf2add)
3147: : maker.Identifier(name);
3148: mainClassTree = maker
3149: .addClassImplementsClause(
3150: mainClassTree,
3151: infTree2add);
3152: }
3153: }
3154: }
3155:
3156: if (origMainTree != mainClassTree) {
3157: wcopy.rewrite(origMainTree, mainClassTree);
3158: }
3159:
3160: }
3161: }
3162: }).commit();
3163:
3164: listenersInMainClass_lastSet = listenersInMainClass;
3165: } catch (IOException ex) {
3166: Logger.getLogger(JavaCodeGenerator.class.getName()).log(
3167: Level.SEVERE, ex.getLocalizedMessage(), ex);
3168: }
3169: }
3170:
3171: private static ClassTree findMainClass(
3172: CompilationController controller, String name) {
3173: for (Tree t : controller.getCompilationUnit().getTypeDecls()) {
3174: if (t.getKind() == Tree.Kind.CLASS
3175: && name.equals(((ClassTree) t).getSimpleName()
3176: .toString())) {
3177:
3178: return (ClassTree) t;
3179: }
3180: }
3181: return null;
3182: }
3183:
3184: // ---------
3185: // generating general code structure (metadata from codestructure package)
3186:
3187: // java code for a statement
3188: private static String getStatementJavaString(
3189: CodeStatement statement, String this Str) {
3190: CodeExpression parent = statement.getParentExpression();
3191: String parentStr;
3192: if (parent != null) {
3193: parentStr = getExpressionJavaString(parent, this Str);
3194: if ("this".equals(parentStr)) // NOI18N
3195: parentStr = this Str;
3196: } else
3197: parentStr = null;
3198:
3199: CodeExpression[] params = statement.getStatementParameters();
3200: String[] paramsStr = new String[params.length];
3201: for (int i = 0; i < params.length; i++)
3202: paramsStr[i] = getExpressionJavaString(params[i], this Str);
3203:
3204: return statement.getJavaCodeString(parentStr, paramsStr);
3205: }
3206:
3207: // java code for an expression
3208: static String getExpressionJavaString(CodeExpression exp,
3209: String this Str) {
3210: CodeVariable var = exp.getVariable();
3211: if (var != null)
3212: return var.getName();
3213:
3214: CodeExpressionOrigin origin = exp.getOrigin();
3215: if (origin == null)
3216: return null;
3217:
3218: CodeExpression parent = origin.getParentExpression();
3219: String parentStr;
3220: if (parent != null) {
3221: parentStr = getExpressionJavaString(parent, this Str);
3222: if ("this".equals(parentStr)) // NOI18N
3223: parentStr = this Str;
3224: } else
3225: parentStr = null;
3226:
3227: CodeExpression[] params = origin.getCreationParameters();
3228: String[] paramsStr = new String[params.length];
3229: for (int i = 0; i < params.length; i++)
3230: paramsStr[i] = getExpressionJavaString(params[i], this Str);
3231:
3232: return origin.getJavaCodeString(parentStr, paramsStr);
3233: }
3234:
3235: // ---------
3236: // Events
3237:
3238: private boolean anyEvents() {
3239: return formModel.getFormEvents().hasEventsInCEDL();
3240: }
3241:
3242: private String getListenerClassName() {
3243: if (listenerClassName == null) {
3244: String initText = formEditorSupport
3245: .getInitComponentSection().getText();
3246: int index = initText.lastIndexOf("private class "); // NOI18N
3247: if (index >= 0) {
3248: StringBuffer nameBuffer = new StringBuffer(16);
3249: index += "private class ".length(); // NOI18N
3250:
3251: int length = initText.length();
3252: while (index < length && initText.charAt(index) == ' ')
3253: index++;
3254:
3255: int i = index;
3256: while (i < length && initText.charAt(i) != ' ')
3257: nameBuffer.append(initText.charAt(i++));
3258:
3259: if (i < length)
3260: listenerClassName = nameBuffer.toString();
3261: }
3262:
3263: if (listenerClassName == null) {
3264: javax.swing.text.Document document = formEditorSupport
3265: .getDocument();
3266: try {
3267: String wholeText = document.getText(0, document
3268: .getLength());
3269: listenerClassName = DEFAULT_LISTENER_CLASS_NAME;
3270: while (wholeText.indexOf(listenerClassName) >= 0)
3271: listenerClassName = "_" + listenerClassName; // NOI18N
3272: } catch (javax.swing.text.BadLocationException ex) {
3273: } // ignore
3274: }
3275:
3276: if (listenerClassName == null)
3277: listenerClassName = DEFAULT_LISTENER_CLASS_NAME;
3278: }
3279:
3280: return listenerClassName;
3281: }
3282:
3283: private String getListenerVariableName() {
3284: if (listenerVariableName == null) {
3285: listenerVariableName = "formListener"; // NOI18N
3286: CodeStructure codeStructure = formModel.getCodeStructure();
3287: for (int i = 1; codeStructure
3288: .isVariableNameReserved(listenerVariableName); i++)
3289: listenerVariableName = "formListener" + i; // NOI18N
3290: }
3291: return listenerVariableName;
3292: }
3293:
3294: // -----------------------------------------------------------------------------
3295: // Event handlers
3296:
3297: /** Generates the specified event handler.
3298: */
3299: private void generateEventHandler(String handlerName,
3300: Method originalMethod, String bodyText,
3301: String annotationText) {
3302: if (!initialized || !canGenerate)
3303: return;
3304:
3305: InteriorSection sec = getEventHandlerSection(handlerName);
3306: if (sec != null && bodyText == null)
3307: return; // already exists, no need to generate
3308:
3309: IndentEngine engine = IndentEngine.find(formEditorSupport
3310: .getDocument());
3311: StringWriter buffer = new StringWriter();
3312:
3313: try {
3314: if (sec == null) {
3315: sec = insertEvendHandlerSection(handlerName);
3316: }
3317: Writer codeWriter = engine.createWriter(formEditorSupport
3318: .getDocument(), sec.getStartPosition().getOffset(),
3319: buffer);
3320: int i0, i1, i2;
3321:
3322: if (annotationText != null) {
3323: codeWriter.write(annotationText);
3324: codeWriter.flush();
3325: }
3326: i0 = buffer.getBuffer().length();
3327: generateListenerMethodHeader(handlerName, originalMethod,
3328: codeWriter);
3329: codeWriter.flush();
3330: i1 = buffer.getBuffer().length();
3331: if (bodyText == null)
3332: bodyText = getDefaultEventBody();
3333: codeWriter.write(bodyText);
3334: codeWriter.flush();
3335: i2 = buffer.getBuffer().length();
3336: codeWriter.write("}\n"); // footer with new line // NOI18N
3337: codeWriter.flush();
3338:
3339: if (i0 != 0) {
3340: formEditorSupport.getDocument().insertString(
3341: sec.getStartPosition().getOffset(),
3342: annotationText, null);
3343: }
3344: sec.setHeader(buffer.getBuffer().substring(i0, i1));
3345: sec.setBody(buffer.getBuffer().substring(i1, i2));
3346: sec.setFooter(buffer.getBuffer().substring(i2));
3347:
3348: codeWriter.close();
3349: } catch (javax.swing.text.BadLocationException e) {
3350: return;
3351: } catch (java.io.IOException ioe) {
3352: return;
3353: }
3354:
3355: clearUndo();
3356: }
3357:
3358: /** Removes the specified event handler - removes the whole method together with the user code!
3359: * @param handlerName The name of the event handler
3360: */
3361: private boolean deleteEventHandler(String handlerName) {
3362: InteriorSection section = getEventHandlerSection(handlerName);
3363: if (section == null || !initialized || !canGenerate)
3364: return false;
3365:
3366: // if there is another guarded section right before or after without
3367: // a gap, the neighbor sections could merge strangely - prevent this by
3368: // inserting an empty line (#94165)
3369: int startPos = section.getStartPosition().getOffset();
3370: int endPos = section.getEndPosition().getOffset();
3371: for (GuardedSection sec : formEditorSupport
3372: .getGuardedSectionManager().getGuardedSections()) {
3373: if (sec.getEndPosition().getOffset() + 1 == startPos) { // close section before
3374: try {
3375: formEditorSupport.getDocument().insertString(
3376: startPos, "\n", null); // NOI18N
3377: } catch (javax.swing.text.BadLocationException ex) {
3378: } // should not happen, ignore
3379: } else if (sec.getStartPosition().getOffset() == endPos + 1) { // close section after
3380: try {
3381: formEditorSupport.getDocument().insertString(
3382: endPos + 1, "\n", null); // NOI18N
3383: } catch (javax.swing.text.BadLocationException ex) {
3384: } // should not happen, ignore
3385: }
3386: }
3387: section.deleteSection();
3388: clearUndo();
3389:
3390: return true;
3391: }
3392:
3393: private String getDefaultEventBody() {
3394: return FormUtils.getBundleString("MSG_EventHandlerBody"); // NOI18N
3395: }
3396:
3397: /** Renames the specified event handler to the given new name.
3398: * @param oldHandlerName The old name of the event handler
3399: * @param newHandlerName The new name of the event handler
3400: */
3401: private void renameEventHandler(String oldHandlerName,
3402: String newHandlerName) {
3403: InteriorSection sec = getEventHandlerSection(oldHandlerName);
3404: if (sec == null || !initialized || !canGenerate)
3405: return;
3406:
3407: String header = sec.getHeader();
3408:
3409: // find the old handler name in the handler method header
3410: int index = header.indexOf('(');
3411: if (index < 0)
3412: return; // should not happen unless the handler code is corrupted
3413: index = header.substring(0, index).lastIndexOf(oldHandlerName);
3414: if (index < 0)
3415: return; // old name not found; should not happen
3416:
3417: IndentEngine engine = IndentEngine.find(formEditorSupport
3418: .getDocument());
3419: StringWriter buffer = new StringWriter();
3420: Writer codeWriter = engine.createWriter(formEditorSupport
3421: .getDocument(), sec.getStartPosition().getOffset(),
3422: buffer);
3423: try {
3424: codeWriter.write(header.substring(0, index));
3425: codeWriter.write(newHandlerName);
3426: codeWriter.write(header.substring(index
3427: + oldHandlerName.length()));
3428: codeWriter.flush();
3429: int i1 = buffer.getBuffer().length();
3430: codeWriter.write("}\n"); // NOI18N // footer with new line
3431: codeWriter.flush();
3432:
3433: sec.setHeader(buffer.getBuffer().substring(0, i1));
3434: sec.setFooter(buffer.getBuffer().substring(i1));
3435: sec.setName(getEventSectionName(newHandlerName));
3436:
3437: codeWriter.close();
3438: } catch (java.beans.PropertyVetoException e) {
3439: return;
3440: } catch (IOException e) {
3441: return;
3442: }
3443:
3444: clearUndo();
3445: }
3446:
3447: /** Focuses the specified event handler in the editor. */
3448: private void gotoEventHandler(String handlerName) {
3449: InteriorSection sec = getEventHandlerSection(handlerName);
3450: if (sec != null && initialized) {
3451: formEditorSupport.openAt(sec.getCaretPosition());
3452: }
3453: }
3454:
3455: /** Gets the body (text) of event handler of given name. */
3456: String getEventHandlerText(String handlerName) {
3457: InteriorSection section = getEventHandlerSection(handlerName);
3458: if (section != null) {
3459: // XXX try to use section.getBody instead
3460: String tx = section.getText();
3461: tx = tx.substring(tx.indexOf("{") + 1, tx.lastIndexOf("}"))
3462: .trim()
3463: + "\n"; // NOI18N
3464: return tx;
3465: }
3466: return null;
3467: }
3468:
3469: private String getEventHandlerAnnotation(String handlerName,
3470: boolean removeAnnotations) {
3471: String code = null;
3472: InteriorSection section = getEventHandlerSection(handlerName);
3473: if (section != null) {
3474: FormJavaSource fjs = FormEditor
3475: .getFormJavaSource(formModel);
3476: code = fjs.getAnnotationCode(handlerName, section
3477: .getStartPosition(), section.getEndPosition(),
3478: removeAnnotations);
3479: }
3480: return code;
3481: }
3482:
3483: // ------------------------------------------------------------------------------------------
3484: // Private methods
3485:
3486: /** Clears undo buffer after code generation */
3487: private void clearUndo() {
3488: formEditorSupport.discardEditorUndoableEdits();
3489: }
3490:
3491: // sections acquirement
3492:
3493: private InteriorSection getEventHandlerSection(String handlerName) {
3494: return formEditorSupport.getGuardedSectionManager()
3495: .findInteriorSection(getEventSectionName(handlerName));
3496: }
3497:
3498: private InteriorSection insertEvendHandlerSection(String handlerName)
3499: throws javax.swing.text.BadLocationException {
3500: int endPos = formEditorSupport.getInitComponentSection()
3501: .getEndPosition().getOffset();
3502: // find last event handler
3503: for (GuardedSection sec : formEditorSupport
3504: .getGuardedSectionManager().getGuardedSections()) {
3505: if (sec instanceof InteriorSection) {
3506: int pos = sec.getEndPosition().getOffset();
3507: if (pos > endPos) {
3508: endPos = pos;
3509: }
3510: }
3511: }
3512: // if there is another guarded section following with no gap, insert empty line (#109242)
3513: for (GuardedSection sec : formEditorSupport
3514: .getGuardedSectionManager().getGuardedSections()) {
3515: if (sec.getStartPosition().getOffset() == endPos + 1) {
3516: formEditorSupport.getDocument().insertString(
3517: endPos + 1, "\n", null); // NOI18N
3518: break;
3519: }
3520: }
3521: // create the new guarded section
3522: return formEditorSupport.getGuardedSectionManager()
3523: .createInteriorSection(
3524: formEditorSupport.getDocument().createPosition(
3525: endPos + 1),
3526: getEventSectionName(handlerName));
3527: }
3528:
3529: // other
3530:
3531: private String getEventSectionName(String handlerName) {
3532: return EVT_SECTION_PREFIX + handlerName;
3533: }
3534:
3535: private String[] generateListenerMethodHeader(String methodName,
3536: Method originalMethod, Writer writer) throws IOException {
3537: Class[] paramTypes = originalMethod.getParameterTypes();
3538: String[] paramNames;
3539:
3540: if (paramTypes.length == 1
3541: && EventObject.class.isAssignableFrom(paramTypes[0])) {
3542: paramNames = new String[] { formSettings
3543: .getEventVariableName() };
3544: } else {
3545: paramNames = new String[paramTypes.length];
3546: for (int i = 0; i < paramTypes.length; i++)
3547: paramNames[i] = "param" + i; // NOI18N
3548: }
3549:
3550: // generate the method
3551: writer.write(methodName != null ? "private " : "public "); // NOI18N
3552: writer
3553: .write(getSourceClassName(originalMethod
3554: .getReturnType()));
3555: writer.write(" "); // NOI18N
3556: writer.write(methodName != null ? methodName : originalMethod
3557: .getName());
3558: writer.write("("); // NOI18N
3559:
3560: for (int i = 0; i < paramTypes.length; i++) {
3561: writer.write(getSourceClassName(paramTypes[i]));
3562: writer.write(" "); // NOI18N
3563: writer.write(paramNames[i]);
3564: if (i + 1 < paramTypes.length)
3565: writer.write(", "); // NOI18N
3566: }
3567: writer.write(")"); // NOI18N
3568:
3569: Class[] exceptions = originalMethod.getExceptionTypes();
3570: if (exceptions.length != 0) {
3571: writer.write("throws "); // NOI18N
3572: for (int i = 0; i < exceptions.length; i++) {
3573: writer.write(getSourceClassName(exceptions[i]));
3574: if (i + 1 < exceptions.length)
3575: writer.write(", "); // NOI18N
3576: }
3577: }
3578:
3579: writer.write(" {\n"); // NOI18N
3580:
3581: return paramNames;
3582: }
3583:
3584: private void generateSuperListenerCall(Method method,
3585: String[] paramNames, Writer codeWriter) throws IOException {
3586: if (method.getReturnType() != Void.TYPE)
3587: codeWriter.write("return "); // NOI18N
3588:
3589: codeWriter.write("super."); // NOI18N
3590: codeWriter.write(method.getName());
3591: codeWriter.write("("); // NOI18N
3592:
3593: for (int i = 0; i < paramNames.length; i++) {
3594: codeWriter.write(paramNames[i]);
3595: if (i + 1 < paramNames.length)
3596: codeWriter.write(", "); // NOI18N
3597: }
3598:
3599: codeWriter.write(");\n"); // NOI18N
3600: }
3601:
3602: private void generateEventHandlerCalls(Event event,
3603: String[] paramNames, Writer codeWriter,
3604: boolean useShortNameIfPossible) throws IOException {
3605: String mainClassRef = null;
3606:
3607: String[] handlers = event.getEventHandlers();
3608: for (int i = 0; i < handlers.length; i++) {
3609: if (i + 1 == handlers.length
3610: && event.getListenerMethod().getReturnType() != Void.TYPE)
3611: codeWriter.write("return "); // NOI18N
3612:
3613: // with anonymous innerclasses, try to avoid generating full names
3614: // (for the reason some old forms might be used as innerclasses)
3615: if (!useShortNameIfPossible
3616: || event.getListenerMethod().getName().equals(
3617: handlers[i])) {
3618: if (mainClassRef == null)
3619: mainClassRef = formEditorSupport
3620: .getFormDataObject().getName()
3621: + ".this."; // NOI18N
3622: codeWriter.write(mainClassRef);
3623: }
3624: codeWriter.write(handlers[i]);
3625: codeWriter.write("("); // NOI18N
3626:
3627: for (int j = 0; j < paramNames.length; j++) {
3628: codeWriter.write(paramNames[j]);
3629: if (j + 1 < paramNames.length)
3630: codeWriter.write(", "); // NOI18N
3631: }
3632:
3633: codeWriter.write(");\n"); // NOI18N
3634: }
3635: }
3636:
3637: void regenerateCode() {
3638: if (!codeUpToDate) {
3639: codeUpToDate = true;
3640: regenerateVariables();
3641: regenerateInitComponents();
3642: ensureMainClassImplementsListeners();
3643: FormModel.t("code regenerated"); // NOI18N
3644: }
3645: }
3646:
3647: static CustomCodeData getCodeData(RADComponent metacomp) {
3648: CodeGenerator gen = FormEditor.getCodeGenerator(metacomp
3649: .getFormModel());
3650: return gen instanceof JavaCodeGenerator ? ((JavaCodeGenerator) gen)
3651: .getCodeData0(metacomp)
3652: : null;
3653: }
3654:
3655: private CustomCodeData getCodeData0(RADComponent metacomp) {
3656: CustomCodeData codeData = new CustomCodeData();
3657: codeData
3658: .setDefaultCategory(CustomCodeData.CodeCategory.CREATE_AND_INIT);
3659: CodeWriter codeWriter = new CodeWriter(new StringWriter(1024),
3660: true);
3661: cleanup();
3662:
3663: CodeVariable var = metacomp.getCodeExpression().getVariable();
3664:
3665: try { // creation & init code
3666: if (var != null && !isFinalFieldVariable(var.getType()))
3667: generateComponentCreate(metacomp, codeWriter, true,
3668: codeData);
3669: // with final field variable the creation statement is part of declaration
3670:
3671: addInitCode(metacomp, codeWriter, codeData);
3672:
3673: if (var != null) { // add declaration
3674: boolean fieldVariable = (var.getType() & CodeVariable.SCOPE_MASK) == CodeVariable.FIELD;
3675: if (fieldVariable) {
3676: codeData
3677: .setDefaultCategory(CustomCodeData.CodeCategory.DECLARATION);
3678: generateComponentFieldVariable(metacomp,
3679: codeWriter, codeData);
3680: }
3681: codeData.setDeclarationData(!fieldVariable, var
3682: .getType()
3683: & CodeVariable.ALL_MODIF_MASK);
3684: }
3685: } catch (IOException ex) { // should not happen
3686: ErrorManager.getDefault().notify(
3687: ErrorManager.INFORMATIONAL, ex);
3688: }
3689:
3690: cleanup();
3691:
3692: return codeData;
3693: }
3694:
3695: private String indentCode(String code) {
3696: return indentCode(code, 0, null);
3697: }
3698:
3699: private String indentCode(String code, int minIndentLevel,
3700: IndentEngine refEngine) {
3701: int spacesPerTab = 4;
3702: boolean braceOnNewLine = false;
3703:
3704: if (refEngine != null) {
3705: Class engineClass = refEngine.getClass();
3706: try {
3707: Method m = engineClass.getMethod("getSpacesPerTab", // NOI18N
3708: new Class[0]);
3709: spacesPerTab = ((Integer) m.invoke(refEngine,
3710: new Object[0])).intValue();
3711: } catch (Exception ex) {
3712: } // ignore
3713:
3714: try {
3715: Method m = engineClass.getMethod(
3716: "getJavaFormatNewlineBeforeBrace", // NOI18N
3717: new Class[0]);
3718: braceOnNewLine = ((Boolean) m.invoke(refEngine,
3719: new Object[0])).booleanValue();
3720: } catch (Exception ex) {
3721: } // ignore
3722: }
3723:
3724: StringBuffer tab = new StringBuffer(spacesPerTab);
3725: for (int i = 0; i < spacesPerTab; i++)
3726: tab.append(" "); // NOI18N
3727:
3728: return doIndentation(code, minIndentLevel, tab.toString(),
3729: braceOnNewLine);
3730: }
3731:
3732: // simple indentation method
3733: private static String doIndentation(String code,
3734: int minIndentLevel, String tab, boolean braceOnNewLine) {
3735:
3736: int indentLevel = minIndentLevel;
3737: boolean lastLineEmpty = false;
3738: int codeLength = code.length();
3739: StringBuffer buffer = new StringBuffer(codeLength);
3740:
3741: int i = 0;
3742: while (i < codeLength) {
3743: int lineStart = i;
3744: int lineEnd;
3745: boolean startingSpace = true;
3746: boolean firstClosingBr = false;
3747: boolean closingBr = false;
3748: int lastOpeningBr = -1;
3749: int endingSpace = -1;
3750: boolean insideString = false;
3751: int brackets = 0;
3752: char c;
3753:
3754: do { // go through one line
3755: c = code.charAt(i);
3756: if (!insideString) {
3757: if (c == '}') {
3758: lastOpeningBr = -1;
3759: endingSpace = -1;
3760: if (startingSpace) { // first non-space char on the line
3761: firstClosingBr = true;
3762: closingBr = true;
3763: startingSpace = false;
3764: lineStart = i;
3765: } else if (!closingBr)
3766: brackets--;
3767: } else if (c == ')') {
3768:
3769: int bracketCount = 0;
3770: int begin = i;
3771: while (begin < code.length()
3772: && (code.charAt(begin) == ')')) {
3773: bracketCount += 1;
3774: begin += 1;
3775: }
3776:
3777: lastOpeningBr = -1;
3778: endingSpace = -1;
3779: if (startingSpace) { // first non-space char on the line
3780: firstClosingBr = true;
3781: closingBr = true;
3782: startingSpace = false;
3783: lineStart = i;
3784: } else if (!closingBr)
3785: brackets -= bracketCount;
3786: if (bracketCount > 1) {
3787: i += bracketCount - 1;
3788: }
3789: } else if (c == '{' || c == '(') {
3790: closingBr = false;
3791: lastOpeningBr = -1;
3792: endingSpace = -1;
3793: if (startingSpace) { // first non-space char on the line
3794: startingSpace = false;
3795: lineStart = i;
3796: } else if (c == '{') // possible last brace on the line
3797: lastOpeningBr = i;
3798: brackets++;
3799: } else if (c == '\"') { // start of String, its content is ignored
3800: insideString = true;
3801: lastOpeningBr = -1;
3802: endingSpace = -1;
3803: if (startingSpace) { // first non-space char on the line
3804: startingSpace = false;
3805: lineStart = i;
3806: }
3807:
3808: } else if (c == ' ' || c == '\t') {
3809: if (endingSpace < 0)
3810: endingSpace = i;
3811: } else {
3812: if (startingSpace) { // first non-space char on the line
3813: startingSpace = false;
3814: lineStart = i;
3815: }
3816: if (c != '\n') { // this char is not a whitespace
3817: endingSpace = -1;
3818: if (lastOpeningBr > -1)
3819: lastOpeningBr = -1;
3820: }
3821: }
3822: } else if (c == '\"' && code.charAt(i - 1) != '\\') // end of String
3823: insideString = false;
3824:
3825: i++;
3826: } while (c != '\n' && i < codeLength);
3827:
3828: if ((i - 1 == lineStart && code.charAt(lineStart) == '\n')
3829: || (i - 2 == lineStart && code.charAt(lineStart) == '\r')) {
3830: // the line is empty
3831: if (!lastLineEmpty) {
3832: buffer.append("\n"); // NOI18N
3833: lastLineEmpty = true;
3834: }
3835: continue; // skip second and more empty lines
3836: } else
3837: lastLineEmpty = false;
3838:
3839: // adjust indentation level for the line
3840: if (firstClosingBr) { // the line starts with } or )
3841: if (indentLevel > minIndentLevel)
3842: indentLevel--;
3843: if (brackets < 0)
3844: brackets = 0; // don't change indentation for the next line
3845: }
3846:
3847: // write indentation space
3848: for (int j = 0; j < indentLevel; j++)
3849: buffer.append(tab);
3850:
3851: if (lastOpeningBr > -1 && braceOnNewLine) {
3852: // write the line without last opening brace
3853: // (indentation option "Add New Line Before Brace")
3854: endingSpace = lastOpeningBr;
3855: c = code.charAt(endingSpace - 1);
3856: while (c == ' ' || c == '\t') {
3857: endingSpace--;
3858: c = code.charAt(endingSpace - 1);
3859: }
3860: i = lastOpeningBr;
3861: brackets = 0;
3862: }
3863:
3864: // calculate line end
3865: if (endingSpace < 0) {
3866: if (c == '\n')
3867: if (code.charAt(i - 2) == '\r')
3868: lineEnd = i - 2; // \r\n at the end of the line
3869: else
3870: lineEnd = i - 1; // \n at the end of the line
3871: else
3872: lineEnd = i; // end of whole code string
3873: } else
3874: // skip spaces at the end of the line
3875: lineEnd = endingSpace;
3876:
3877: // write the line
3878: buffer.append(code.substring(lineStart, lineEnd));
3879: buffer.append("\n"); // NOI18N
3880:
3881: // calculate indentation level for the next line
3882: if (brackets < 0) {
3883: if (indentLevel > minIndentLevel)
3884: indentLevel += brackets;
3885:
3886: } else if (brackets > 0)
3887: indentLevel++;
3888: }
3889: return buffer.toString();
3890: }
3891:
3892: /**
3893: * Class for filtering generated code - processing special marks in the code
3894: * (provided by properties/property editors).
3895: * This way (e.g.) code for ResourceBundle.getBundle can be optimized
3896: * (caching the bundle in a variable) or line comments for property setters
3897: * placed correctly.
3898: * [In future pre-init and post-init code could be done this way as well
3899: * (and it would work also for nested properties or layout constraints).]
3900: * To work correctly, the write method requires to be given complete
3901: * statements as they appear in initComponents(), so it can add a preceding
3902: * or following statement).
3903: */
3904: private class CodeWriter {
3905: private Writer writer;
3906: private boolean inMethod;
3907:
3908: CodeWriter(Writer writer, boolean method) {
3909: this .writer = writer;
3910: this .inMethod = method;
3911: }
3912:
3913: void write(String str) throws IOException {
3914: int idx = str.indexOf(CODE_MARK);
3915: if (idx >= 0) {
3916: StringBuilder buf = new StringBuilder(str.length());
3917: if (idx > 0) {
3918: buf.append(str.substring(0, idx));
3919: }
3920: String lineComment = null;
3921: String codeToSubst = null;
3922: String varType = null;
3923:
3924: do {
3925: String part;
3926: if (str.startsWith(CODE_MARK_LINE_COMMENT, idx)) {
3927: // line comment to be added at the end of the line
3928: int sub = idx + CODE_MARK_LINE_COMMENT.length();
3929: idx = str.indexOf(CODE_MARK, sub);
3930: String lc = idx < 0 ? str.substring(sub) : str
3931: .substring(sub, idx);
3932: if (lineComment == null) {
3933: lineComment = lc;
3934: } else if (!lineComment.equals(lc)) {
3935: lineComment = lineComment + " " + lc; // NOI18N
3936: }
3937: continue;
3938: } else if (str.startsWith(CODE_MARK_VARIABLE_SUBST,
3939: idx)) {
3940: // there is a code that can be cached in a local varaible to
3941: // avoid calling it multiple times (e.g. ResourceBundle.getBundle)
3942: int sub = idx
3943: + CODE_MARK_VARIABLE_SUBST.length();
3944: idx = str.indexOf(CODE_MARK, sub);
3945: String s = idx < 0 ? str.substring(sub) : str
3946: .substring(sub, idx);
3947: part = null;
3948: if (codeToSubst == null) {
3949: codeToSubst = s;
3950: } else if (varType == null) {
3951: varType = s;
3952: } else {
3953: if (inMethod) {
3954: part = replaceCodeWithVariable(
3955: codeToSubst, varType, s,
3956: lineComment, writer);
3957: } else { // can't replace when in member field variable init
3958: part = codeToSubst;
3959: }
3960: codeToSubst = varType = null;
3961: }
3962: if (part == null) { // no real code in this fragment
3963: continue;
3964: }
3965: } else if (str.startsWith(CODE_MARK_END, idx)) { // plain code follows
3966: int sub = idx + CODE_MARK_END.length();
3967: idx = str.indexOf(CODE_MARK, sub);
3968: part = idx < 0 ? str.substring(sub) : str
3969: .substring(sub, idx);
3970: } else {
3971: int sub = idx;
3972: idx = str.indexOf(CODE_MARK, sub);
3973: part = idx < 0 ? str.substring(sub) : str
3974: .substring(sub, idx);
3975: }
3976: if (lineComment != null) {
3977: int eol = part.indexOf('\n');
3978: if (eol >= 0) {
3979: buf.append(part.substring(0, eol));
3980: buf.append(" // "); // NOI18N
3981: buf.append(lineComment);
3982: buf.append("\n"); // NOI18N
3983: part = part.substring(eol + 1);
3984: lineComment = null;
3985: }
3986: }
3987: buf.append(part);
3988: } while (idx >= 0);
3989:
3990: if (lineComment != null) {
3991: buf.append(" // "); // NOI18N
3992: buf.append(lineComment);
3993: }
3994:
3995: str = buf.toString();
3996: }
3997: writer.write(str);
3998: }
3999:
4000: Writer getWriter() {
4001: return writer;
4002: }
4003:
4004: void clearBuffer() {
4005: if (writer instanceof StringWriter) {
4006: StringBuffer buf = ((StringWriter) writer).getBuffer();
4007: buf.delete(0, buf.length());
4008: }
4009: }
4010:
4011: public String extractString() {
4012: String str = writer.toString();
4013: clearBuffer();
4014: return str;
4015: }
4016: }
4017:
4018: private String replaceCodeWithVariable(String codeToSubst,
4019: String varType, String varName, String lineComment,
4020: Writer writer) throws IOException {
4021: String variable;
4022: if (repeatedCodeVariables != null) {
4023: variable = repeatedCodeVariables.get(codeToSubst);
4024: } else {
4025: repeatedCodeVariables = new HashMap<String, String>();
4026: variable = null;
4027: }
4028: if (variable == null) {
4029: Class type;
4030: try {
4031: type = FormUtils.loadClass(varType, formModel);
4032: } catch (Exception ex) { // should not happen - load things like ResourceBundle or ResourceMap
4033: Logger.getLogger(getClass().getName()).log(Level.INFO,
4034: "", ex); // NOI18N
4035: return codeToSubst;
4036: } catch (LinkageError ex) {
4037: Logger.getLogger(getClass().getName()).log(Level.INFO,
4038: "", ex); // NOI18N
4039: return codeToSubst;
4040: }
4041: variable = formModel.getCodeStructure()
4042: .getExternalVariableName(type, varName, true);
4043: repeatedCodeVariables.put(codeToSubst, variable);
4044: // add varaible declaration
4045: writer.write(varType);
4046: writer.write(" "); // NOI18N
4047: writer.write(variable);
4048: writer.write(" = "); // NOI18N
4049: writer.write(codeToSubst);
4050: writer.write(";"); // NOI18N
4051: if (lineComment != null) {
4052: writer.write(" // "); // NOI18N
4053: writer.write(lineComment);
4054: }
4055: writer.write("\n"); // NOI18N
4056: }
4057: return variable;
4058: }
4059:
4060: //
4061: // {{{ FormListener
4062: //
4063:
4064: private class FormListener implements FormModelListener {
4065:
4066: public void formChanged(FormModelEvent[] events) {
4067: if (events == null)
4068: return;
4069:
4070: boolean modifying = false;
4071: boolean toBeSaved = false;
4072: boolean toBeClosed = false;
4073:
4074: for (int i = 0; i < events.length; i++) {
4075: FormModelEvent ev = events[i];
4076:
4077: // form loaded
4078: if (ev.getChangeType() == FormModelEvent.FORM_LOADED) {
4079: if (formModel.getSettings()
4080: .getListenerGenerationStyle() == CEDL_MAINCLASS) {
4081: if (FormEditor.getFormEditor(formModel)
4082: .needPostCreationUpdate()) {
4083: listenersInMainClass_lastSet = new Class[0];
4084: } else {
4085: listenersInMainClass_lastSet = formModel
4086: .getFormEvents().getCEDLTypes();
4087: }
4088: }
4089: continue;
4090: }
4091:
4092: if (ev.isModifying())
4093: modifying = true;
4094:
4095: if (ev.getChangeType() == FormModelEvent.EVENT_HANDLER_ADDED) {
4096: String handlerName = ev.getEventHandler();
4097: String bodyText = ev.getNewEventHandlerContent();
4098: String annotationText = ev
4099: .getNewEventHandlerAnnotation();
4100: if ((ev.getCreatedDeleted() || bodyText != null)
4101: && ev.getComponent().isInModel()) {
4102: if (!ev.getCreatedDeleted()) {
4103: ev
4104: .setOldEventHandlerContent(getEventHandlerText(handlerName));
4105: }
4106:
4107: generateEventHandler(
4108: handlerName,
4109: (ev.getComponentEvent() == null) ? formModel
4110: .getFormEvents()
4111: .getOriginalListenerMethod(
4112: handlerName)
4113: : ev.getComponentEvent()
4114: .getListenerMethod(),
4115: bodyText, annotationText);
4116: }
4117: if (events.length == 1 && bodyText == null)
4118: gotoEventHandler(handlerName);
4119: } else if (ev.getChangeType() == FormModelEvent.EVENT_HANDLER_REMOVED) {
4120: if (ev.getCreatedDeleted()) {
4121: String handlerName = ev.getEventHandler();
4122: ev
4123: .setOldEventHandlerContent(getEventHandlerText(handlerName));
4124: ev
4125: .setOldEventHandlerAnnotation(getEventHandlerAnnotation(
4126: handlerName, true));
4127: deleteEventHandler(handlerName);
4128: }
4129: } else if (ev.getChangeType() == FormModelEvent.EVENT_HANDLER_RENAMED) {
4130: renameEventHandler(ev.getOldEventHandler(), ev
4131: .getNewEventHandler());
4132: } else if (ev.getChangeType() == FormModelEvent.FORM_TO_BE_SAVED)
4133: toBeSaved = true;
4134: else if (ev.getChangeType() == FormModelEvent.FORM_TO_BE_CLOSED)
4135: toBeClosed = true;
4136: }
4137:
4138: if (modifying)
4139: codeUpToDate = false;
4140:
4141: if ((!codeUpToDate && toBeSaved)
4142: || (isJavaEditorDisplayed())) {
4143: regenerateCode();
4144: }
4145:
4146: if (toBeSaved) {
4147: RADComponent[] components = formModel
4148: .getModelContainer().getSubBeans();
4149: for (int i = 0; i < components.length; i++)
4150: serializeComponentsRecursively(components[i]);
4151: }
4152: }
4153:
4154: private boolean isJavaEditorDisplayed() {
4155: boolean showing = false;
4156: if (EventQueue.isDispatchThread()) { // issue 91715
4157: FormDataObject dobj = FormEditor
4158: .getFormDataObject(formModel);
4159: if (dobj != null) { // #89793, #70439
4160: JEditorPane[] jeditPane = dobj
4161: .getFormEditorSupport().getOpenedPanes();
4162: if (jeditPane != null) {
4163: for (int i = 0; i < jeditPane.length; i++) {
4164: if (showing = jeditPane[i].isShowing()) {
4165: break;
4166: }
4167: }
4168: }
4169: }
4170: }
4171: return showing;
4172: }
4173:
4174: private void serializeComponentsRecursively(RADComponent comp) {
4175: Object value = comp.getAuxValue(AUX_CODE_GENERATION);
4176: if (comp.hasHiddenState()
4177: || (value != null && VALUE_SERIALIZE.equals(value))) {
4178: String serializeTo = (String) comp
4179: .getAuxValue(AUX_SERIALIZE_TO);
4180: if (serializeTo != null) {
4181: try {
4182: FileObject fo = formEditorSupport
4183: .getFormDataObject().getPrimaryFile();
4184: FileObject serFile = fo.getParent()
4185: .getFileObject(serializeTo, "ser"); // NOI18N
4186: if (serFile == null) {
4187: serFile = fo.getParent().createData(
4188: serializeTo, "ser"); // NOI18N
4189: }
4190: if (serFile != null) {
4191: FileLock lock = null;
4192: ObjectOutputStream oos = null;
4193: try {
4194: lock = serFile.lock();
4195: oos = new OOS(serFile
4196: .getOutputStream(lock));
4197: if (comp instanceof RADVisualContainer) {
4198: // [PENDING - remove temporarily the subcomponents]
4199: }
4200: oos.writeObject(comp.getBeanInstance());
4201: } finally {
4202: if (oos != null)
4203: oos.close();
4204: if (lock != null)
4205: lock.releaseLock();
4206: }
4207: } else {
4208: // [PENDING - handle problem]
4209: }
4210: } catch (java.io.NotSerializableException e) {
4211: e.printStackTrace();
4212: // [PENDING - notify error]
4213: } catch (java.io.IOException e) {
4214: e.printStackTrace();
4215: // [PENDING - notify error]
4216: } catch (Exception e) {
4217: e.printStackTrace();
4218: // [PENDING - notify error]
4219: }
4220: } else {
4221: // [PENDING - notify error]
4222: }
4223: }
4224: if (comp instanceof ComponentContainer) {
4225: RADComponent[] children = ((ComponentContainer) comp)
4226: .getSubBeans();
4227: for (int i = 0; i < children.length; i++) {
4228: serializeComponentsRecursively(children[i]);
4229: }
4230: }
4231: }
4232: }
4233:
4234: // hacked ObjectOutputStream - to replace special values used by property
4235: // editors (like SuperColor from ColorEditor or NbImageIcon from IconEditor)
4236: private static class OOS extends ObjectOutputStream {
4237: OOS(OutputStream out) throws IOException {
4238: super (out);
4239: enableReplaceObject(true);
4240: }
4241:
4242: @Override
4243: protected Object replaceObject(Object obj) throws IOException {
4244: if (obj.getClass().getName().startsWith("org.netbeans.") // NOI18N
4245: || obj.getClass().getName().startsWith(
4246: "org.openide.")) // NOI18N
4247: {
4248: if (obj instanceof java.awt.Color)
4249: return new java.awt.Color(((java.awt.Color) obj)
4250: .getRGB());
4251: if (obj instanceof javax.swing.ImageIcon)
4252: return new javax.swing.ImageIcon(
4253: ((javax.swing.ImageIcon) obj).getImage());
4254: }
4255: return obj;
4256: }
4257: }
4258:
4259: //
4260: // {{{ CodeGenerateEditor
4261: //
4262:
4263: final public static class CodeGenerateEditor extends
4264: PropertyEditorSupport {
4265: private RADComponent component;
4266:
4267: /** Display Names for alignment. */
4268: private static final String generateName = FormUtils
4269: .getBundleString("VALUE_codeGen_generate"); // NOI18N
4270: private static final String serializeName = FormUtils
4271: .getBundleString("VALUE_codeGen_serialize"); // NOI18N
4272:
4273: public CodeGenerateEditor(RADComponent component) {
4274: this .component = component;
4275: }
4276:
4277: /** @return names of the possible directions */
4278: @Override
4279: public String[] getTags() {
4280: if (component.hasHiddenState()) {
4281: return new String[] { serializeName };
4282: } else {
4283: return new String[] { generateName, serializeName };
4284: }
4285: }
4286:
4287: /** @return text for the current value */
4288: @Override
4289: public String getAsText() {
4290: Integer value = (Integer) getValue();
4291: if (value.equals(VALUE_SERIALIZE))
4292: return serializeName;
4293: else
4294: return generateName;
4295: }
4296:
4297: /** Setter.
4298: * @param str string equal to one value from directions array
4299: */
4300: @Override
4301: public void setAsText(String str) {
4302: if (component.hasHiddenState()) {
4303: setValue(VALUE_SERIALIZE);
4304: } else {
4305: if (serializeName.equals(str)) {
4306: setValue(VALUE_SERIALIZE);
4307: } else if (generateName.equals(str)) {
4308: setValue(VALUE_GENERATE_CODE);
4309: }
4310: }
4311: }
4312: }
4313:
4314: // }}}
4315:
4316: //
4317: // {{{ CodeProperty
4318: //
4319:
4320: private class CodeProperty extends FormProperty {
4321: // using FormProperty to be able to disable change firing for temporary
4322: // changes in CodeCustomizer
4323: private String auxKey;
4324: private RADComponent component;
4325: private FormModel.FormVersion versionLevel;
4326:
4327: CodeProperty(RADComponent metacomp, String propertyName,
4328: String auxKey, String displayName,
4329: String shortDescription,
4330: FormModel.FormVersion versionLevel) {
4331: super (propertyName, String.class, displayName, null);
4332: setShortDescription(shortDescription); // FormProperty adds the type to the tooltip
4333: this .auxKey = auxKey;
4334: component = metacomp;
4335: this .versionLevel = versionLevel;
4336: try {
4337: reinstateProperty();
4338: } catch (Exception ex) { // should not happen
4339: ErrorManager.getDefault().notify(
4340: ErrorManager.INFORMATIONAL, ex);
4341: }
4342: }
4343:
4344: public void setTargetValue(Object value) {
4345: if (value != null && !(value instanceof String))
4346: throw new IllegalArgumentException();
4347:
4348: if (value != null && !value.equals("")) { // NOI18N
4349: component.setAuxValue(auxKey, value);
4350: component.getFormModel().raiseVersionLevel(
4351: versionLevel, versionLevel);
4352: } else if (component.getAuxValue(auxKey) != null) {
4353: component.getAuxValues().remove(auxKey);
4354: }
4355: }
4356:
4357: public Object getTargetValue() {
4358: Object value = component.getAuxValue(auxKey);
4359: if (value == null)
4360: value = ""; // NOI18N
4361: return value;
4362: }
4363:
4364: @Override
4365: public boolean supportsDefaultValue() {
4366: return true;
4367: }
4368:
4369: @Override
4370: public Object getDefaultValue() {
4371: return ""; // NOI18N
4372: }
4373:
4374: @Override
4375: protected void propertyValueChanged(Object old, Object current) {
4376: super .propertyValueChanged(old, current);
4377: if (isChangeFiring()) {
4378: formModel.fireSyntheticPropertyChanged(component,
4379: getName(), old, current);
4380: if (component.getNodeReference() != null) {
4381: component.getNodeReference()
4382: .firePropertyChangeHelper(getName(), null,
4383: null);
4384: }
4385: }
4386: }
4387:
4388: @Override
4389: public PropertyEditor getExpliciteEditor() {
4390: return new CodeEditor();
4391: }
4392:
4393: @Override
4394: public boolean canWrite() {
4395: return JavaCodeGenerator.this .canGenerate
4396: && !formModel.isReadOnly();
4397: }
4398: }
4399:
4400: private class CodeEditor extends PropertyEditorSupport implements
4401: ExPropertyEditor {
4402: private PropertyEnv env;
4403:
4404: public void attachEnv(PropertyEnv env) {
4405: this .env = env;
4406: }
4407:
4408: @Override
4409: public Component getCustomEditor() {
4410: return new CustomCodeEditor(this , env, FormEditor
4411: .createCodeEditorPane(formModel));
4412: }
4413:
4414: @Override
4415: public boolean supportsCustomEditor() {
4416: return true;
4417: }
4418: }
4419:
4420: // }}}
4421:
4422: // Properties
4423:
4424: private class VariablesModifierProperty extends
4425: PropertySupport.ReadWrite {
4426:
4427: private VariablesModifierProperty() {
4428: super (PROP_VARIABLE_MODIFIER, Integer.class, FormUtils
4429: .getBundleString("PROP_VARIABLES_MODIFIER"), // NOI18N
4430: FormUtils
4431: .getBundleString("HINT_VARIABLES_MODIFIER")); // NOI18N
4432: }
4433:
4434: public void setValue(Object value) {
4435: if (!(value instanceof Integer))
4436: throw new IllegalArgumentException();
4437:
4438: Integer oldValue = (Integer) getValue();
4439: Integer newValue = (Integer) value;
4440: int varType;
4441: int variablesModifier = newValue.intValue();
4442: if (formModel.getSettings().getVariablesLocal()) {
4443: varType = CodeVariable.LOCAL
4444: | (variablesModifier & CodeVariable.FINAL); // | CodeVariable.EXPLICIT_DECLARATION;
4445: } else
4446: varType = CodeVariable.FIELD | variablesModifier;
4447:
4448: formModel.getCodeStructure()
4449: .setDefaultVariableType(varType);
4450: formModel.getSettings().setVariablesModifier(
4451: variablesModifier);
4452: formModel.fireSyntheticPropertyChanged(null,
4453: PROP_VARIABLE_MODIFIER, oldValue, newValue);
4454: FormEditor formEditor = FormEditor.getFormEditor(formModel);
4455: formEditor.getFormRootNode().firePropertyChangeHelper(
4456: PROP_VARIABLE_MODIFIER, oldValue, newValue);
4457: }
4458:
4459: public Object getValue() {
4460: return new Integer(formModel.getSettings()
4461: .getVariablesModifier());
4462: }
4463:
4464: @Override
4465: public boolean supportsDefaultValue() {
4466: return true;
4467: }
4468:
4469: @Override
4470: public void restoreDefaultValue() {
4471: setValue(new Integer(FormLoaderSettings.getInstance()
4472: .getVariablesModifier()));
4473: }
4474:
4475: @Override
4476: public boolean isDefaultValue() {
4477: return (formModel.getSettings().getVariablesModifier() == FormLoaderSettings
4478: .getInstance().getVariablesModifier());
4479: }
4480:
4481: @Override
4482: public boolean canWrite() {
4483: return JavaCodeGenerator.this .canGenerate
4484: && !JavaCodeGenerator.this .formModel.isReadOnly();
4485: }
4486:
4487: @Override
4488: public PropertyEditor getPropertyEditor() {
4489: boolean local = formModel.getSettings().getVariablesLocal();
4490: return local ? new ModifierEditor(Modifier.FINAL)
4491: : new ModifierEditor(Modifier.PUBLIC
4492: | Modifier.PROTECTED | Modifier.PRIVATE
4493: | Modifier.STATIC | Modifier.FINAL
4494: | Modifier.TRANSIENT | Modifier.VOLATILE);
4495: }
4496:
4497: }
4498:
4499: private class LocalVariablesProperty extends
4500: PropertySupport.ReadWrite {
4501:
4502: private LocalVariablesProperty() {
4503: super (PROP_VARIABLE_LOCAL, Boolean.TYPE, FormUtils
4504: .getBundleString("PROP_VARIABLES_LOCAL"), // NOI18N
4505: FormUtils.getBundleString("HINT_VARIABLES_LOCAL")); // NOI18N
4506: }
4507:
4508: public void setValue(Object value) {
4509: if (!(value instanceof Boolean))
4510: throw new IllegalArgumentException();
4511: if (value.equals(getValue()))
4512: return;
4513:
4514: Boolean oldValue = (Boolean) getValue();
4515: Boolean newValue = (Boolean) value;
4516: FormSettings formSettings = formModel.getSettings();
4517: boolean variablesLocal = newValue.booleanValue();
4518: int variablesModifier = variablesLocal ? (formSettings
4519: .getVariablesModifier() & CodeVariable.FINAL)
4520: : formSettings.getVariablesModifier();
4521: Integer oldModif = new Integer(formModel.getSettings()
4522: .getVariablesModifier());
4523: Integer newModif = new Integer(variablesModifier);
4524: int varType = variablesLocal ? CodeVariable.LOCAL
4525: | variablesModifier // | CodeVariable.EXPLICIT_DECLARATION
4526: : CodeVariable.FIELD | variablesModifier;
4527:
4528: formModel.getCodeStructure()
4529: .setDefaultVariableType(varType);
4530: formSettings.setVariablesLocal(variablesLocal);
4531: formSettings.setVariablesModifier(variablesModifier);
4532: formModel.fireSyntheticPropertyChanged(null,
4533: PROP_VARIABLE_LOCAL, oldValue, newValue);
4534: formModel.fireSyntheticPropertyChanged(null,
4535: PROP_VARIABLE_MODIFIER, oldModif, newModif);
4536: FormEditor formEditor = FormEditor.getFormEditor(formModel);
4537: FormNode formRootNode = formEditor.getFormRootNode();
4538: formRootNode.firePropertyChangeHelper(PROP_VARIABLE_LOCAL,
4539: oldValue, newValue);
4540: formRootNode.firePropertyChangeHelper(
4541: PROP_VARIABLE_MODIFIER, oldModif, newModif);
4542: }
4543:
4544: public Object getValue() {
4545: return Boolean.valueOf(formModel.getSettings()
4546: .getVariablesLocal());
4547: }
4548:
4549: @Override
4550: public boolean supportsDefaultValue() {
4551: return true;
4552: }
4553:
4554: @Override
4555: public void restoreDefaultValue() {
4556: setValue(Boolean.valueOf(FormLoaderSettings.getInstance()
4557: .getVariablesLocal()));
4558: }
4559:
4560: @Override
4561: public boolean isDefaultValue() {
4562: return (formModel.getSettings().getVariablesLocal() == FormLoaderSettings
4563: .getInstance().getVariablesLocal());
4564: }
4565:
4566: @Override
4567: public boolean canWrite() {
4568: return JavaCodeGenerator.this .canGenerate
4569: && !JavaCodeGenerator.this .formModel.isReadOnly();
4570: }
4571:
4572: }
4573:
4574: private class GenerateMnemonicsCodeProperty extends
4575: PropertySupport.ReadWrite {
4576:
4577: private GenerateMnemonicsCodeProperty() {
4578: super (
4579: PROP_GENERATE_MNEMONICS,
4580: Boolean.TYPE,
4581: FormUtils
4582: .getBundleString("PROP_GENERATE_MNEMONICS"), // NOI18N
4583: FormUtils
4584: .getBundleString("HINT_GENERATE_MNEMONICS2")); // NOI18N
4585: }
4586:
4587: public void setValue(Object value) {
4588: if (!(value instanceof Boolean))
4589: throw new IllegalArgumentException();
4590:
4591: Boolean oldValue = (Boolean) getValue();
4592: Boolean newValue = (Boolean) value;
4593: formModel.getSettings().setGenerateMnemonicsCode(
4594: newValue.booleanValue());
4595: formModel.fireSyntheticPropertyChanged(null,
4596: PROP_GENERATE_MNEMONICS, oldValue, newValue);
4597: FormEditor formEditor = FormEditor.getFormEditor(formModel);
4598: formEditor.getFormRootNode().firePropertyChangeHelper(
4599: PROP_GENERATE_MNEMONICS, oldValue, newValue);
4600: }
4601:
4602: public Object getValue() {
4603: return Boolean.valueOf(formModel.getSettings()
4604: .getGenerateMnemonicsCode());
4605: }
4606:
4607: @Override
4608: public boolean canWrite() {
4609: return JavaCodeGenerator.this .canGenerate
4610: && !JavaCodeGenerator.this .formModel.isReadOnly();
4611: }
4612:
4613: @Override
4614: public boolean supportsDefaultValue() {
4615: return true;
4616: }
4617:
4618: @Override
4619: public void restoreDefaultValue() {
4620: setValue(Boolean.valueOf(FormLoaderSettings.getInstance()
4621: .getGenerateMnemonicsCode()));
4622: }
4623:
4624: @Override
4625: public boolean isDefaultValue() {
4626: return (formModel.getSettings().getGenerateMnemonicsCode() == FormLoaderSettings
4627: .getInstance().getGenerateMnemonicsCode());
4628: }
4629:
4630: }
4631:
4632: private class ListenerGenerationStyleProperty extends
4633: PropertySupport.ReadWrite {
4634:
4635: private ListenerGenerationStyleProperty() {
4636: super (
4637: PROP_LISTENER_GENERATION_STYLE,
4638: Integer.class,
4639: FormUtils
4640: .getBundleString("PROP_LISTENER_GENERATION_STYLE"), // NOI18N
4641: FormUtils
4642: .getBundleString("HINT_LISTENER_GENERATION_STYLE")); // NOI18N
4643: }
4644:
4645: public void setValue(Object value) {
4646: if (!(value instanceof Integer))
4647: throw new IllegalArgumentException();
4648:
4649: Integer oldValue = (Integer) getValue();
4650: Integer newValue = (Integer) value;
4651: formModel.getSettings().setListenerGenerationStyle(
4652: newValue.intValue());
4653: formModel.fireSyntheticPropertyChanged(null,
4654: PROP_LISTENER_GENERATION_STYLE, oldValue, newValue);
4655: FormEditor formEditor = FormEditor.getFormEditor(formModel);
4656: formEditor.getFormRootNode().firePropertyChangeHelper(
4657: PROP_LISTENER_GENERATION_STYLE, oldValue, newValue);
4658: }
4659:
4660: public Object getValue() {
4661: return new Integer(formModel.getSettings()
4662: .getListenerGenerationStyle());
4663: }
4664:
4665: @Override
4666: public boolean supportsDefaultValue() {
4667: return true;
4668: }
4669:
4670: @Override
4671: public void restoreDefaultValue() {
4672: setValue(new Integer(FormLoaderSettings.getInstance()
4673: .getListenerGenerationStyle()));
4674: }
4675:
4676: @Override
4677: public boolean isDefaultValue() {
4678: return (formModel.getSettings()
4679: .getListenerGenerationStyle() == FormLoaderSettings
4680: .getInstance().getListenerGenerationStyle());
4681: }
4682:
4683: @Override
4684: public boolean canWrite() {
4685: return JavaCodeGenerator.this .canGenerate
4686: && !JavaCodeGenerator.this .formModel.isReadOnly();
4687: }
4688:
4689: @Override
4690: public PropertyEditor getPropertyEditor() {
4691: return new FormLoaderSettingsBeanInfo.ListenerGenerationStyleEditor();
4692: }
4693:
4694: }
4695:
4696: // analogical to ListenerGenerationStyleProperty ...
4697: private class LayoutCodeTargetProperty extends
4698: PropertySupport.ReadWrite {
4699:
4700: private LayoutCodeTargetProperty() {
4701: super (
4702: FormLoaderSettings.PROP_LAYOUT_CODE_TARGET,
4703: Integer.class,
4704: FormUtils
4705: .getBundleString("PROP_LAYOUT_CODE_TARGET"), // NOI18N
4706: FormUtils
4707: .getBundleString("HINT_LAYOUT_CODE_TARGET")); // NOI18N
4708: }
4709:
4710: public void setValue(Object value) {
4711: if (!(value instanceof Integer))
4712: throw new IllegalArgumentException();
4713:
4714: Integer oldValue = (Integer) getValue();
4715: Integer newValue = (Integer) value;
4716: formModel.getSettings().setLayoutCodeTarget(
4717: newValue.intValue());
4718: FormEditor.updateProjectForNaturalLayout(formModel);
4719: formModel.fireSyntheticPropertyChanged(null,
4720: FormLoaderSettings.PROP_LAYOUT_CODE_TARGET,
4721: oldValue, newValue);
4722: FormEditor.getFormEditor(formModel).getFormRootNode()
4723: .firePropertyChangeHelper(
4724: FormLoaderSettings.PROP_LAYOUT_CODE_TARGET,
4725: oldValue, newValue);
4726: }
4727:
4728: public Object getValue() {
4729: return new Integer(formModel.getSettings()
4730: .getLayoutCodeTarget());
4731: }
4732:
4733: @Override
4734: public boolean supportsDefaultValue() {
4735: return true;
4736: }
4737:
4738: @Override
4739: public void restoreDefaultValue() {
4740: setValue(new Integer(FormLoaderSettings.getInstance()
4741: .getLayoutCodeTarget()));
4742: }
4743:
4744: @Override
4745: public boolean isDefaultValue() {
4746: return (formModel.getSettings().getLayoutCodeTarget() == FormLoaderSettings
4747: .getInstance().getLayoutCodeTarget());
4748: }
4749:
4750: @Override
4751: public boolean canWrite() {
4752: return JavaCodeGenerator.this .canGenerate
4753: && !JavaCodeGenerator.this .formModel.isReadOnly();
4754: }
4755:
4756: @Override
4757: public PropertyEditor getPropertyEditor() {
4758: return new FormLoaderSettingsBeanInfo.LayoutCodeTargetEditor(
4759: true);
4760: }
4761:
4762: }
4763: }
|