KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > contentassist > AbstractControlContentAssistSubjectAdapter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.contentassist;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.core.runtime.Platform;
21
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.custom.VerifyKeyListener;
24 import org.eclipse.swt.events.DisposeEvent;
25 import org.eclipse.swt.events.DisposeListener;
26 import org.eclipse.swt.events.KeyEvent;
27 import org.eclipse.swt.events.KeyListener;
28 import org.eclipse.swt.events.VerifyEvent;
29 import org.eclipse.swt.graphics.Image;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Event;
32 import org.eclipse.swt.widgets.Listener;
33
34 import org.eclipse.jface.fieldassist.ControlDecoration;
35 import org.eclipse.jface.resource.ImageDescriptor;
36 import org.eclipse.jface.text.IEventConsumer;
37 import org.eclipse.jface.viewers.ILabelProvider;
38 import org.eclipse.jface.viewers.ILabelProviderListener;
39 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
40
41
42 /**
43  * An <code>AbstractControlContentAssistSubjectAdapter</code> delegates assistance requests from a
44  * {@linkplain org.eclipse.jface.text.contentassist.ContentAssistant content assistant}
45  * to a <code>Control</code>.
46  *
47  * A visual feedback can be configured via {@link #setContentAssistCueProvider(ILabelProvider)}.
48  *
49  * @since 3.0
50  * @deprecated As of 3.2, replaced by Platform UI's field assist support
51  */

52 public abstract class AbstractControlContentAssistSubjectAdapter implements IContentAssistSubjectControl {
53
54     protected static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jface.text/debug/ContentAssistSubjectAdapters")); //$NON-NLS-1$//$NON-NLS-2$
55

56     /**
57      * VerifyKeyListeners for the control.
58      */

59     private List JavaDoc fVerifyKeyListeners;
60     /**
61      * KeyListeners for the control.
62      */

63     private Set JavaDoc fKeyListeners;
64     /**
65      * The Listener installed on the control which passes events to
66      * {@link #fVerifyKeyListeners fVerifyKeyListeners} and {@link #fKeyListeners}.
67      */

68     private Listener fControlListener;
69     /**
70      * The cue label provider, or <code>null</code> iff none.
71      * @since 3.3
72      */

73     private ILabelProvider fCueLabelProvider;
74     /**
75      * The control decoration, or <code>null</code> iff fCueLabelProvider is null.
76      * @since 3.3
77      */

78     private ControlDecoration fControlDecoration;
79     /**
80      * The default cue image, or <code>null</code> if not cached yet.
81      * @since 3.3
82      */

83     private Image fCachedDefaultCueImage;
84     
85     /**
86      * Creates a new {@link AbstractControlContentAssistSubjectAdapter}.
87      */

88     public AbstractControlContentAssistSubjectAdapter() {
89         fVerifyKeyListeners= new ArrayList JavaDoc(1);
90         fKeyListeners= new HashSet JavaDoc(1);
91     }
92
93     /*
94      * @see org.eclipse.jface.text.contentassist.IContentAssistSubjectControl#getControl()
95      */

96     public abstract Control getControl();
97
98     /*
99      * @see org.eclipse.jface.text.contentassist.IContentAssistSubjectControl#addKeyListener(org.eclipse.swt.events.KeyListener)
100      */

101     public void addKeyListener(KeyListener keyListener) {
102         fKeyListeners.add(keyListener);
103
104         if (DEBUG)
105             System.out.println("AbstractControlContentAssistSubjectAdapter#addKeyListener()"); //$NON-NLS-1$
106

107         installControlListener();
108     }
109
110     /*
111      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#removeKeyListener(org.eclipse.swt.events.KeyListener)
112      */

113     public void removeKeyListener(KeyListener keyListener) {
114         boolean deleted= fKeyListeners.remove(keyListener);
115
116         if (DEBUG) {
117             if (!deleted)
118                 System.out.println("removeKeyListener -> wasn't here"); //$NON-NLS-1$
119
System.out.println("AbstractControlContentAssistSubjectAdapter#removeKeyListener() -> " + fKeyListeners.size()); //$NON-NLS-1$
120
}
121
122         uninstallControlListener();
123     }
124
125     /*
126      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#supportsVerifyKeyListener()
127      */

128     public boolean supportsVerifyKeyListener() {
129         return true;
130     }
131
132     /*
133      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#appendVerifyKeyListener(org.eclipse.swt.custom.VerifyKeyListener)
134      */

135     public boolean appendVerifyKeyListener(final VerifyKeyListener verifyKeyListener) {
136         fVerifyKeyListeners.add(verifyKeyListener);
137
138         if (DEBUG)
139             System.out.println("AbstractControlContentAssistSubjectAdapter#appendVerifyKeyListener() -> " + fVerifyKeyListeners.size()); //$NON-NLS-1$
140

141         installControlListener();
142         return true;
143     }
144
145     /*
146      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#prependVerifyKeyListener(org.eclipse.swt.custom.VerifyKeyListener)
147      */

148     public boolean prependVerifyKeyListener(final VerifyKeyListener verifyKeyListener) {
149         fVerifyKeyListeners.add(0, verifyKeyListener);
150
151         if (DEBUG)
152             System.out.println("AbstractControlContentAssistSubjectAdapter#prependVerifyKeyListener() -> " + fVerifyKeyListeners.size()); //$NON-NLS-1$
153

154         installControlListener();
155         return true;
156     }
157
158     /*
159      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#removeVerifyKeyListener(org.eclipse.swt.custom.VerifyKeyListener)
160      */

161     public void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener) {
162         fVerifyKeyListeners.remove(verifyKeyListener);
163
164         if (DEBUG)
165             System.out.println("AbstractControlContentAssistSubjectAdapter#removeVerifyKeyListener() -> " + fVerifyKeyListeners.size()); //$NON-NLS-1$
166

167         uninstallControlListener();
168     }
169
170     /*
171      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#setEventConsumer(org.eclipse.jface.text.IEventConsumer)
172      */

173     public void setEventConsumer(IEventConsumer eventConsumer) {
174         // this is not supported
175
if (DEBUG)
176             System.out.println("AbstractControlContentAssistSubjectAdapter#setEventConsumer()"); //$NON-NLS-1$
177
}
178
179     /*
180      * @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getLineDelimiter()
181      */

182     public String JavaDoc getLineDelimiter() {
183         return System.getProperty("line.separator"); //$NON-NLS-1$
184
}
185
186     /**
187      * Installs <code>fControlListener</code>, which handles VerifyEvents and KeyEvents by
188      * passing them to {@link #fVerifyKeyListeners} and {@link #fKeyListeners}.
189      */

190     private void installControlListener() {
191         if (DEBUG)
192             System.out.println("AbstractControlContentAssistSubjectAdapter#installControlListener() -> k: " + fKeyListeners.size() + ", v: " + fVerifyKeyListeners.size()); //$NON-NLS-1$ //$NON-NLS-2$
193

194         if (fControlListener != null)
195             return;
196
197         fControlListener= new Listener() {
198             public void handleEvent(Event e) {
199                 if (! getControl().isFocusControl())
200                     return; //SWT.TRAVERSE_MNEMONIC events can also come in to inactive widgets
201
VerifyEvent verifyEvent= new VerifyEvent(e);
202                 KeyEvent keyEvent= new KeyEvent(e);
203                 switch (e.type) {
204                     case SWT.Traverse :
205
206                         if (DEBUG)
207                             dump("before traverse", e, verifyEvent); //$NON-NLS-1$
208

209                         verifyEvent.doit= true;
210                         for (Iterator JavaDoc iter= fVerifyKeyListeners.iterator(); iter.hasNext(); ) {
211                             ((VerifyKeyListener) iter.next()).verifyKey(verifyEvent);
212                             if (! verifyEvent.doit) {
213                                 e.detail= SWT.TRAVERSE_NONE;
214                                 e.doit= true;
215                                 if (DEBUG)
216                                     dump("traverse eaten by verify", e, verifyEvent); //$NON-NLS-1$
217
return;
218                             }
219
220                             if (DEBUG)
221                                 dump("traverse OK", e, verifyEvent); //$NON-NLS-1$
222
}
223                         break;
224
225                     case SWT.KeyDown:
226                         for (Iterator JavaDoc iter= fVerifyKeyListeners.iterator(); iter.hasNext(); ) {
227                             ((VerifyKeyListener) iter.next()).verifyKey(verifyEvent);
228                             if (! verifyEvent.doit) {
229                                 e.doit= verifyEvent.doit;
230                                 if (DEBUG)
231                                     dump("keyDown eaten by verify", e, verifyEvent); //$NON-NLS-1$
232
return;
233                             }
234                         }
235
236                         if (DEBUG)
237                             dump("keyDown OK", e, verifyEvent); //$NON-NLS-1$
238

239                         for (Iterator JavaDoc iter= fKeyListeners.iterator(); iter.hasNext();) {
240                             ((KeyListener) iter.next()).keyPressed(keyEvent);
241                         }
242                         break;
243
244                     default :
245                         Assert.isTrue(false);
246                 }
247             }
248
249             /**
250              * Dump the given events to "standard" output.
251              *
252              * @param who who dump's
253              * @param e the event
254              * @param ve the verify event
255              */

256             private void dump(String JavaDoc who, Event e, VerifyEvent ve) {
257                 StringBuffer JavaDoc sb= new StringBuffer JavaDoc("--- [AbstractControlContentAssistSubjectAdapter]\n"); //$NON-NLS-1$
258
sb.append(who);
259                 sb.append(" - e: keyCode="+e.keyCode+hex(e.keyCode)); //$NON-NLS-1$
260
sb.append("; character="+e.character+hex(e.character)); //$NON-NLS-1$
261
sb.append("; stateMask="+e.stateMask+hex(e.stateMask)); //$NON-NLS-1$
262
sb.append("; doit="+e.doit); //$NON-NLS-1$
263
sb.append("; detail="+e.detail+hex(e.detail)); //$NON-NLS-1$
264
sb.append("; widget="+e.widget); //$NON-NLS-1$
265
sb.append("\n"); //$NON-NLS-1$
266
sb.append(" verifyEvent keyCode="+e.keyCode+hex(e.keyCode)); //$NON-NLS-1$
267
sb.append("; character="+e.character+hex(e.character)); //$NON-NLS-1$
268
sb.append("; stateMask="+e.stateMask+hex(e.stateMask)); //$NON-NLS-1$
269
sb.append("; doit="+ve.doit); //$NON-NLS-1$
270
sb.append("; widget="+e.widget); //$NON-NLS-1$
271
System.out.println(sb);
272             }
273
274             private String JavaDoc hex(int i) {
275                 return "[0x" + Integer.toHexString(i) + ']'; //$NON-NLS-1$
276
}
277         };
278         getControl().addListener(SWT.Traverse, fControlListener);
279         getControl().addListener(SWT.KeyDown, fControlListener);
280
281         if (DEBUG)
282             System.out.println("AbstractControlContentAssistSubjectAdapter#installControlListener() - installed"); //$NON-NLS-1$
283
}
284
285     /**
286      * Uninstalls <code>fControlListener</code> iff there are no <code>KeyListener</code>s and no
287      * <code>VerifyKeyListener</code>s registered.
288      * Otherwise does nothing.
289      */

290     private void uninstallControlListener() {
291         if (fControlListener == null || fKeyListeners.size() + fVerifyKeyListeners.size() != 0) {
292
293             if (DEBUG)
294                 System.out.println("AbstractControlContentAssistSubjectAdapter#uninstallControlListener() -> k: " + fKeyListeners.size() + ", v: " + fVerifyKeyListeners.size()); //$NON-NLS-1$ //$NON-NLS-2$
295

296             return;
297         }
298         getControl().removeListener(SWT.Traverse, fControlListener);
299         getControl().removeListener(SWT.KeyDown, fControlListener);
300         fControlListener= null;
301
302         if (DEBUG)
303             System.out.println("AbstractControlContentAssistSubjectAdapter#uninstallControlListener() - done"); //$NON-NLS-1$
304
}
305
306     /**
307      * Sets the visual feedback provider for content assist.
308      * The given {@link ILabelProvider} methods are called with
309      * {@link #getControl()} as argument.
310      *
311      * <ul>
312      * <li><code>getImage(Object)</code> provides the visual cue image.
313      * The image can maximally be 5 pixels wide and 8 pixels high.
314      * If <code>getImage(Object)</code> returns <code>null</code>, a default image is used.
315      * </li>
316      * <li><code>getText(Object)</code> provides the hover info text.
317      * It is shown when hovering over the cue image or the adapted {@link Control}.
318      * No info text is shown if <code>getText(Object)</code> returns <code>null</code>.
319      * </li>
320      * </ul>
321      * <p>
322      * The given {@link ILabelProvider} becomes owned by the {@link AbstractControlContentAssistSubjectAdapter},
323      * i.e. it gets disposed when the adapted {@link Control} is disposed
324      * or when another {@link ILabelProvider} is set.
325      * </p>
326      *
327      * @param labelProvider a {@link ILabelProvider}, or <code>null</code>
328      * if no visual feedback should be shown
329      */

330     public void setContentAssistCueProvider(final ILabelProvider labelProvider) {
331         if (fCueLabelProvider != null) {
332             fCueLabelProvider.dispose();
333         }
334         
335         fCueLabelProvider= labelProvider;
336         
337         if (labelProvider == null) {
338             if (fControlDecoration != null) {
339                 fControlDecoration.dispose();
340                 fControlDecoration= null;
341             }
342             
343         } else {
344             if (fControlDecoration == null) {
345                 fControlDecoration= new ControlDecoration(getControl(), (SWT.TOP | SWT.LEFT));
346                 getControl().addDisposeListener(new DisposeListener() {
347                     public void widgetDisposed(DisposeEvent e) {
348                         if (fCueLabelProvider != null) {
349                             fCueLabelProvider.dispose();
350                             fCueLabelProvider= null;
351                         }
352                         if (fControlDecoration != null) {
353                             fControlDecoration.dispose();
354                             fControlDecoration= null;
355                         }
356                         if (fCachedDefaultCueImage != null) {
357                             fCachedDefaultCueImage.dispose();
358                             fCachedDefaultCueImage= null;
359                         }
360                     }
361                 });
362                 fControlDecoration.setShowHover(true);
363                 fControlDecoration.setShowOnlyOnFocus(true);
364             }
365             
366             ILabelProviderListener listener= new ILabelProviderListener() {
367                 public void labelProviderChanged(LabelProviderChangedEvent event) {
368                     fControlDecoration.setDescriptionText(labelProvider.getText(getControl()));
369                     Image image= labelProvider.getImage(getControl());
370                     if (image == null)
371                         image= getDefaultCueImage();
372                     fControlDecoration.setImage(image);
373                 }
374             };
375             labelProvider.addListener(listener);
376             //initialize control decoration:
377
listener.labelProviderChanged(new LabelProviderChangedEvent(labelProvider));
378         }
379     }
380     
381     /**
382      * Returns the default cue image.
383      *
384      * @return the default cue image
385      * @since 3.3
386      */

387     private Image getDefaultCueImage() {
388         if (fCachedDefaultCueImage == null) {
389             ImageDescriptor cueID= ImageDescriptor.createFromFile(AbstractControlContentAssistSubjectAdapter.class, "images/content_assist_cue.gif"); //$NON-NLS-1$
390
fCachedDefaultCueImage= cueID.createImage(getControl().getDisplay());
391         }
392         return fCachedDefaultCueImage;
393     }
394 }
395
Popular Tags