KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > search > SearchTypePanel


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

19
20
21 package org.netbeans.modules.search;
22
23
24 import java.awt.BorderLayout JavaDoc;
25 import java.awt.Component JavaDoc;
26 import java.awt.Dialog JavaDoc;
27 import java.awt.GridBagConstraints JavaDoc;
28 import java.awt.GridBagLayout JavaDoc;
29 import java.awt.Insets JavaDoc;
30 import java.awt.event.ActionEvent JavaDoc;
31 import java.awt.event.ActionListener JavaDoc;
32 import java.beans.BeanInfo JavaDoc;
33 import java.beans.Customizer JavaDoc;
34 import java.beans.IntrospectionException JavaDoc;
35 import java.beans.PropertyChangeEvent JavaDoc;
36 import java.beans.PropertyChangeListener JavaDoc;
37 import java.io.ByteArrayInputStream JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.ObjectInputStream JavaDoc;
40 import java.util.Collection JavaDoc;
41 import java.util.Collections JavaDoc;
42 import java.util.ResourceBundle JavaDoc;
43 import javax.swing.BorderFactory JavaDoc;
44 import javax.swing.JComboBox JavaDoc;
45 import javax.swing.JLabel JavaDoc;
46 import javax.swing.JPanel JavaDoc;
47 import javax.swing.JTextField JavaDoc;
48 import org.netbeans.modules.search.types.FullTextCustomizer;
49
50 import org.openide.DialogDescriptor;
51 import org.openide.DialogDisplayer;
52 import org.openide.ErrorManager;
53 import org.openide.awt.Mnemonics;
54 import org.openide.util.HelpCtx;
55 import org.openide.util.NbBundle;
56 import org.openide.util.Utilities;
57 import org.openidex.search.SearchType;
58
59
60 /**
61  * Panel which shows to user one search type allowing it to customize.
62  *
63  * @author Peter Zavadsky
64  * @author Marian Petras
65  * @see SearchPanel
66  */

67 public final class SearchTypePanel extends JPanel JavaDoc
68                                    implements PropertyChangeListener JavaDoc,
69                                               ActionListener JavaDoc,
70                                               DialogLifetime {
71
72     /** Name of customized property. */
73     public static final String JavaDoc PROP_CUSTOMIZED = "customized"; // NOI18N
74
/** Modificator suffix. */
75     private static final String JavaDoc MODIFICATOR_SUFFIX = " *"; // NOI18N
76
/** Customized property. Indicates this criterion model
77      * was customized by user. */

78     private boolean customized;
79     /** Search type this model is customized by. */
80     private SearchType searchType;
81     /**
82      * has this panel's customizer been initialized with
83      * <code>setObject(...)</code>?
84      *
85      * @see #initializeWithObject()
86      */

87     private boolean initialized = false;
88     /** Customizer for search type. */
89     final Customizer JavaDoc customizer;
90     /** Customizer component. */
91     final Component JavaDoc customizerComponent;
92     /**
93      * saved criteria for this panel
94      *
95      * @see #addSavedCriteria
96      */

97     private SearchCriterion[] savedCriteria;
98
99     private String JavaDoc lastSavedName;
100     
101     
102     /** Creates new form <code>SearchTypePanel</code>. */
103     public SearchTypePanel(SearchType searchType,
104                            final boolean initFromHistory) {
105         initComponents();
106         initAccessibility();
107                 
108         this.searchType = searchType;
109
110         customizer = createCustomizer(this.searchType, initFromHistory);
111         if (customizer != null) {
112             customizerComponent = (Component JavaDoc) customizer;
113         } else {
114             customizerComponent = null;
115             
116             initialized = true; //cannot initialize <null> customizer
117

118             // PENDING use property sheet as it will implement Customizer
119
// allow hiding tabs, ....
120
System.err.println("No customizer for " //NOI18N
121
+ this.searchType.getName()
122                                + ", skipping..."); //NOI18N
123
}
124
125         customizer.setObject(this.searchType);
126         if (initFromHistory && (customizer instanceof FullTextCustomizer)) {
127             ((FullTextCustomizer) customizer).initFromHistory();
128         }
129         this.searchType.addPropertyChangeListener(this);
130         
131         ResourceBundle JavaDoc bundle = NbBundle.getBundle(SearchTypePanel.class);
132         Mnemonics.setLocalizedText(
133                 applyCheckBox,
134                 bundle.getString("TEXT_BUTTON_APPLY")); //NOI18N
135

136         Mnemonics.setLocalizedText(
137                 saveButton,
138                 bundle.getString("TEXT_BUTTON_SAVE_AS")); //NOI18N
139

140         saveButton.setEnabled(false);
141         
142         Mnemonics.setLocalizedText(
143                 restoreButton,
144                 bundle.getString("TEXT_BUTTON_RESTORE")); //NOI18N
145

146         /* The button is disabled until saved criteria are available. */
147         restoreButton.setEnabled(false);
148
149         customizerPanel.add(customizerComponent, BorderLayout.CENTER);
150
151         setCustomized(this.searchType.isValid());
152         
153         // obtain tab label string & icon
154
setName(createName());
155     }
156
157     private void initAccessibility() {
158         ResourceBundle JavaDoc bundle = NbBundle.getBundle(SearchTypePanel.class);
159         this.getAccessibleContext().setAccessibleDescription(
160                 bundle.getString("ACS_DIALOG_DESC")); //NOI18N
161
restoreButton.getAccessibleContext().setAccessibleDescription(
162                 bundle.getString("ACS_TEXT_BUTTON_RESTORE")); //NOI18N
163
saveButton.getAccessibleContext().setAccessibleDescription(
164                 bundle.getString("ACS_TEXT_BUTTON_SAVE_AS")); //NOI18N
165
applyCheckBox.getAccessibleContext().setAccessibleDescription(
166                 bundle.getString("ACS_TEXT_BUTTON_APPLY")); //NOI18N
167
}
168     
169     /** This method is called from within the constructor to
170      * initialize the form.
171      * WARNING: Do NOT modify this code. The content of this method is
172      * always regenerated by the Form Editor.
173      */

174     private void initComponents() {//GEN-BEGIN:initComponents
175
java.awt.GridBagConstraints JavaDoc gridBagConstraints;
176
177         customizerPanel = new javax.swing.JPanel JavaDoc();
178
179         setLayout(new java.awt.GridBagLayout JavaDoc());
180
181         customizerPanel.setLayout(new java.awt.BorderLayout JavaDoc());
182
183         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
184         gridBagConstraints.gridwidth = 2;
185         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
186         gridBagConstraints.weightx = 1.0;
187         gridBagConstraints.weighty = 1.0;
188         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 0, 11);
189         add(customizerPanel, gridBagConstraints);
190
191         applyCheckBox.addActionListener(this);
192         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
193         gridBagConstraints.gridx = 0;
194         gridBagConstraints.gridy = 1;
195         gridBagConstraints.gridwidth = 2;
196         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
197         gridBagConstraints.insets = new java.awt.Insets JavaDoc(17, 11, 0, 11);
198         add(applyCheckBox, gridBagConstraints);
199
200         saveButton.addActionListener(this);
201         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
202         gridBagConstraints.gridx = 0;
203         gridBagConstraints.gridy = 2;
204         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
205         gridBagConstraints.weightx = 1.0;
206         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 11, 0);
207         add(saveButton, gridBagConstraints);
208
209         restoreButton.addActionListener(this);
210         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
211         gridBagConstraints.gridx = 1;
212         gridBagConstraints.gridy = 2;
213         gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
214         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 11, 11);
215         add(restoreButton, gridBagConstraints);
216
217     }//GEN-END:initComponents
218

219
220     // Variables declaration - do not modify//GEN-BEGIN:variables
221
private final javax.swing.JCheckBox JavaDoc applyCheckBox = new javax.swing.JCheckBox JavaDoc();
222     private javax.swing.JPanel JavaDoc customizerPanel;
223     private final javax.swing.JButton JavaDoc restoreButton = new javax.swing.JButton JavaDoc();
224     private final javax.swing.JButton JavaDoc saveButton = new javax.swing.JButton JavaDoc();
225     // End of variables declaration//GEN-END:variables
226

227     /**
228      * Called when the <em>Save Settings as...</em> or <em>Restore Saved...</em>
229      * button is pressed or when the <em>Use This Criterion for Search</em>
230      * checkbox is (de)selected.
231      */

232     public void actionPerformed(ActionEvent JavaDoc e) {
233         final Object JavaDoc source = e.getSource();
234         
235         if (source == applyCheckBox) {
236             
237             /* PENDING: Some better solution of valid / customized needed. */
238             boolean selected = applyCheckBox.isSelected();
239             setCustomized(selected);
240             searchType.setValid(selected);
241             
242         } else if (source == saveButton) {
243             saveCriterion();
244             
245         } else if (source == restoreButton) {
246             restoreCriterion();
247             
248         } else {
249             
250             /* this should never happen */
251             assert false;
252         }
253     }
254     
255     // PENDING Better solution for these properties are needed.
256
/** Listens on search type PROP_VALID property change and sets
257      * customized property accordingly. */

258     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
259         if (evt.getSource() == searchType) {
260
261             // if Type fires valid property change listens for
262
// its invalidity -> mark itself as unmodified
263
if (SearchType.PROP_VALID.equals(evt.getPropertyName()) ) {
264                 
265                 if (evt.getNewValue().equals(Boolean.FALSE)) {
266                     setCustomized (false);
267                     return;
268                 } else {
269                     setCustomized (true);
270                 }
271             }
272         }
273     }
274         
275     public void onOk() {
276         if (customizer instanceof DialogLifetime) {
277             ((DialogLifetime)customizer).onOk();
278         }
279     }
280     
281     public void onCancel() {
282         if (customizer instanceof DialogLifetime) {
283             ((DialogLifetime)customizer).onCancel();
284         }
285     }
286     
287     /**
288      * Creates name used as tab name,
289      * @return name. */

290     private String JavaDoc createName() {
291         String JavaDoc name = searchType.getName();
292
293         if(customized) {
294             return name + MODIFICATOR_SUFFIX;
295         } else {
296             return name;
297         }
298     }
299
300     /**
301      * Creates a customizer for a given search type.
302      *
303      * @param searchTypeClass class of the search type
304      * @return customizer object for the search type,
305      * or <code>null</code> if the customizer could not be created
306      */

307     private static Customizer JavaDoc createCustomizer(final SearchType searchType,
308                                                final boolean initFromHistory) {
309         final Class JavaDoc searchTypeClass = searchType.getClass();
310         Class JavaDoc clazz = null;
311         
312         if (isDefaultSearchType(searchTypeClass)) {
313             String JavaDoc typeClassName = searchType.getClass().getName();
314             assert typeClassName.endsWith("Type"); //NOI18N
315

316             int typeNameLen = typeClassName.length();
317             String JavaDoc customizerClassName
318                     = new StringBuffer JavaDoc(typeNameLen + 6)
319                       .append(typeClassName.substring(0, typeNameLen - 4))
320                       .append("Customizer") //NOI18N
321
.toString();
322             try {
323                 clazz = Class.forName(customizerClassName);
324             } catch (Exception JavaDoc ex) {
325                 assert false;
326                 ErrorManager.getDefault().notify(ErrorManager.ERROR, ex);
327             }
328         }
329         
330         if (clazz == null) {
331             final BeanInfo JavaDoc beanInfo;
332             try {
333                 beanInfo = Utilities.getBeanInfo(searchTypeClass);
334             } catch (IntrospectionException JavaDoc ie) {
335                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ie);
336                 return null;
337             }
338
339             clazz = beanInfo.getBeanDescriptor ().getCustomizerClass ();
340         }
341         if (clazz == null) return null;
342
343         Object JavaDoc o;
344         try {
345             o = clazz.newInstance ();
346         } catch (InstantiationException JavaDoc e) {
347             return null;
348         } catch (IllegalAccessException JavaDoc e) {
349             return null;
350         }
351
352         if (!(o instanceof Component JavaDoc) ||
353                 !(o instanceof Customizer JavaDoc)) return null;
354         return (Customizer JavaDoc) o;
355     }
356     
357     /**
358      * Checks whether the given <code>SearchType</code> class represents
359      * a default search type.
360      * (Default search type is such a search type that is defined
361      * in the Utilities module.)
362      *
363      * @param searchTypeClass <code>SearchType</code> class to check
364      * @return <code>true</code> if the given <code>Class</code> object
365      * represents a default search type; <code>false</code> if not
366      */

367     private static boolean isDefaultSearchType(Class JavaDoc searchTypeClass) {
368         assert SearchType.class.isAssignableFrom(searchTypeClass);
369
370         String JavaDoc mandatoryPackage = "org.netbeans.modules.search.types"; //NOI18N
371

372         String JavaDoc className = searchTypeClass.getName();
373         return className.startsWith(mandatoryPackage)
374                && (className.lastIndexOf('.') == mandatoryPackage.length());
375     }
376     
377     /**
378      * Sets customized property.
379      *
380      * @param cust value to which customized property to set.
381      */

382     private void setCustomized(boolean cust) {
383         customized = cust;
384
385         saveButton.setEnabled(customized);
386         applyCheckBox.setSelected(customized);
387
388         setName(createName());
389
390         firePropertyChange(PROP_CUSTOMIZED, !cust, cust);
391     }
392
393     /** Tests whether this panel is customized. */
394     public boolean isCustomized() {
395         return customized;
396     }
397
398     /** Saves the criterion. */
399     private void saveCriterion() {
400         JPanel JavaDoc pane = new JPanel JavaDoc();
401         pane.setLayout(new BorderLayout JavaDoc(12,0));
402         
403         ResourceBundle JavaDoc bundle = NbBundle.getBundle(SearchTypePanel.class);
404         JLabel JavaDoc nameLab = new JLabel JavaDoc();
405         Mnemonics.setLocalizedText(
406                 nameLab,
407                 bundle.getString("TEXT_LABEL_NAME")); //NOI18N
408

409         pane.add(nameLab, BorderLayout.WEST);
410         pane.getAccessibleContext().setAccessibleDescription(
411                 bundle.getString("ACS_SaveAsPanel")); //NOI18N
412

413         JTextField JavaDoc textField;
414         if (lastSavedName != null) {
415             textField = new JTextField JavaDoc(lastSavedName, 20);
416         } else {
417             textField = new JTextField JavaDoc(20);
418         }
419         textField.getAccessibleContext().setAccessibleDescription(
420                 bundle.getString("ACS_TEXT_LABEL_SELECT")); //NOI18N
421

422         nameLab.setLabelFor(textField);
423         pane.add(textField, BorderLayout.CENTER);
424         pane.setBorder(BorderFactory.createEmptyBorder(12,12,0,11));
425         
426         DialogDescriptor desc = new DialogDescriptor(
427                 pane,
428                 bundle.getString("TEXT_LABEL_SAVE_CRITERION")); //NOI18N
429
Dialog JavaDoc dialog = DialogDisplayer.getDefault().createDialog(desc);
430         
431         while (true) {
432             dialog.setVisible(true);
433             if (desc.getValue().equals(DialogDescriptor.OK_OPTION)) {
434                 String JavaDoc name = textField.getText();
435                 if (name.length() > 0) {
436                     saveCriterion(name);
437                     lastSavedName = name;
438                     break;
439                 }
440             } else {
441                 return; // cancel
442
}
443         }
444     }
445     
446     /** */
447     private void saveCriterion(String JavaDoc name) {
448         SearchType copy = (SearchType) searchType.clone();
449         copy.setName(name);
450         
451         SearchCriterion toSave;
452         try {
453             toSave = new SearchCriterion(copy);
454         } catch (IOException JavaDoc ex) {
455             ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, ex);
456             return;
457         }
458         
459         /* file the new criterion into the list of saved criteria: */
460         String JavaDoc className = toSave.searchTypeClassName;
461         boolean found = false;
462         if (savedCriteria != null) {
463             for (int i = 0; i < savedCriteria.length; i++) {
464                 if (savedCriteria[i].name.equals(name)
465                         && savedCriteria[i].searchTypeClassName.equals(className)) {
466                     found = true;
467                     SearchProjectSettings.getInstance()
468                             .replaceSearchCriterion(name, className, toSave);
469                     savedCriteria[i] = toSave;
470                     break;
471                 }
472             }
473         }
474         if (!found) {
475             SearchProjectSettings.getInstance().addSearchCriterion(toSave);
476             addSavedCriteria(Collections.singleton(toSave));
477         }
478     }
479     
480     /**
481      * Displays a dialog for choosing from a list of (saved) criteria
482      * and loads the selected criterion (if the choice is confirmed).
483      */

484     private void restoreCriterion() {
485         JPanel JavaDoc pane = new JPanel JavaDoc();
486         pane.setLayout(new GridBagLayout JavaDoc());
487         
488         ResourceBundle JavaDoc bundle = NbBundle.getBundle(SearchTypePanel.class);
489         pane.getAccessibleContext().setAccessibleDescription(
490                 bundle.getString("ACS_RestorePanel")); //NOI18N
491

492         JLabel JavaDoc resLabel = new JLabel JavaDoc();
493         Mnemonics.setLocalizedText(
494                 resLabel,
495                 bundle.getString("TEXT_LABEL_SELECT")); //NOI18N
496

497         JComboBox JavaDoc combo = new JComboBox JavaDoc(savedCriteria);
498         combo.getAccessibleContext().setAccessibleDescription(
499                 bundle.getString("ACSD_SELECT_CRITERION")); //NOI18N
500
resLabel.setLabelFor(combo);
501         
502         GridBagConstraints JavaDoc gbc = new GridBagConstraints JavaDoc();
503         gbc.insets = new Insets JavaDoc(0, 0, 0, 12);
504         pane.add(resLabel, gbc);
505         
506         gbc.fill = GridBagConstraints.HORIZONTAL;
507         gbc.weightx = 1.0d;
508         gbc.insets = new Insets JavaDoc(0, 0, 0, 0);
509         pane.add(combo, gbc);
510         
511         pane.setBorder(BorderFactory.createEmptyBorder(12,12,0,11));
512         
513         DialogDescriptor desc = new DialogDescriptor(
514                 pane,
515                 bundle.getString("TEXT_LABEL_RESTORE_CRITERION")); //NOI18N
516
DialogDisplayer.getDefault().createDialog(desc).setVisible(true);
517         
518         if (desc.getValue().equals(DialogDescriptor.OK_OPTION)) {
519             SearchCriterion c = (SearchCriterion) combo.getSelectedItem();
520             restoreCriterion(c);
521         }
522     }
523     
524     /** */
525     private void restoreCriterion(SearchCriterion c) {
526         SearchType searchType;
527         ObjectInputStream JavaDoc ois = null;
528         try {
529             ois = new SearchTypeInputStream(
530                     new ByteArrayInputStream JavaDoc(c.criterionData));
531             searchType = (SearchType) ois.readObject();
532         } catch (Exception JavaDoc ex) {
533             String JavaDoc msg = NbBundle.getMessage(
534                     SearchTypePanel.class,
535                     "TEXT_MSG_Error_while_loading_criterion"); //NOI18N
536
ErrorManager.getDefault().notify(
537                     ErrorManager.EXCEPTION,
538                     ErrorManager.getDefault().annotate(ex, msg));
539             return;
540         } finally {
541             if (ois != null) {
542                 try {
543                     ois.close();
544                 } catch (IOException JavaDoc ex2) {
545                     /* give up */
546                 }
547             }
548         }
549         restoreSearchType(searchType);
550     }
551
552     /** Restores the search type. */
553     private void restoreSearchType(SearchType searchType) {
554         this.searchType.removePropertyChangeListener(this);
555
556         this.searchType = (SearchType) searchType.clone();
557         initialized = false;
558         initializeWithObject();
559         this.searchType.addPropertyChangeListener(this);
560
561         setCustomized(true);
562     }
563     
564     /**
565      * Initializes this panel's customizer using <code>setObject(...)</code>,
566      * if it has not been initialized yet.
567      */

568     final void initializeWithObject() {
569         if (!initialized) {
570             customizer.setObject(this.searchType);
571             initialized = true;
572         }
573     }
574
575     /** Return currently hold bean. */
576     public SearchType getSearchType() {
577         return searchType;
578     }
579     
580     /**
581      * Class equality
582      *
583      * @return this.bean.getClass().equals(bean.getClass());
584      */

585     public boolean equals(Object JavaDoc obj) {
586         try {
587             return searchType.getClass().equals(
588                     ((SearchTypePanel) obj).getSearchType().getClass());
589         } catch (ClassCastException JavaDoc ex) {
590             return false;
591         }
592     }
593
594     /** Gets help context. */
595     public HelpCtx getHelpCtx() {
596         return searchType.getHelpCtx();
597     }
598     
599     /**
600      * Adds the specified set of search criteria to the list of saved criteria
601      * available in this panel.
602      *
603      * @param criteria search criteria to add
604      */

605     void addSavedCriteria(Collection JavaDoc criteria) {
606         if (criteria.isEmpty()) {
607             return;
608         }
609         
610         SearchCriterion[] newCriteria = new SearchCriterion[criteria.size()];
611         criteria.toArray(newCriteria);
612         if (savedCriteria == null) {
613             savedCriteria = newCriteria;
614             restoreButton.setEnabled(true);
615         } else {
616             
617             /* append the specified criteria to the current set of criteria: */
618             SearchCriterion[] oldCriteria = savedCriteria;
619             savedCriteria = new SearchCriterion[oldCriteria.length
620                                                 + newCriteria.length];
621             System.arraycopy(oldCriteria, 0,
622                              savedCriteria, 0,
623                              oldCriteria.length);
624             System.arraycopy(newCriteria, 0,
625                              savedCriteria, oldCriteria.length,
626                              newCriteria.length);
627         }
628     }
629     
630 }
631
Popular Tags