KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > MultiKeyBinding


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.editor;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import javax.swing.text.JTextComponent JavaDoc;
25 import javax.swing.KeyStroke JavaDoc;
26 import javax.swing.Action JavaDoc;
27
28 /**
29 * Extension of JTextComponent.KeyBinding to hold several successive keystrokes.
30 * The binding containing null key(s) is assumed to assign the default action.
31 *
32 * @author Miloslav Metelka
33 * @version 1.00
34 */

35
36 public class MultiKeyBinding extends JTextComponent.KeyBinding JavaDoc
37     implements java.io.Externalizable JavaDoc {
38
39     /** Successive keystroke. They must be pressed in the order they
40     * are stored in the array in order to invoke the associated action.
41     */

42     public KeyStroke JavaDoc[] keys;
43
44     static final long serialVersionUID =-8602816556604003688L;
45
46     /** Constructor for serialization */
47     public MultiKeyBinding() {
48         super(null, null);
49     }
50
51     /** Constructor for assigning keystroke sequence to action
52     * @param keys successive keystroke that must be pressed in order
53     * to invoke action
54     * @param actionName action that will be invoked. Action is resolved
55     * from name by calling kit.getActions() after the kit is constructed
56     */

57     public MultiKeyBinding(KeyStroke JavaDoc[] keys, String JavaDoc actionName) {
58         super(null, actionName);
59         this.keys = keys;
60     }
61
62     /** Compatibility constructor */
63     public MultiKeyBinding(KeyStroke JavaDoc key, String JavaDoc actionName) {
64         super(key, actionName);
65     }
66
67     /** Constructor for existing KeyBinding */
68     public MultiKeyBinding(JTextComponent.KeyBinding JavaDoc kb) {
69         this(kb.key, kb.actionName);
70     }
71
72     public boolean equals(Object JavaDoc o) {
73         if (o instanceof MultiKeyBinding) {
74             MultiKeyBinding kb = (MultiKeyBinding)o;
75
76             // Compare action names
77
if (actionName == null) {
78                 if (kb.actionName != null) {
79                     return false;
80                 }
81             } else {
82                 if (!actionName.equals(kb.actionName)) {
83                     return false;
84                 }
85             }
86
87             // Action names match, now compare action keys
88
if (keys == null) {
89                 if (kb.keys == null) {
90                     return (key == null && kb.key == null)
91                            || (key != null && key.equals(kb.key));
92                 } else {
93                     return (kb.keys.length == 1
94                             && ((key == null && kb.keys[0] == null)
95                                 || (key != null && key.equals(kb.keys[0]))));
96                 }
97             } else { // keys != null
98
if (kb.keys != null) {
99                     return Arrays.equals(keys, kb.keys);
100                 } else { // kb.keys == null
101
return (keys.length == 1
102                             && ((kb.key == null && keys[0] == null)
103                                 || (kb.key != null && kb.key.equals(keys[0]))));
104                 }
105             }
106         }
107         return false;
108     }
109
110     /** Add or replace key bindings array by changes given in
111     * the second bindings array
112     * @param target target list of bindings
113     * @param changes list of changes to apply:
114     * binding containing the non-null keystroke(s) and non-null action
115     * will add the binding or replace the old binding with the same
116     * keystroke(s) in the target array,
117     * binding of the non-null keystroke(s) and null action removes
118     * the binding for that keystroke from the target array (if it existed)
119     * binding containing null keystroke and non-null action adds
120     * or replaces default action
121     */

122     public static void updateKeyBindings(JTextComponent.KeyBinding JavaDoc[] target,
123                                          JTextComponent.KeyBinding JavaDoc[] changes) {
124         ArrayList JavaDoc tgt = new ArrayList JavaDoc(Arrays.asList(target));
125         MultiKeyBinding tmp = new MultiKeyBinding(new KeyStroke JavaDoc[1], null);
126         MultiKeyBinding cur;
127         for (int i = 0; i < changes.length; i++) {
128             if (changes[i] instanceof MultiKeyBinding) {
129                 cur = (MultiKeyBinding)changes[i];
130                 if (cur.keys == null) { // single key multi binding
131
tmp.keys[0] = cur.key;
132                     tmp.actionName = cur.actionName;
133                     cur = tmp;
134                 }
135             } else { // simulate multi binding
136
tmp.keys[0] = changes[i].key;
137                 tmp.actionName = changes[i].actionName;
138                 cur = tmp;
139             }
140             // cycle through all bindings
141
boolean matched = false;
142             for (int j = 0; j < tgt.size(); j++) {
143                 JTextComponent.KeyBinding JavaDoc kb = (JTextComponent.KeyBinding JavaDoc)tgt.get(j);
144                 if (kb instanceof MultiKeyBinding) {
145                     MultiKeyBinding mkb = (MultiKeyBinding)kb;
146                     if (mkb.keys == null) { // single key multi binding
147
if (cur.keys.length == 1 && cur.keys[0].equals(mkb.key)) { // found
148
if (mkb.actionName == null) { // remove
149
tgt.remove(i);
150                             } else { // replace
151
tgt.set(i, mkb);
152                             }
153                             matched = true;
154                             break;
155                         }
156                     } else { // multi binding
157
if (cur.keys.length == mkb.keys.length) {
158                             matched = true;
159                             for (int k = 0; k < cur.keys.length; k++) {
160                                 if (!cur.keys[k].equals(mkb.keys[k])) {
161                                     matched = false;
162                                     break;
163                                 }
164                             }
165                             if (matched) {
166                                 if (mkb.actionName == null) { // remove
167
tgt.remove(i);
168                                 } else { // replace
169
tgt.set(i, mkb);
170                                 }
171                                 break;
172                             }
173                         }
174                     }
175                 } else { // single key binding
176
if (cur.keys.length == 1 && cur.keys[0].equals(kb.key)) { // found
177
if (kb.actionName == null) { // remove
178
tgt.remove(i);
179                         } else { // replace
180
tgt.set(i, kb);
181                         }
182                         matched = true;
183                         break;
184                     }
185                 }
186             }
187             if (!matched) {
188                 tgt.add(changes[tgt.size()]);
189             }
190         }
191     }
192
193     public void readExternal(java.io.ObjectInput JavaDoc in)
194     throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
195         Object JavaDoc obj = in.readObject ();
196
197         if( obj instanceof Integer JavaDoc ) { // new settings format
198
int len = ((Integer JavaDoc)obj).intValue();
199             if( len >= 0 ) {
200                 keys = new KeyStroke JavaDoc[ len ];
201                 for( int i=0; i<len; i++ ) {
202                     keys[i] = KeyStroke.getKeyStroke( in.readInt(), in.readInt(), in.readBoolean() );
203                 }
204             } else {
205                 keys = null;
206             }
207
208             if( in.readBoolean() ) {
209                 key = KeyStroke.getKeyStroke( in.readInt(), in.readInt(), in.readBoolean() );
210             } else {
211                 key = null;
212             }
213
214             actionName = (String JavaDoc)in.readObject();
215
216         } else { // compatibility mode, settings in old format
217
keys = (KeyStroke JavaDoc[])obj;
218             key = (KeyStroke JavaDoc)in.readObject();
219             actionName = (String JavaDoc)in.readObject();
220         }
221     }
222
223     public void writeExternal(java.io.ObjectOutput JavaDoc out)
224     throws java.io.IOException JavaDoc {
225
226         if( keys != null ) {
227             out.writeObject( new Integer JavaDoc( keys.length ) );
228             for( int i=0; i<keys.length; i++ ) {
229                 out.writeInt( keys[i].getKeyCode() );
230                 out.writeInt( keys[i].getModifiers() );
231                 out.writeBoolean( keys[i].isOnKeyRelease() );
232             }
233         } else {
234             out.writeObject( new Integer JavaDoc( -1 ) );
235         }
236
237         if( key != null ) {
238             out.writeBoolean( true );
239             out.writeInt( key.getKeyCode() );
240             out.writeInt( key.getModifiers() );
241             out.writeBoolean( key.isOnKeyRelease() );
242         } else {
243             out.writeBoolean( false );
244         }
245         out.writeObject( actionName );
246     }
247
248     public String JavaDoc toString() {
249         if (keys == null) {
250             return "key=" + key + ", actionName=" + actionName; // NOI18N
251
} else {
252             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
253             for (int i = 0; i < keys.length; i++) {
254                 sb.append("key"); // NOI18N
255
sb.append(i);
256                 sb.append('=');
257                 sb.append(keys[i]);
258                 sb.append(", "); // NOI18N
259
}
260             sb.append("actionName="); // NOI18N
261
sb.append(actionName);
262             return sb.toString();
263         }
264     }
265
266 }
267
Popular Tags