KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > options > KeyBindingsEditorPanel


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 package org.netbeans.modules.editor.options;
21
22 import java.beans.*;
23 import java.awt.event.*;
24 import java.awt.Dialog JavaDoc;
25 import java.awt.Component JavaDoc;
26 import javax.swing.*;
27 import java.util.*;
28
29 import org.openide.*;
30 import org.openide.util.NbBundle;
31 import org.netbeans.editor.*;
32 import org.netbeans.modules.editor.NbEditorKit;
33 import org.openide.util.HelpCtx;
34 import org.openide.util.Lookup;
35
36
37 /**
38  * @author Petr Nejedly
39  */

40 public class KeyBindingsEditorPanel extends javax.swing.JPanel JavaDoc {
41
42     private ActionDescriptor[] acts;
43     private int actionIndex;
44     private String JavaDoc kitClassName;
45     private KeyBindingsEditor editor;
46     private ButtonGroup sortGroup;
47
48     /** Creates new form KeyBindingsEditorPanel */
49     public KeyBindingsEditorPanel( KeyBindingsEditor editor ) {
50         this.editor = editor;
51         initComponents ();
52         
53         getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_Panel")); // NOI18N
54
sequencesLabel.setDisplayedMnemonic(getBundleString("KBEP_Sequences_Mnemonic").charAt (0)); // NOI18N
55
actionsList.getAccessibleContext().setAccessibleName(getBundleString("ACSN_KBEP_Actions")); // NOI18N
56
actionsList.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_Actions")); // NOI18N
57
sequencesList.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_Sequences")); // NOI18N
58
nameSortRadioButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_name_sort_button")); // NOI18N
59
actionSortRadioButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_action_sort_button")); // NOI18N
60
addSequenceButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_Add")); // NOI18N
61
removeSequenceButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_KBEP_Remove")); // NOI18N
62

63         // set up ButtonGroup for sort Buttons
64
sortGroup = new ButtonGroup ();
65         sortGroup.add (actionSortRadioButton);
66         sortGroup.add (nameSortRadioButton);
67     }
68
69     private String JavaDoc getBundleString(String JavaDoc s) {
70         return NbBundle.getMessage(KeyBindingsEditorPanel.class, s);
71     }
72     
73     
74     /**
75      * Sets the current editorKit and action->Vector(KeyStroke[]) mapping.
76      * Note: first item points to proper EditorKit class.
77      */

78     public void setValue( List l ) {
79         if (l != null)
80             kitClassName = (String JavaDoc)l.get( 0 );
81         else
82             return;
83         
84         Class JavaDoc kitClass = null;
85         try {
86             ClassLoader JavaDoc loader = (ClassLoader JavaDoc)Lookup.getDefault().lookup(ClassLoader JavaDoc.class);
87             kitClass = Class.forName( kitClassName, true, loader);
88         } catch( ClassNotFoundException JavaDoc e ) {
89             org.openide.ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, e);
90             return;
91         }
92
93         // Get all actions available in given kit, sort them and store their
94
// ActionDescriptors. Prepare mapping for looking them up by their names.
95
Class JavaDoc actionKitClass = kitClass;
96         if( actionKitClass == BaseKit.class )
97             actionKitClass = NbEditorKit.class; // Hack to get actions from higher-located kits too
98
Action[] actions = BaseKit.getKit( actionKitClass ).getActions();
99
100         // Create our sorter, ActionDescriptors knows themselves how to sort
101
TreeMap treeMap = new TreeMap( );
102         // Fill it with new ActionDescriptors for actions, they'll be in-sorted
103
for( int i=0; i<actions.length; i++ ) {
104             if (actions[i]!=null){
105                 Object JavaDoc internalActionObj = actions[i].getValue(BaseAction.NO_KEYBINDING);
106                 if (internalActionObj instanceof Boolean JavaDoc){
107                     if (((Boolean JavaDoc)internalActionObj).booleanValue()){
108                         continue; //filter out editor internal actions - #49589
109
}
110                 }
111             }
112             ActionDescriptor val = new ActionDescriptor( actions[i] );
113             treeMap.put( val.name, val );
114         }
115
116         // add all inherited bindings
117
Class JavaDoc parent = kitClass.getSuperclass();
118         Settings.KitAndValue[] kv = Settings.getValueHierarchy( parent, SettingsNames.KEY_BINDING_LIST );
119         // go through all levels and add inherited bindings
120
for( int i=kv.length - 1; i >= 0; i--)
121             addKeyBindingList( treeMap, ((List)kv[i].value).iterator(), true );
122
123
124         // add bindings of current kit - couple ActionDescriptors with proper KeySequences
125
addKeyBindingList( treeMap, l.listIterator( 1 ), false );
126
127         // Create our sorted list of ActionDescriptors
128
acts = (ActionDescriptor[])treeMap.values().toArray( new ActionDescriptor[0] );
129
130         // do we have anything to manage?
131
if( acts.length > 0 ) addSequenceButton.setEnabled( true );
132
133         // sort all Actions
134
Arrays.sort (acts);
135         
136         actionsList.setListData( acts );
137         actionsList.setSelectedIndex( actionIndex );
138         updateSequences( 0 );
139         
140         // select the right sort button
141
if (ActionDescriptor.getSortMode () == ActionDescriptor.SORT_BY_ACTION) {
142             actionSortRadioButton.setSelected (true);
143         } else {
144             nameSortRadioButton.setSelected (true);
145         }
146     }
147
148     private void addKeyBindingList( Map target, Iterator source, boolean inherited ) {
149         while( source.hasNext() ) {
150             MultiKeyBinding b = (MultiKeyBinding)source.next();
151             ActionDescriptor ad = (ActionDescriptor)target.get( b.actionName );
152
153             if( ad != null ) { // we've found proper action
154
KeySequence sequence = getKeySequenceForBinding( inherited, b );
155
156                 if( sequence == null ) {
157                 } else {
158                     ad.sequences.add( sequence );
159                 }
160             } else {
161                 // complain for weird mapping
162
//System.err.println( "Weird mapping" );
163
}
164         }
165     }
166
167     private KeySequence getKeySequenceForBinding( boolean inherited, MultiKeyBinding binding ) {
168         KeyStroke[] sequence = binding.keys;
169         if( sequence == null ) { // convert simple KeyStroke to KeyStroke[1]
170
if( binding.key == null ) return null;
171             sequence = new KeyStroke[1];
172             sequence[0] = binding.key;
173         }
174         return new KeySequence( inherited, sequence );
175     }
176
177     /**
178      * Return the list of MultiKeyBindings
179      */

180     public List getValue() {
181         Vector val = new Vector();
182         // add the kitClass of current kit
183
val.add( kitClassName );
184
185         // go through whole array of Actions and add all KeySequences for every Action
186
for( int i=0; i<acts.length; i++ ) {
187             String JavaDoc name = acts[i].name;
188             for( Iterator iter=acts[i].sequences.iterator(); iter.hasNext(); ) {
189                 KeySequence seq = (KeySequence)iter.next();
190                 if( !seq.isInherited() ) { // add only our bindings, not inherited
191
val.add( new MultiKeyBinding( seq.getKeyStrokes(), name ) );
192                 }
193             }
194         }
195
196         // that's it, done
197
return val;
198     }
199
200     // index tells which sequence to select
201
private void updateSequences( int index ) {
202         Vector bindings = acts[actionIndex].sequences;
203         // reflect the change in actionIndex or actual sequenceList
204
sequencesList.setListData( bindings );
205         // select proper line, this will also fire ValueChanged on sequencesList
206
if( bindings.size() > 0 ) sequencesList.setSelectedIndex( index );
207     }
208
209     // index tells which sequence is selected - to which we are bound
210
private void updateRemoveButton() {
211         int id = sequencesList.getSelectedIndex() ;
212         Vector b = acts[actionIndex].sequences;
213
214         boolean enable = id >= 0 && id < b.size() && !((KeySequence)b.get( id )).isInherited();
215         removeSequenceButton.setEnabled( enable );
216     }
217
218
219     private void notifyEditor() {
220         if( editor != null ) editor.customEditorChange();
221     }
222
223     private void sortActionsList () {
224         // set sort mode of ActionDescriptor
225
int mode = actionSortRadioButton.isSelected () ? ActionDescriptor.SORT_BY_ACTION
226                                                      : ActionDescriptor.SORT_BY_NAME;
227         ActionDescriptor.setSortMode (mode);
228         ActionDescriptor ad = acts [actionIndex];
229         // resort array
230
Arrays.sort (acts);
231         
232         // refresh list content and select right item
233
int newIndex = 0;
234         for (int x=0; x < acts.length; x++) {
235             if (acts [x] == ad) {
236                 newIndex = x;
237                 break;
238             }
239         }
240         actionsList.setListData (acts);
241         // note: setListData will call actionsListValueChanged which will set
242
// actionIndex to -1 because the selection is empty.
243
actionIndex = newIndex;
244         actionsList.setSelectedIndex (actionIndex);
245         actionsList.ensureIndexIsVisible (actionIndex);
246         actionsList.requestFocus ();
247     }
248     
249     /**
250      * Create our visual representation.
251      */

252     private void initComponents() {//GEN-BEGIN:initComponents
253
java.awt.GridBagConstraints JavaDoc gridBagConstraints;
254
255         actionsPanel = new javax.swing.JPanel JavaDoc();
256         sortButtonsPanel = new javax.swing.JPanel JavaDoc();
257         nameSortRadioButton = new javax.swing.JRadioButton JavaDoc();
258         actionSortRadioButton = new javax.swing.JRadioButton JavaDoc();
259         actionsScrollPane = new javax.swing.JScrollPane JavaDoc();
260         actionsList = new javax.swing.JList JavaDoc();
261         sequencesPanel = new javax.swing.JPanel JavaDoc();
262         sequencesLabel = new javax.swing.JLabel JavaDoc();
263         sequencesScrollPane = new javax.swing.JScrollPane JavaDoc();
264         sequencesList = new javax.swing.JList JavaDoc();
265         addSequenceButton = new javax.swing.JButton JavaDoc();
266         removeSequenceButton = new javax.swing.JButton JavaDoc();
267
268         setLayout(new java.awt.BorderLayout JavaDoc(0, 12));
269
270         setBorder(new javax.swing.border.EmptyBorder JavaDoc(new java.awt.Insets JavaDoc(12, 12, 11, 11)));
271         actionsPanel.setLayout(new java.awt.GridBagLayout JavaDoc());
272
273         actionsPanel.setBorder(new javax.swing.border.TitledBorder JavaDoc(new javax.swing.border.EmptyBorder JavaDoc(new java.awt.Insets JavaDoc(0, 0, 0, 0)), getBundleString("KBEP_Actions")));
274         sortButtonsPanel.setLayout(new java.awt.GridBagLayout JavaDoc());
275
276         nameSortRadioButton.setMnemonic(getBundleString ("KBEP_name_sort_button_mnemonic").charAt (0));
277         nameSortRadioButton.setText(getBundleString ("KBEP_name_sort_button"));
278         nameSortRadioButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
279             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
280                 nameSortRadioButtonActionPerformed(evt);
281             }
282         });
283
284         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
285         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
286         sortButtonsPanel.add(nameSortRadioButton, gridBagConstraints);
287
288         actionSortRadioButton.setMnemonic(getBundleString ("KBEP_action_sort_button_mnemonic").charAt (0));
289         actionSortRadioButton.setText(getBundleString ("KBEP_action_sort_button"));
290         actionSortRadioButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
291             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
292                 actionSortRadioButtonActionPerformed(evt);
293             }
294         });
295
296         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
297         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
298         gridBagConstraints.weightx = 1.0;
299         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 12, 0, 0);
300         sortButtonsPanel.add(actionSortRadioButton, gridBagConstraints);
301
302         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
303         gridBagConstraints.gridx = 0;
304         gridBagConstraints.gridy = 0;
305         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
306         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
307         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
308         actionsPanel.add(sortButtonsPanel, gridBagConstraints);
309
310         actionsList.addListSelectionListener(new javax.swing.event.ListSelectionListener JavaDoc() {
311             public void valueChanged(javax.swing.event.ListSelectionEvent JavaDoc evt) {
312                 actionsListValueChanged(evt);
313             }
314         });
315
316         actionsScrollPane.setViewportView(actionsList);
317
318         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
319         gridBagConstraints.gridx = 0;
320         gridBagConstraints.gridy = 1;
321         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
322         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
323         gridBagConstraints.weightx = 1.0;
324         gridBagConstraints.weighty = 1.0;
325         actionsPanel.add(actionsScrollPane, gridBagConstraints);
326
327         add(actionsPanel, java.awt.BorderLayout.CENTER);
328
329         sequencesPanel.setLayout(new java.awt.GridBagLayout JavaDoc());
330
331         sequencesLabel.setLabelFor(sequencesList);
332         sequencesLabel.setText(getBundleString("KBEP_Sequences"));
333         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
334         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
335         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 2, 12);
336         sequencesPanel.add(sequencesLabel, gridBagConstraints);
337
338         sequencesScrollPane.setPreferredSize(new java.awt.Dimension JavaDoc(259, 80));
339         sequencesList.setCellRenderer(new KeySequenceCellRenderer());
340         sequencesList.addListSelectionListener(new javax.swing.event.ListSelectionListener JavaDoc() {
341             public void valueChanged(javax.swing.event.ListSelectionEvent JavaDoc evt) {
342                 sequencesListValueChanged(evt);
343             }
344         });
345
346         sequencesScrollPane.setViewportView(sequencesList);
347
348         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
349         gridBagConstraints.gridx = 0;
350         gridBagConstraints.gridy = 1;
351         gridBagConstraints.gridheight = 3;
352         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
353         gridBagConstraints.weightx = 1.0;
354         gridBagConstraints.weighty = 1.0;
355         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 0, 12);
356         sequencesPanel.add(sequencesScrollPane, gridBagConstraints);
357
358         addSequenceButton.setMnemonic(getBundleString ("KBEP_Add_Mnemonic").charAt (0));
359         addSequenceButton.setText(getBundleString( "KBEP_Add" ));
360         addSequenceButton.setEnabled(false);
361         addSequenceButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
362             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
363                 addSequenceButtonActionPerformed(evt);
364             }
365         });
366
367         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
368         gridBagConstraints.gridx = 1;
369         gridBagConstraints.gridy = 1;
370         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
371         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
372         sequencesPanel.add(addSequenceButton, gridBagConstraints);
373
374         removeSequenceButton.setMnemonic(getBundleString ("KBEP_Remove_Mnemonic").charAt (0));
375         removeSequenceButton.setText(getBundleString( "KBEP_Remove" ));
376         removeSequenceButton.setEnabled(false);
377         removeSequenceButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
378             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
379                 removeSequenceButtonActionPerformed(evt);
380             }
381         });
382
383         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
384         gridBagConstraints.gridx = 1;
385         gridBagConstraints.gridy = 2;
386         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
387         sequencesPanel.add(removeSequenceButton, gridBagConstraints);
388
389         add(sequencesPanel, java.awt.BorderLayout.SOUTH);
390
391     }//GEN-END:initComponents
392

393     private void nameSortRadioButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_nameSortRadioButtonActionPerformed
394
sortActionsList ();
395     }//GEN-LAST:event_nameSortRadioButtonActionPerformed
396

397     private void actionSortRadioButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_actionSortRadioButtonActionPerformed
398
sortActionsList ();
399     }//GEN-LAST:event_actionSortRadioButtonActionPerformed
400

401     private void sequencesListValueChanged (javax.swing.event.ListSelectionEvent JavaDoc evt) {//GEN-FIRST:event_sequencesListValueChanged
402
updateRemoveButton();
403     }//GEN-LAST:event_sequencesListValueChanged
404

405     private void addSequenceButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_addSequenceButtonActionPerformed
406
// Create KeySequence input dialog and ask user for value
407
KeySequence newSequence = new KeySequenceRequester().getKeySequence();
408         // If user canceled action, stop entering
409
if( newSequence == null ) return;
410         // Add new KeySequence to proper list
411
acts[actionIndex].sequences.add( newSequence );
412         // Render and select the last added item
413
updateSequences( acts[actionIndex].sequences.size()-1 );
414         notifyEditor();
415     }//GEN-LAST:event_addSequenceButtonActionPerformed
416

417     private void removeSequenceButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_removeSequenceButtonActionPerformed
418
// Remove selected sequences from sequenceList
419
int index = sequencesList.getSelectedIndex();
420         if( index >= 0 ) {
421             acts[actionIndex].sequences.remove( index );
422             if( index >= acts[actionIndex].sequences.size() ) index--;
423             updateSequences( index );
424             notifyEditor();
425         }
426     }//GEN-LAST:event_removeSequenceButtonActionPerformed
427

428     private void actionsListValueChanged (javax.swing.event.ListSelectionEvent JavaDoc evt) {//GEN-FIRST:event_actionsListValueChanged
429
if (actionsList.getSelectedIndex () < 0) return;
430         actionIndex = actionsList.getSelectedIndex();
431         updateSequences( 0 );
432     }//GEN-LAST:event_actionsListValueChanged
433

434
435     // Variables declaration - do not modify//GEN-BEGIN:variables
436
private javax.swing.JList JavaDoc sequencesList;
437     private javax.swing.JButton JavaDoc addSequenceButton;
438     private javax.swing.JPanel JavaDoc sortButtonsPanel;
439     private javax.swing.JPanel JavaDoc actionsPanel;
440     private javax.swing.JScrollPane JavaDoc sequencesScrollPane;
441     private javax.swing.JRadioButton JavaDoc actionSortRadioButton;
442     private javax.swing.JPanel JavaDoc sequencesPanel;
443     private javax.swing.JScrollPane JavaDoc actionsScrollPane;
444     private javax.swing.JRadioButton JavaDoc nameSortRadioButton;
445     private javax.swing.JButton JavaDoc removeSequenceButton;
446     private javax.swing.JLabel JavaDoc sequencesLabel;
447     private javax.swing.JList JavaDoc actionsList;
448     // End of variables declaration//GEN-END:variables
449

450     /**
451      * Encapsulation for components of dialog asking for new KeySequence
452      */

453     private class KeySequenceRequester {
454
455         KeySequenceInputPanel input;
456         DialogDescriptor dd;
457         Dialog JavaDoc dial;
458
459         Object JavaDoc[] buttons = { new JButton( getBundleString( "KBEP_OK_LABEL" ) ), // NOI18N
460
new JButton( getBundleString("KBEP_CLEAR_LABEL" ) ), // NOI18N
461
DialogDescriptor.CANCEL_OPTION };
462         KeySequence retVal = null;
463
464         KeySequenceRequester() {
465             ((JButton)buttons[0]).getAccessibleContext().setAccessibleDescription(LocaleSupport.getString("ACSD_KBEP_OK")); // NOI18N
466
((JButton)buttons[1]).getAccessibleContext().setAccessibleDescription(LocaleSupport.getString("ACSD_KBEP_CLEAR")); // NOI18N
467
((JButton)buttons[1]).setMnemonic (getBundleString("KBEP_CLEAR_Mnemonic").charAt (0)); // NOI18N
468
((JButton)buttons[0]).setEnabled( false ); // default initial state
469

470             // Prepare KeySequence input dialog
471
input = new KeySequenceInputPanel();
472             input.addPropertyChangeListener( new PropertyChangeListener() {
473                                                  public void propertyChange( PropertyChangeEvent evt ) {
474                                                      if( KeySequenceInputPanel.PROP_KEYSEQUENCE != evt.getPropertyName() ) return;
475                                                      KeyStroke[] seq = input.getKeySequence();
476                                                      String JavaDoc warn = getCollisionString( seq );
477                                                      input.setInfoText( warn == null ? "" : warn ); // NOI18N
478
((JButton)buttons[0]).setEnabled( warn == null );
479                                                  }
480                                              } );
481
482             dd = new DialogDescriptor ( input, getBundleString( "KBEP_AddSequence" ), // NOI18N
483
true, buttons, buttons[0], DialogDescriptor.BOTTOM_ALIGN, HelpCtx.DEFAULT_HELP, new ActionListener(){
484                                             public void actionPerformed( ActionEvent evt ) {
485                                                 if( evt.getSource() == buttons[1] ) { // Clear pressed
486
input.clear(); // Clear entered KeyStrokes, start again
487
input.requestFocus(); // Make user imediately able to enter new strokes
488
} else if( evt.getSource() == buttons[0] ) { // OK pressed
489
retVal = new KeySequence( false, input.getKeySequence() );
490                                                     dial.dispose(); // Done
491
}
492                                             }
493                                         });
494
495         }
496
497         KeySequence getKeySequence() {
498             dial = org.openide.DialogDisplayer.getDefault().createDialog(dd);
499             input.requestFocus(); // Place caret in it, hopefully
500
dial.setVisible(true); // let the user tell us their wish, result will be stored in retVal
501
return retVal;
502         }
503
504         String JavaDoc getCollisionString( KeyStroke[] seq ) {
505             if( seq.length == 0 ) return ""; // NOI18N not valid sequence, but don't alert user
506

507             for( int i=0; i<acts.length; i++ ) { // for all actions
508
Iterator iter = acts[i].sequences.iterator();
509                 while( iter.hasNext() ) {
510                     KeyStroke[] s1 = ((KeySequence)iter.next()).getKeyStrokes();
511                     if( isOverlapingSequence( s1, seq ) ) {
512                         Object JavaDoc[] values = { Utilities.keySequenceToString( s1 ), acts[i] };
513                         return NbBundle.getMessage(KeyBindingsEditorPanel.class, "KBEP_FMT_Collision" , values );
514                     }
515                 }
516             }
517             return null; // no colliding sequence
518
}
519
520         private boolean isOverlapingSequence( KeyStroke[] s1, KeyStroke[] s2 ) {
521             int l = Math.min( s1.length, s2.length );
522             while( l-- > 0 ) if( !s1[l].equals( s2[l] ) ) return false;
523             return true;
524         }
525     }
526
527
528
529     /**
530      * Information holder class for Action, it knows it's Action name, which
531      * sequences is this Action bound to, and how to correctly present
532      * it as String (it's displayName ).
533      * It also knows how to sort it's instances (Comparable)
534      * As it is private, all members could be directly read.
535      */

536     private static final class ActionDescriptor implements Comparable JavaDoc {
537         
538         public static final int SORT_BY_ACTION = 0;
539         public static final int SORT_BY_NAME = 1;
540         private static int sortMode = SORT_BY_NAME;
541         
542         String JavaDoc name;
543         String JavaDoc displayName;
544         Vector sequences;
545
546         ActionDescriptor( Action a ) {
547             name = (String JavaDoc)a.getValue( Action.NAME );
548             String JavaDoc shortDesc = (String JavaDoc)a.getValue( Action.SHORT_DESCRIPTION );
549             displayName = shortDesc == null ? name : shortDesc + " [" + name + "]"; // NOI18N
550
sequences = new Vector();
551         }
552
553         public String JavaDoc toString() {
554             return displayName;
555         }
556
557         // Naturaly ordered by its name
558
public int compareTo( Object JavaDoc o ) {
559             if (sortMode == SORT_BY_ACTION) {
560                 return name.compareTo( ((ActionDescriptor)o).name );
561             } else {
562                 return displayName.compareToIgnoreCase (((ActionDescriptor)o).displayName);
563             }
564         }
565         
566         public static void setSortMode (int sMode) {
567             sortMode = sMode;
568         }
569         public static int getSortMode () {
570             return sortMode;
571         }
572     }
573
574     /**
575      * Container class for KeyStroke[], which knows if this KeyStroke is inherited
576      * and how to correctly present it as String.
577      */

578     private final static class KeySequence {
579         private boolean inherited;
580         private KeyStroke[] sequence;
581
582         KeySequence( boolean inherited, KeyStroke[] sequence) {
583             this.inherited = inherited;
584             this.sequence = sequence;
585         }
586
587         KeyStroke[] getKeyStrokes() {
588             return sequence;
589         }
590
591         boolean isInherited() {
592             return inherited;
593         }
594
595         public String JavaDoc toString() {
596             return Utilities.keySequenceToString( sequence );
597         }
598     }
599
600     /**
601      * Special cell renderer for sequencesList, which renders inherited KeySequences
602      * differently from not inherited to visually notify user which sequences
603      * couldn't be removed.
604      */

605     private final static class KeySequenceCellRenderer extends JLabel implements ListCellRenderer {
606
607         public KeySequenceCellRenderer() {
608             setOpaque( true );
609         }
610
611         public Component JavaDoc getListCellRendererComponent( JList list, Object JavaDoc value,
612                 int index, boolean isSelected, boolean cellHasFocus
613                                                      ) {
614             setText( value.toString() );
615             setBackground( isSelected ? list.getSelectionBackground() : list.getBackground() );
616
617             if( (value instanceof KeySequence) && ((KeySequence)value).isInherited() )
618                 setForeground( java.awt.Color.gray );
619             else
620                 setForeground( isSelected ? list.getSelectionForeground() : list.getForeground() );
621
622             setEnabled(list.isEnabled());
623             setFont(list.getFont());
624             return this;
625         }
626     }
627
628 }
629
Popular Tags