001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form;
043:
044: import java.awt.Component;
045: import java.awt.Dimension;
046: import java.awt.EventQueue;
047: import java.awt.event.ComponentAdapter;
048: import java.awt.event.ComponentEvent;
049: import javax.swing.BorderFactory;
050: import javax.swing.JEditorPane;
051: import javax.swing.JLabel;
052: import javax.swing.JScrollPane;
053: import javax.swing.JTextField;
054: import javax.swing.event.DocumentEvent;
055: import javax.swing.event.DocumentListener;
056: import org.jdesktop.layout.GroupLayout;
057: import org.netbeans.api.editor.guards.SimpleSection;
058: import org.openide.util.Utilities;
059:
060: /**
061: * Custom editor for RADConnectionPropertyEditor. Allows editing the custom code
062: * of a property.
063: *
064: * @author Tomas Pavek
065: */
066: class CodeCustomEditor extends javax.swing.JPanel implements
067: DocumentListener, Runnable {
068:
069: private RADConnectionPropertyEditor propertyEditor;
070:
071: private JEditorPane codePane;
072: private boolean ignoreUpdate;
073:
074: private JLabel headerLabel = new JLabel();
075: private JLabel footerLabel = new JLabel();
076: private JTextField typeField = new JTextField();
077: private JScrollPane jScrollPane = new JScrollPane() {
078: // We want the editor pane's height to accommodate to the actual number
079: // of lines. For that we also need to include the horizontal scrollbar
080: // height into the preferred height. See also invokeUpdate method.
081: @Override
082: public Dimension getPreferredSize() {
083: Dimension prefSize = super .getPreferredSize();
084: Component hBar = getHorizontalScrollBar();
085: if (hBar != null && hBar.isVisible()) {
086: prefSize = new Dimension(prefSize.width,
087: prefSize.height
088: + hBar.getPreferredSize().height);
089: }
090: return prefSize;
091: }
092: };
093:
094: public CodeCustomEditor(RADConnectionPropertyEditor propertyEditor,
095: FormModel formModel, FormProperty property) {
096: this .propertyEditor = propertyEditor;
097:
098: codePane = new JEditorPane();
099: jScrollPane.setViewportView(codePane);
100:
101: resetLayout();
102:
103: int codePos = -1;
104: FormDataObject dobj = FormEditor.getFormDataObject(formModel);
105: SimpleSection sec = dobj.getFormEditorSupport()
106: .getInitComponentSection();
107: if ((property instanceof RADProperty)
108: && (property.getWriteMethod() != null)) {
109: RADComponent metacomp = ((RADProperty) property)
110: .getRADComponent();
111: headerLabel.setFont(codePane.getFont());
112: headerLabel.setText("<html>" + metacomp.getName() + ".<b>" // NOI18N
113: + property.getWriteMethod().getName() + "</b>("); // NOI18N
114: footerLabel.setFont(codePane.getFont());
115: footerLabel.setText(");"); // NOI18N
116:
117: String codeSnippet;
118: if (metacomp != formModel.getTopRADComponent()) {
119: codeSnippet = " " + metacomp.getName() + "."
120: + property.getWriteMethod().getName() + "("; // NOI18N
121: } else {
122: codeSnippet = " " + property.getWriteMethod().getName()
123: + "("; // NOI18N
124: }
125: codePos = sec.getText().indexOf(codeSnippet);
126: if (codePos >= 0) {
127: codePos += codeSnippet.length();
128: }
129: } else {
130: headerLabel.setText(FormUtils
131: .getBundleString("CodeCustomEditor.codeLabel")); // NOI18N
132: }
133: if (codePos < 0) {
134: codePos = sec.getText().indexOf('{') + 2;
135: }
136: FormUtils.setupEditorPane(codePane, dobj.getPrimaryFile(),
137: codePos + sec.getStartPosition().getOffset());
138:
139: typeField.setBorder(BorderFactory.createEmptyBorder());
140: typeField.setEditable(false);
141: typeField.setFont(codePane.getFont());
142: typeField.setText(Utilities.getClassName(property
143: .getValueType()));
144:
145: codePane.getDocument().addDocumentListener(this );
146:
147: // issue 103809
148: addComponentListener(new ComponentAdapter() {
149: @Override
150: public void componentShown(ComponentEvent ev) {
151: revalidate();
152: repaint();
153: }
154: });
155: }
156:
157: private void resetLayout() {
158: GroupLayout layout = new GroupLayout(this );
159: this .setLayout(layout);
160: layout.setAutocreateContainerGaps(true);
161: layout.setHorizontalGroup(layout.createSequentialGroup().add(
162: headerLabel, GroupLayout.PREFERRED_SIZE,
163: GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
164: .add(3).add(
165: layout.createParallelGroup(GroupLayout.LEADING)
166: .add(jScrollPane,
167: GroupLayout.PREFERRED_SIZE,
168: 320, Short.MAX_VALUE).add(
169: typeField)).add(3).add(
170: footerLabel));
171:
172: int prefHeight;
173: int maxHeight;
174: if (jScrollPane.getPreferredSize().getHeight() > 300) {
175: prefHeight = 300;
176: maxHeight = GroupLayout.DEFAULT_SIZE;
177: } else {
178: prefHeight = GroupLayout.DEFAULT_SIZE;
179: maxHeight = GroupLayout.PREFERRED_SIZE;
180: }
181:
182: layout.setVerticalGroup(layout.createSequentialGroup().add(
183: layout.createParallelGroup(GroupLayout.LEADING).add(
184: layout.createSequentialGroup().add(
185: jScrollPane.getInsets().top).add(
186: layout.createParallelGroup().add(
187: headerLabel).add(footerLabel)))
188: .add(jScrollPane, GroupLayout.DEFAULT_SIZE,
189: prefHeight, maxHeight)).add(typeField,
190: GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
191: GroupLayout.PREFERRED_SIZE));
192: }
193:
194: void setValue(
195: RADConnectionPropertyEditor.RADConnectionDesignValue value) {
196: if (value != null
197: && value.getType() == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_CODE) {
198: ignoreUpdate = true;
199: codePane.setText(value.getCode());
200: ignoreUpdate = false;
201:
202: resetLayout();
203: }
204: }
205:
206: // DocumentListener
207: public void insertUpdate(DocumentEvent e) {
208: invokeUpdate();
209: }
210:
211: // DocumentListener
212: public void removeUpdate(DocumentEvent e) {
213: invokeUpdate();
214: }
215:
216: // DocumentListener
217: public void changedUpdate(DocumentEvent e) {
218: }
219:
220: private void invokeUpdate() {
221: if (!ignoreUpdate) {
222: ignoreUpdate = true;
223: EventQueue.invokeLater(this ); // set the value
224:
225: // also update the editor pane size according to the number of lines
226: // (can't just track line count changes because the preferred height
227: // also changes when the horizontal scrollbar appears/hides)
228: revalidate();
229: repaint();
230: }
231: }
232:
233: // updates the value in the property editor
234: public void run() {
235: propertyEditor
236: .setValue(new RADConnectionPropertyEditor.RADConnectionDesignValue(
237: codePane.getText()));
238: ignoreUpdate = false;
239: }
240: }
|