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.beans.*;
045: import java.util.*;
046: import java.awt.*;
047:
048: import org.openide.awt.Mnemonics;
049:
050: /** The MethodPicker is a form which allows user to pick one of methods
051: * with specified required return type.
052: *
053: * @author Ian Formanek
054: */
055: public class MethodPicker extends javax.swing.JPanel {
056:
057: static final long serialVersionUID = 7355140527892160804L;
058:
059: /**
060: * Initializes the Form.
061: *
062: * @param formModel form model.
063: * @param componentToSelect component whose methods should be displayed.
064: * @param requiredType required return type of the method.
065: */
066: public MethodPicker(FormModel formModel,
067: RADComponent componentToSelect, Class requiredType) {
068: this .requiredType = requiredType;
069: initComponents();
070:
071: java.util.List<RADComponent> componentsList = formModel
072: .getComponentList();
073: Collections.sort(componentsList,
074: new ParametersPicker.ComponentComparator());
075: components = new RADComponent[componentsList.size()];
076: componentsList.toArray(components);
077:
078: int selIndex = -1;
079: for (Iterator it = componentsList.iterator(); it.hasNext();) {
080: RADComponent radComp = (RADComponent) it.next();
081: if (componentToSelect != null
082: && componentToSelect == radComp)
083: selIndex = componentsCombo.getItemCount();
084: if (radComp == formModel.getTopRADComponent())
085: componentsCombo.addItem(FormUtils
086: .getBundleString("CTL_FormTopContainerName")); // NOI18N
087: else
088: componentsCombo.addItem(radComp.getName());
089: }
090: if (selIndex >= 0)
091: componentsCombo.setSelectedIndex(selIndex);
092:
093: updateMethodList();
094:
095: Mnemonics.setLocalizedText(componentLabel, FormUtils
096: .getBundleString("CTL_CW_Component")); // NOI18N
097: Mnemonics.setLocalizedText(listLabel, FormUtils
098: .getBundleString("CTL_CW_MethodList")); // NOI18N
099:
100: componentsCombo
101: .getAccessibleContext()
102: .setAccessibleDescription(
103: FormUtils
104: .getBundleString("ACSD_CTL_CW_Component")); // NOI18N
105: methodList.getAccessibleContext().setAccessibleDescription(
106: FormUtils.getBundleString("ACSD_CTL_CW_MethodList")); // NOI18N
107: getAccessibleContext().setAccessibleDescription(
108: FormUtils.getBundleString("ACSD_MethodPicker")); // NOI18N
109: }
110:
111: public boolean isPickerValid() {
112: return pickerValid;
113: }
114:
115: private void setPickerValid(boolean v) {
116: boolean old = pickerValid;
117: pickerValid = v;
118: firePropertyChange("pickerValid", old, pickerValid); // NOI18N
119: }
120:
121: RADComponent getSelectedComponent() {
122: return selectedComponent;
123: }
124:
125: void setSelectedComponent(RADComponent selectedComponent) {
126: if (selectedComponent != null)
127: componentsCombo
128: .setSelectedItem(selectedComponent.getName());
129: }
130:
131: MethodPickerItem getSelectedMethod() {
132: if ((selectedComponent == null)
133: || (methodList.getSelectedIndex() == -1))
134: return null;
135: return items[methodList.getSelectedIndex()];
136: }
137:
138: void setSelectedMethod(MethodDescriptor selectedMethod) {
139: if (selectedMethod == null) {
140: methodList.setSelectedIndex(-1);
141: } else {
142: methodList.setSelectedValue(FormUtils
143: .getMethodName(selectedMethod), true);
144: }
145: }
146:
147: // ----------------------------------------------------------------------------
148: // private methods
149:
150: private void updateMethodList() {
151: RADComponent sel = getSelectedComponent();
152: if (sel == null) {
153: methodList.setListData(new Object[0]);
154: methodList.revalidate();
155: methodList.repaint();
156: } else {
157: MethodDescriptor[] descs;
158:
159: descs = sel.getBeanInfo().getMethodDescriptors();
160:
161: Map<String, MethodPickerItem> filtered = new HashMap<String, MethodPickerItem>();
162: for (int i = 0; i < descs.length; i++) {
163: if (requiredType.isAssignableFrom(descs[i].getMethod()
164: .getReturnType())
165: && (descs[i].getMethod().getParameterTypes().length == 0)) // [FUTURE: - currently we allow only methods without params]
166: {
167: MethodPickerItem item = createItem(descs[i]);
168: filtered.put(item.getMethodName(), item);
169: }
170: }
171:
172: if (sel == sel.getFormModel().getTopRADComponent()) {
173: String[] names = FormEditor.getFormJavaSource(
174: sel.getFormModel())
175: .getMethodNames(requiredType);
176: for (int i = 0; i < names.length; i++) {
177: MethodPickerItem item = createItem(names[i]);
178: if (!filtered.containsKey(item.getMethodName())) {
179: filtered.put(item.getMethodName(), item);
180: }
181: }
182: }
183:
184: items = new MethodPickerItem[filtered.size()];
185: filtered.values().toArray(items);
186:
187: // sort the methods by name
188: Arrays.sort(items, new Comparator<MethodPickerItem>() {
189: public int compare(MethodPickerItem o1,
190: MethodPickerItem o2) {
191: return o1.getMethodName().compareTo(
192: o2.getMethodName());
193: }
194: });
195:
196: String[] listItems = new String[items.length];
197: for (int i = 0; i < listItems.length; i++)
198: listItems[i] = items[i].getMethodName();
199:
200: methodList.setListData(listItems);
201: methodList.revalidate();
202: methodList.repaint();
203: }
204: }
205:
206: private MethodPickerItem createItem(final MethodDescriptor desc) {
207: return new MethodPickerItem() {
208: private String name = FormUtils.getMethodName(desc);
209:
210: public String getMethodName() {
211: return name;
212: }
213:
214: public Class[] getParameterTypes() {
215: return desc.getMethod().getParameterTypes();
216: }
217:
218: public boolean providesMethodDescriptor() {
219: return true;
220: }
221:
222: public MethodDescriptor getMethodDescriptor() {
223: return desc;
224: }
225: };
226: }
227:
228: private MethodPickerItem createItem(final String methodName) {
229: return new MethodPickerItem() {
230: private String name = FormUtils.getMethodName(methodName,
231: NO_PARAMETERS);
232:
233: public String getMethodName() {
234: return name;
235: }
236:
237: public Class[] getParameterTypes() {
238: return NO_PARAMETERS;
239: }
240:
241: public boolean providesMethodDescriptor() {
242: return false;
243: }
244:
245: public MethodDescriptor getMethodDescriptor() {
246: return null;
247: }
248: };
249: }
250:
251: private void updateState() {
252: if ((getSelectedComponent() == null)
253: || (getSelectedMethod() == null)) {
254: setPickerValid(false);
255: } else {
256: setPickerValid(getSelectedMethod().getParameterTypes().length == 0);
257: }
258: }
259:
260: /** This method is called from within the constructor to
261: * initialize the form.
262: * WARNING: Do NOT modify this code. The content of this method is
263: * always regenerated by the FormEditor.
264: */
265: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
266: private void initComponents() {
267: java.awt.GridBagConstraints gridBagConstraints;
268:
269: componentLabel = new javax.swing.JLabel();
270: componentsCombo = new javax.swing.JComboBox();
271: listLabel = new javax.swing.JLabel();
272: propertiesScrollPane = new javax.swing.JScrollPane();
273: methodList = new javax.swing.JList();
274:
275: setLayout(new java.awt.GridBagLayout());
276:
277: setBorder(javax.swing.BorderFactory.createEmptyBorder(12, 12,
278: 0, 11));
279: componentLabel.setLabelFor(componentsCombo);
280: componentLabel.setText("Component:");
281: gridBagConstraints = new java.awt.GridBagConstraints();
282: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
283: gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 6);
284: add(componentLabel, gridBagConstraints);
285:
286: componentsCombo
287: .addItemListener(new java.awt.event.ItemListener() {
288: public void itemStateChanged(
289: java.awt.event.ItemEvent evt) {
290: componentsComboItemStateChanged(evt);
291: }
292: });
293:
294: gridBagConstraints = new java.awt.GridBagConstraints();
295: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
296: gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
297: add(componentsCombo, gridBagConstraints);
298:
299: listLabel.setLabelFor(methodList);
300: listLabel.setText("Methods");
301: gridBagConstraints = new java.awt.GridBagConstraints();
302: gridBagConstraints.gridx = 0;
303: gridBagConstraints.gridy = 1;
304: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
305: gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
306: add(listLabel, gridBagConstraints);
307:
308: methodList
309: .setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
310: methodList
311: .addListSelectionListener(new javax.swing.event.ListSelectionListener() {
312: public void valueChanged(
313: javax.swing.event.ListSelectionEvent evt) {
314: methodListValueChanged(evt);
315: }
316: });
317:
318: propertiesScrollPane.setViewportView(methodList);
319:
320: gridBagConstraints = new java.awt.GridBagConstraints();
321: gridBagConstraints.gridx = 0;
322: gridBagConstraints.gridy = 2;
323: gridBagConstraints.gridwidth = 2;
324: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
325: gridBagConstraints.weightx = 1.0;
326: gridBagConstraints.weighty = 1.0;
327: add(propertiesScrollPane, gridBagConstraints);
328:
329: }// </editor-fold>//GEN-END:initComponents
330:
331: private void methodListValueChanged(
332: javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_methodListValueChanged
333: updateState();
334: }//GEN-LAST:event_methodListValueChanged
335:
336: private void componentsComboItemStateChanged(
337: java.awt.event.ItemEvent evt) {//GEN-FIRST:event_componentsComboItemStateChanged
338: if (componentsCombo.getSelectedIndex() == -1)
339: selectedComponent = null;
340: else
341: selectedComponent = components[componentsCombo
342: .getSelectedIndex()];
343: updateMethodList();
344: }//GEN-LAST:event_componentsComboItemStateChanged
345:
346: // Variables declaration - do not modify//GEN-BEGIN:variables
347: private javax.swing.JLabel componentLabel;
348: private javax.swing.JComboBox componentsCombo;
349: private javax.swing.JLabel listLabel;
350: private javax.swing.JList methodList;
351: private javax.swing.JScrollPane propertiesScrollPane;
352: // End of variables declaration//GEN-END:variables
353:
354: private boolean pickerValid = false;
355:
356: interface MethodPickerItem {
357: public String getMethodName();
358:
359: public Class[] getParameterTypes();
360:
361: public MethodDescriptor getMethodDescriptor();
362: }
363:
364: private RADComponent[] components;
365: private Class<?> requiredType;
366: private MethodPickerItem[] items;
367: private RADComponent selectedComponent;
368: private static Class[] NO_PARAMETERS = new Class[0];
369:
370: }
|