KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > PaintManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.text;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.swt.custom.StyledText;
19 import org.eclipse.swt.events.KeyEvent;
20 import org.eclipse.swt.events.KeyListener;
21 import org.eclipse.swt.events.MouseEvent;
22 import org.eclipse.swt.events.MouseListener;
23 import org.eclipse.swt.widgets.Control;
24
25 import org.eclipse.jface.viewers.ISelectionChangedListener;
26 import org.eclipse.jface.viewers.ISelectionProvider;
27 import org.eclipse.jface.viewers.SelectionChangedEvent;
28
29
30 /**
31  * Manages the {@link org.eclipse.jface.text.IPainter} object registered with an
32  * {@link org.eclipse.jface.text.ITextViewer}.
33  * <p>
34  * Clients usually instantiate and configure objects of this type.</p>
35  *
36  * @since 2.1
37  */

38 public final class PaintManager implements KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener {
39
40     /**
41      * Position updater used by the position manager. This position updater differs from the default position
42      * updater in that it extends a position when an insertion happens at the position's offset and right behind
43      * the position.
44      */

45     static class PaintPositionUpdater extends DefaultPositionUpdater {
46
47         /**
48          * Creates the position updater for the given category.
49          *
50          * @param category the position category
51          */

52         protected PaintPositionUpdater(String JavaDoc category) {
53             super(category);
54         }
55
56         /**
57          * If an insertion happens at a position's offset, the
58          * position is extended rather than shifted. Also, if something is added
59          * right behind the end of the position, the position is extended rather
60          * than kept stable.
61          */

62         protected void adaptToInsert() {
63
64             int myStart= fPosition.offset;
65             int myEnd= fPosition.offset + fPosition.length;
66             myEnd= Math.max(myStart, myEnd);
67
68             int yoursStart= fOffset;
69             int yoursEnd= fOffset + fReplaceLength;// - 1;
70
yoursEnd= Math.max(yoursStart, yoursEnd);
71
72             if (myEnd < yoursStart)
73                 return;
74
75             if (myStart <= yoursStart)
76                 fPosition.length += fReplaceLength;
77             else
78                 fPosition.offset += fReplaceLength;
79         }
80     }
81
82     /**
83      * The paint position manager used by this paint manager. The paint position
84      * manager is installed on a single document and control the creation/disposed
85      * and updating of a position category that will be used for managing positions.
86      */

87     static class PositionManager implements IPaintPositionManager {
88
89 // /** The document this position manager works on */
90
private IDocument fDocument;
91         /** The position updater used for the managing position category */
92         private IPositionUpdater fPositionUpdater;
93         /** The managing position category */
94         private String JavaDoc fCategory;
95
96         /**
97          * Creates a new position manager. Initializes the managing
98          * position category using its class name and its hash value.
99          */

100         public PositionManager() {
101             fCategory= getClass().getName() + hashCode();
102             fPositionUpdater= new PaintPositionUpdater(fCategory);
103         }
104
105         /**
106          * Installs this position manager in the given document. The position manager stays
107          * active until <code>uninstall</code> or <code>dispose</code>
108          * is called.
109          *
110          * @param document the document to be installed on
111          */

112         public void install(IDocument document) {
113             fDocument= document;
114             fDocument.addPositionCategory(fCategory);
115             fDocument.addPositionUpdater(fPositionUpdater);
116         }
117
118         /**
119          * Disposes this position manager. The position manager is automatically
120          * removed from the document it has previously been installed
121          * on.
122          */

123         public void dispose() {
124             uninstall(fDocument);
125         }
126
127         /**
128          * Uninstalls this position manager form the given document. If the position
129          * manager has no been installed on this document, this method is without effect.
130          *
131          * @param document the document form which to uninstall
132          */

133         public void uninstall(IDocument document) {
134             if (document == fDocument && document != null) {
135                 try {
136                     fDocument.removePositionUpdater(fPositionUpdater);
137                     fDocument.removePositionCategory(fCategory);
138                 } catch (BadPositionCategoryException x) {
139                     // should not happen
140
}
141                 fDocument= null;
142             }
143         }
144
145         /*
146          * @see IPositionManager#addManagedPosition(Position)
147          */

148         public void managePosition(Position position) {
149             try {
150                 fDocument.addPosition(fCategory, position);
151             } catch (BadPositionCategoryException x) {
152                 // should not happen
153
} catch (BadLocationException x) {
154                 // should not happen
155
}
156         }
157
158         /*
159          * @see IPositionManager#removeManagedPosition(Position)
160          */

161         public void unmanagePosition(Position position) {
162             try {
163                 fDocument.removePosition(fCategory, position);
164             } catch (BadPositionCategoryException x) {
165                 // should not happen
166
}
167         }
168     }
169
170
171     /** The painters managed by this paint manager. */
172     private List JavaDoc fPainters= new ArrayList JavaDoc(2);
173     /** The position manager used by this paint manager */
174     private PositionManager fManager;
175     /** The associated text viewer */
176     private ITextViewer fTextViewer;
177
178     /**
179      * Creates a new paint manager for the given text viewer.
180      *
181      * @param textViewer the text viewer associated to this newly created paint manager
182      */

183     public PaintManager(ITextViewer textViewer) {
184         fTextViewer= textViewer;
185     }
186
187
188     /**
189      * Adds the given painter to the list of painters managed by this paint manager.
190      * If the painter is already registered with this paint manager, this method is
191      * without effect.
192      *
193      * @param painter the painter to be added
194      */

195     public void addPainter(IPainter painter) {
196         if (!fPainters.contains(painter)) {
197             fPainters.add(painter);
198             if (fPainters.size() == 1)
199                 install();
200             painter.setPositionManager(fManager);
201             painter.paint(IPainter.INTERNAL);
202         }
203     }
204
205     /**
206      * Removes the given painter from the list of painters managed by this
207      * paint manager. If the painter has not previously been added to this
208      * paint manager, this method is without effect.
209      *
210      * @param painter the painter to be removed
211      */

212     public void removePainter(IPainter painter) {
213         if (fPainters.remove(painter)) {
214             painter.deactivate(true);
215             painter.setPositionManager(null);
216         }
217         if (fPainters.size() == 0)
218             dispose();
219     }
220
221     /**
222      * Installs/activates this paint manager. Is called as soon as the
223      * first painter is to be managed by this paint manager.
224      */

225     private void install() {
226
227         fManager= new PositionManager();
228         if (fTextViewer.getDocument() != null)
229             fManager.install(fTextViewer.getDocument());
230
231         fTextViewer.addTextInputListener(this);
232
233         addListeners();
234     }
235
236     /**
237      * Installs our listener set on the text viewer and the text widget,
238      * respectively.
239      */

240     private void addListeners() {
241         ISelectionProvider provider= fTextViewer.getSelectionProvider();
242         provider.addSelectionChangedListener(this);
243
244         fTextViewer.addTextListener(this);
245
246         StyledText text= fTextViewer.getTextWidget();
247         text.addKeyListener(this);
248         text.addMouseListener(this);
249     }
250
251     /**
252      * Disposes this paint manager. The paint manager uninstalls itself
253      * and clears all registered painters. This method is also called when the
254      * last painter is removed from the list of managed painters.
255      */

256     public void dispose() {
257
258         if (fManager != null) {
259             fManager.dispose();
260             fManager= null;
261         }
262
263         for (Iterator JavaDoc e = fPainters.iterator(); e.hasNext();)
264             ((IPainter) e.next()).dispose();
265         fPainters.clear();
266
267         fTextViewer.removeTextInputListener(this);
268
269         removeListeners();
270     }
271
272     /**
273      * Removes our set of listeners from the text viewer and widget,
274      * respectively.
275      */

276     private void removeListeners() {
277         ISelectionProvider provider= fTextViewer.getSelectionProvider();
278         if (provider != null)
279             provider.removeSelectionChangedListener(this);
280
281         fTextViewer.removeTextListener(this);
282
283         StyledText text= fTextViewer.getTextWidget();
284         if (text != null && !text.isDisposed()) {
285             text.removeKeyListener(this);
286             text.removeMouseListener(this);
287         }
288     }
289
290     /**
291      * Triggers all registered painters for the given reason.
292      *
293      * @param reason the reason
294      * @see IPainter
295      */

296     private void paint(int reason) {
297         for (Iterator JavaDoc e = fPainters.iterator(); e.hasNext();)
298             ((IPainter) e.next()).paint(reason);
299     }
300
301     /*
302      * @see KeyListener#keyPressed(KeyEvent)
303      */

304     public void keyPressed(KeyEvent e) {
305         paint(IPainter.KEY_STROKE);
306     }
307
308     /*
309      * @see KeyListener#keyReleased(KeyEvent)
310      */

311     public void keyReleased(KeyEvent e) {
312     }
313
314     /*
315      * @see MouseListener#mouseDoubleClick(MouseEvent)
316      */

317     public void mouseDoubleClick(MouseEvent e) {
318     }
319
320     /*
321      * @see MouseListener#mouseDown(MouseEvent)
322      */

323     public void mouseDown(MouseEvent e) {
324         paint(IPainter.MOUSE_BUTTON);
325     }
326
327     /*
328      * @see MouseListener#mouseUp(MouseEvent)
329      */

330     public void mouseUp(MouseEvent e) {
331     }
332
333     /*
334      * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
335      */

336     public void selectionChanged(SelectionChangedEvent event) {
337         paint(IPainter.SELECTION);
338     }
339
340     /*
341      * @see ITextListener#textChanged(TextEvent)
342      */

343     public void textChanged(TextEvent event) {
344
345         if (!event.getViewerRedrawState())
346             return;
347
348         Control control= fTextViewer.getTextWidget();
349         if (control != null) {
350             control.getDisplay().asyncExec(new Runnable JavaDoc() {
351                 public void run() {
352                     if (fTextViewer != null)
353                         paint(IPainter.TEXT_CHANGE);
354                 }
355             });
356         }
357     }
358
359     /*
360      * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
361      */

362     public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
363         if (oldInput != null) {
364             for (Iterator JavaDoc e = fPainters.iterator(); e.hasNext();)
365                 ((IPainter) e.next()).deactivate(false);
366             fManager.uninstall(oldInput);
367             removeListeners();
368         }
369     }
370
371     /*
372      * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
373      */

374     public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
375         if (newInput != null) {
376             fManager.install(newInput);
377             paint(IPainter.TEXT_CHANGE);
378             addListeners();
379         }
380     }
381 }
382
383
Popular Tags