KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > search > types > TextCustomizer


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.types;
22
23
24 import java.awt.BorderLayout JavaDoc;
25 import java.awt.Color JavaDoc;
26 import java.awt.Component JavaDoc;
27 import java.awt.GridLayout JavaDoc;
28 import java.awt.event.ItemEvent JavaDoc;
29 import java.awt.event.ItemListener JavaDoc;
30 import java.awt.event.KeyEvent JavaDoc;
31 import java.awt.event.KeyListener JavaDoc;
32 import java.beans.Customizer JavaDoc;
33 import java.beans.PropertyChangeListener JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.ResourceBundle JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Set JavaDoc;
39 import java.util.Vector JavaDoc;
40 import javax.swing.BorderFactory JavaDoc;
41 import javax.swing.Box JavaDoc;
42 import javax.swing.BoxLayout JavaDoc;
43 import javax.swing.DefaultComboBoxModel JavaDoc;
44 import javax.swing.JButton JavaDoc;
45 import javax.swing.JCheckBox JavaDoc;
46 import javax.swing.JComboBox JavaDoc;
47 import javax.swing.JComponent JavaDoc;
48 import javax.swing.JPanel JavaDoc;
49 import javax.swing.JRootPane JavaDoc;
50 import javax.swing.JTextField JavaDoc;
51 import javax.swing.SwingUtilities JavaDoc;
52 import javax.swing.border.CompoundBorder JavaDoc;
53 import javax.swing.border.TitledBorder JavaDoc;
54 import javax.swing.UIManager JavaDoc;
55 import javax.swing.event.DocumentEvent JavaDoc;
56 import javax.swing.event.DocumentListener JavaDoc;
57 import org.netbeans.modules.search.DialogLifetime;
58 import org.netbeans.modules.search.FindDialogMemory;
59
60 import org.openide.awt.Mnemonics;
61 import org.openide.util.NbBundle;
62 import org.openidex.search.SearchPattern;
63
64
65 /**
66  * Customizer of TextType beans.
67  *
68  * @author Petr Kuzel
69  * @author Marian Petras
70  */

71 public abstract class TextCustomizer extends JPanel JavaDoc
72         implements Customizer JavaDoc, DialogLifetime, ItemListener JavaDoc,
73                    KeyListener JavaDoc
74 {
75
76     private final JComboBox JavaDoc substringComboBox = new JComboBox JavaDoc();
77     private final JCheckBox JavaDoc caseSensitiveCheckBox = new JCheckBox JavaDoc();
78     private final JCheckBox JavaDoc regexpCheckBox = new JCheckBox JavaDoc();
79     private final JCheckBox JavaDoc wholeWordsCheckBox = new JCheckBox JavaDoc();
80     private final JPanel JavaDoc contentPanel = new JPanel JavaDoc();
81     /**
82      * index to the {@link #contentPanel} where the replace panel should be
83      * inserted, if any
84      */

85     private int replacePanelIndex = -1;
86     /** */
87     private boolean replacePanelPresent = false;
88     
89     protected TextType peer;
90
91     /** Creates new form FullTextCustomizer */
92     public TextCustomizer() {
93         initComponents ();
94         initAccessibility ();
95         initTextFieldListeners();
96         TitledBorder JavaDoc tb = new TitledBorder JavaDoc(getBorderLabel());
97         tb.setBorder(new CompoundBorder JavaDoc());
98         setBorder (tb);
99
100         initHistory();
101     }
102
103    
104     /** Allow derived customizers.
105     */

106     protected String JavaDoc getBorderLabel() {
107         return null;
108     }
109
110     private void initAccessibility(){
111         ResourceBundle JavaDoc bundle = NbBundle.getBundle(TextCustomizer.class);
112         substringComboBox.getAccessibleContext().setAccessibleName(bundle.getString("ACSN_PROP_SUBSTRING"));
113         substringComboBox.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_PROP_SUBSTRING"));
114         caseSensitiveCheckBox.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_TEXT_LABEL_CASE_SENSITIVE"));
115         wholeWordsCheckBox.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_TEXT_LABEL_WHOLE_WORDS"));
116         regexpCheckBox.getAccessibleContext().setAccessibleDescription(bundle.getString("ACS_TEXT_LABEL_RE"));
117     }
118     
119     /**
120      */

121     private void initTextFieldListeners() {
122         class TextChangeListener implements DocumentListener JavaDoc {
123             private JTextField JavaDoc textField;
124             TextChangeListener(JTextField JavaDoc textField) {
125                 this.textField = textField;
126             }
127             public void changedUpdate(DocumentEvent JavaDoc e) {
128                 documentChanged();
129             }
130             public void insertUpdate(DocumentEvent JavaDoc e) {
131                 documentChanged();
132             }
133             public void removeUpdate(DocumentEvent JavaDoc e) {
134                 documentChanged();
135             }
136             private void documentChanged() {
137                 stringChanged();
138             }
139         }
140         ((JTextField JavaDoc)substringComboBox.getEditor().getEditorComponent()).getDocument().addDocumentListener(
141                 new TextChangeListener((JTextField JavaDoc)substringComboBox.getEditor().getEditorComponent()));
142     }
143       
144     /**
145      * Initializes the search pattern combo-box's popup with the last
146      * entered patterns. The combo-box's text-field remains empty.
147      */

148     private void initHistory() {
149         final List JavaDoc/*<SearchPattern>*/ patterns = getSearchPatterns();
150         if (!patterns.isEmpty()) {
151             final Set JavaDoc inserted = new HashSet JavaDoc(patterns.size());
152             final Vector JavaDoc itemsList = new Vector JavaDoc(patterns.size());
153             
154             final Iterator JavaDoc it = patterns.iterator();
155             while (it.hasNext()) {
156                 String JavaDoc str = ((SearchPattern)it.next()).getSearchExpression();
157                 if (inserted.add(str)) {
158                     itemsList.add(str);
159                 }
160             }
161             substringComboBox.setModel(new DefaultComboBoxModel JavaDoc(itemsList));
162             substringComboBox.setSelectedIndex(-1);
163         }
164     }
165     
166     /**
167      * Initializes the text-field with the last value from the history.
168      */

169     public void initFromHistory() {
170         Object JavaDoc topmostItem = getSearchPatterns().get(0);
171         if (topmostItem != null) {
172             putCurrentSearchPattern((SearchPattern) topmostItem);
173         }
174     }
175     
176     /**
177      */

178     private void initComponents() {
179         substringComboBox.setEditable(true);
180         substringComboBox.addItemListener(this);
181         activateEnterKeyBypass(substringComboBox);
182         
183         Mnemonics.setLocalizedText(
184                 wholeWordsCheckBox,
185                 NbBundle.getMessage(TextCustomizer.class,
186                                     "TEXT_LABEL_WHOLE_WORDS")); //NOI18N
187
wholeWordsCheckBox.setBorder(null);
188         wholeWordsCheckBox.addItemListener(this);
189
190         Mnemonics.setLocalizedText(
191                 caseSensitiveCheckBox,
192                 NbBundle.getMessage(TextCustomizer.class,
193                                     "TEXT_LABEL_CASE_SENSITIVE")); //NOI18N
194
caseSensitiveCheckBox.setBorder(null);
195         caseSensitiveCheckBox.addItemListener(this);
196
197         Mnemonics.setLocalizedText(
198                 regexpCheckBox,
199                 NbBundle.getMessage(TextCustomizer.class,
200                                     "TEXT_LABEL_RE")); //NOI18N
201
regexpCheckBox.setBorder(null);
202         regexpCheckBox.addItemListener(this);
203         
204         JPanel JavaDoc checkBoxesPanel = new JPanel JavaDoc(new GridLayout JavaDoc(0, 1, 0, 2));
205         checkBoxesPanel.add(wholeWordsCheckBox);
206         checkBoxesPanel.add(caseSensitiveCheckBox);
207         checkBoxesPanel.add(regexpCheckBox);
208         checkBoxesPanel.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0));
209         
210         contentPanel.setLayout(new BoxLayout JavaDoc(contentPanel, BoxLayout.Y_AXIS));
211         contentPanel.add(substringComboBox);
212         contentPanel.add(Box.createVerticalStrut(6));
213         replacePanelIndex = contentPanel.getComponentCount();
214         contentPanel.add(checkBoxesPanel);
215         substringComboBox.setAlignmentX(0f);
216         checkBoxesPanel.setAlignmentX(0f);
217         
218         setLayout(new BorderLayout JavaDoc());
219         add(contentPanel, BorderLayout.NORTH);
220         
221         setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
222     }
223     
224     /**
225      */

226     protected void addReplacePanel(Box JavaDoc replaceBox) {
227         if (replacePanelPresent) {
228             throw new IllegalStateException JavaDoc();
229         }
230         
231         replacePanelPresent = true;
232         
233         assert replacePanelIndex >= 0;
234         int insertIndex = replacePanelIndex;
235         for (Component JavaDoc c : replaceBox.getComponents()) {
236             contentPanel.add(c, insertIndex++);
237             if (c instanceof JComponent JavaDoc) {
238                 ((JComponent JavaDoc) c).setAlignmentX(0f);
239             }
240         }
241         contentPanel.add(Box.createVerticalStrut(6), insertIndex);
242     }
243     
244     /**
245      * Creates a bypass around the default JComboBox's and JTextField's
246      * mechanism for handling key events.
247      * The bypass ensures that the Enter key always activates
248      * the default button (if enabled). It was made as a quick fix of bug #54279
249      * ("Need to press Enter twice to start searching").
250      */

251     protected void activateEnterKeyBypass(JComboBox JavaDoc comboBox) {
252         Component JavaDoc editor = comboBox.getEditor().getEditorComponent();
253         if (!(editor instanceof JTextField JavaDoc)) {
254             assert false;
255             return;
256         }
257         ((JTextField JavaDoc) editor).addKeyListener(this);
258     }
259     
260     /**
261      * If the pressed key was Enter, activates the default button (if enabled).
262      * It also consumes the event so that the default
263      * <code>JTextField</code>'s handling mechanism is bypassed.
264      */

265     public void keyPressed(KeyEvent JavaDoc e) {
266         if ((e.getKeyCode() == KeyEvent.VK_ENTER) && (e.getModifiersEx() == 0)){
267             
268             JRootPane JavaDoc rootPane = SwingUtilities.getRootPane(this);
269             if (rootPane != null) {
270                 JButton JavaDoc button = rootPane.getDefaultButton();
271                 if ((button != null) && button.isEnabled()) {
272                     e.consume();
273                     button.doClick();
274                 }
275             }
276         }
277     }
278     
279     /**
280      */

281     public void keyReleased(KeyEvent JavaDoc e) {
282         //ignore
283
}
284     
285     /**
286      */

287     public void keyTyped(KeyEvent JavaDoc e) {
288         //ignore
289
}
290     
291     /**
292      */

293     protected String JavaDoc getComboText(JComboBox JavaDoc comboBox) {
294         return ((JTextField JavaDoc) comboBox.getEditor().getEditorComponent()).getText();
295     }
296     
297     /**
298      * Called when the Regular Expression check-box is selected or deselected.
299      */

300     private void regexpChkBoxChanged() {
301         enableUI();
302         
303         if (peer == null) {
304             return;
305         }
306         
307         final String JavaDoc text = getComboText(substringComboBox);
308         if ((text == null) || (text.length() == 0)) {
309             
310             /*
311              * The checkbox was (de)selected at the moment the combo-box
312              * editor was empty - so this cannot change the validity
313              * and there is no need to update the peer.
314              */

315             return;
316         }
317         
318         if (!regexpCheckBox.isSelected()) {
319             peer.setMatchString(text);
320             substringComboBox.getEditor().getEditorComponent().setForeground(getForegroundColor());
321         } else {
322             try {
323                 peer.setRe(text);
324                 substringComboBox.getEditor().getEditorComponent().setForeground(getForegroundColor());
325             } catch (IllegalArgumentException JavaDoc ex) {
326                 substringComboBox.getEditor().getEditorComponent().setForeground(getErrorForegroundColor());
327             }
328         }
329     }
330     
331     /**
332      * Called whenever contents of the textfield changes.
333      */

334     private void stringChanged() {
335         if (peer == null) {
336             return;
337         }
338         
339         final String JavaDoc text = getComboText(substringComboBox);
340         if (!regexpCheckBox.isSelected()) {
341             peer.setMatchString(text);
342             substringComboBox.getEditor().getEditorComponent().setForeground(getForegroundColor());
343         } else {
344             try {
345                 peer.setRe(text);
346                 substringComboBox.getEditor().getEditorComponent().setForeground(getForegroundColor());
347             } catch (IllegalArgumentException JavaDoc ex) {
348                 substringComboBox.getEditor().getEditorComponent().setForeground(getErrorForegroundColor());
349             }
350         }
351     }
352     
353     /** Initialize customizer with proper values.
354     */

355     public void setObject(final Object JavaDoc obj) {
356
357         peer = (TextType) obj;
358
359         // set default coloring
360
substringComboBox.setForeground(getForegroundColor());
361
362         String JavaDoc text;
363         Boolean JavaDoc isRegexp = null;
364         
365         if ((text = peer.getRe()).length() != 0) {
366             isRegexp = Boolean.TRUE;
367         } else if ((text = peer.getMatchString()).length() != 0) {
368             isRegexp = Boolean.FALSE;
369         } else {
370             text = getComboText(substringComboBox);
371         }
372         
373         if (isRegexp != null) {
374             
375             /* Let's initialize the form according to the peer: */
376             substringComboBox.setSelectedItem(text);
377             
378             regexpCheckBox.setSelected(isRegexp.booleanValue());
379             caseSensitiveCheckBox.setSelected(peer.isCaseSensitive());
380             wholeWordsCheckBox.setSelected(peer.getWholeWords());
381             
382         } else if ((text != null) && (text.length() != 0)) {
383             
384             /* Let's initialize the peer according to the form content: */
385             stringChanged();
386         }
387         
388         enableUI();
389     }
390     
391     public void addPropertyChangeListener(final PropertyChangeListener JavaDoc p1) {
392     }
393
394     public void removePropertyChangeListener(final PropertyChangeListener JavaDoc p1) {
395     }
396
397     public void requestFocus() {
398         JTextField JavaDoc tf = (JTextField JavaDoc)substringComboBox.getEditor().getEditorComponent();
399         int n = tf.getText().length();
400         if (n > 0) {
401             tf.setCaretPosition(0);
402             tf.moveCaretPosition(n);
403         }
404         tf.requestFocus();
405     }
406
407
408     // colors
409

410     private Color JavaDoc findColor (String JavaDoc key, Color JavaDoc defCol) {
411         Color JavaDoc color = UIManager.getDefaults().getColor (key);
412         if ( color != null ) {
413             return color;
414         }
415         return defCol;
416     }
417
418     private Color JavaDoc getForegroundColor () {
419         return findColor ("TextField.foreground", Color.black);
420     }
421
422     private Color JavaDoc getErrorForegroundColor () {
423         return findColor ("TextField.errorForeground", Color.red);
424     }
425
426     /**
427      * Enables or disables UI components (the checkboxes) based on the state
428      * of the regexpCheckBox.
429      */

430     private void enableUI() {
431         boolean r = regexpCheckBox.isSelected();
432         regexpCheckBox.setEnabled(true);
433         caseSensitiveCheckBox.setEnabled(!r);
434         wholeWordsCheckBox.setEnabled(!r);
435     }
436     
437     /**
438      * ItemListener implementation
439      */

440     public void itemStateChanged(ItemEvent JavaDoc e) {
441         Object JavaDoc source = e.getSource();
442         
443         if (source == substringComboBox) {
444             stringChanged();
445         
446         } else if (source == wholeWordsCheckBox) {
447             peer.setWholeWords(wholeWordsCheckBox.isSelected());
448             
449         } else if (source == caseSensitiveCheckBox) {
450             peer.setCaseSensitive(caseSensitiveCheckBox.isSelected());
451             
452         } else if (source == regexpCheckBox) {
453             regexpChkBoxChanged();
454             
455         } else {
456             /* This should never happen. */
457             assert false;
458         }
459     }
460     
461     /**
462      * Read current dialog contents as a SearchPattern.
463      * @return SearchPattern for the contents of the current dialog. Null if the
464      * search string is empty, meaning that the dialog is empty.
465      */

466     private SearchPattern getCurrentSearchPattern() {
467         return SearchPattern.
468                 create(
469                     getComboText(substringComboBox),
470                     wholeWordsCheckBox.isSelected(),
471                     caseSensitiveCheckBox.isSelected(),
472                     regexpCheckBox.isSelected());
473     }
474     
475     /**
476      * Init dialog according to the pattern.
477      * @param pat SearchPattern to fill into the dialog. Use null to empty the
478      * dialog.
479      */

480     private void putCurrentSearchPattern(final SearchPattern pat) {
481         assert pat != null;
482
483         substringComboBox.setSelectedItem(pat.getSearchExpression());
484         wholeWordsCheckBox.setSelected(pat.isWholeWords());
485         caseSensitiveCheckBox.setSelected(pat.isMatchCase());
486         regexpCheckBox.setSelected(pat.isRegExp());
487         
488         enableUI();
489     }
490     
491     private void initCheckBoxes(SearchPattern pat) {
492         wholeWordsCheckBox.setSelected(pat.isWholeWords());
493         caseSensitiveCheckBox.setSelected(pat.isMatchCase());
494         regexpCheckBox.setSelected(pat.isRegExp());
495         enableUI();
496     }
497     
498     /*****************************/
499     /**
500      * Hooks to search history
501      * By default, the history is empty.
502      **/

503    
504     /**
505      * Returns an unmodifiable List of SearchPatterns.
506      * By default, history is stored locally and not serialized between sessions.
507      *
508      * @return unmodifiable List of SearchPatterns
509      */

510     abstract protected List JavaDoc/*<SearchPattern>*/ getSearchPatterns();
511     
512     /** Adds SearchPattern to SearchHistory
513      * @param pattern the SearchPattern to add
514      */

515     abstract protected void addSearchPattern(SearchPattern pattern);
516
517
518     public void onOk() {
519         final SearchPattern searchPattern = getCurrentSearchPattern();
520         
521         if (searchPattern != null) {
522             addSearchPattern(searchPattern);
523             
524             String JavaDoc expr = searchPattern.getSearchExpression();
525             if ((expr != null) && (expr.length() != 0)) {
526                 FindDialogMemory.getDefault()
527                         .setSearchTypeUsed(peer.getClass().getName(), true);
528             }
529         }
530     }
531     
532     public void onCancel() {
533     }
534
535 }
536
Popular Tags