KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > text > QuietEditorPane


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.openide.text;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.Container JavaDoc;
24 import java.awt.Font JavaDoc;
25 import java.awt.FontMetrics JavaDoc;
26 import java.awt.Frame JavaDoc;
27 import java.awt.Rectangle JavaDoc;
28 import java.awt.datatransfer.Clipboard JavaDoc;
29 import java.awt.datatransfer.DataFlavor JavaDoc;
30 import java.awt.datatransfer.Transferable JavaDoc;
31 import java.awt.dnd.DnDConstants JavaDoc;
32 import java.awt.dnd.DropTarget JavaDoc;
33 import java.awt.dnd.DropTargetDragEvent JavaDoc;
34 import java.awt.dnd.DropTargetDropEvent JavaDoc;
35 import java.awt.dnd.DropTargetEvent JavaDoc;
36 import java.awt.dnd.DropTargetListener JavaDoc;
37 import java.awt.event.InputEvent JavaDoc;
38 import java.util.TooManyListenersException JavaDoc;
39 import javax.swing.Icon JavaDoc;
40 import javax.swing.JComponent JavaDoc;
41 import javax.swing.JEditorPane JavaDoc;
42 import javax.swing.SwingConstants JavaDoc;
43 import javax.swing.SwingUtilities JavaDoc;
44 import javax.swing.TransferHandler JavaDoc;
45 import javax.swing.plaf.UIResource JavaDoc;
46 import javax.swing.text.Caret JavaDoc;
47 import javax.swing.text.Document JavaDoc;
48 import javax.swing.text.JTextComponent JavaDoc;
49 import org.openide.util.Lookup;
50 import org.openide.windows.ExternalDropHandler;
51 import org.openide.windows.TopComponent;
52
53 /** performance trick - 18% of time saved during open of an editor
54 *
55 * @author Ales Novak
56 */

57 final class QuietEditorPane extends JEditorPane JavaDoc {
58     
59     static DataFlavor JavaDoc constructActiveEditorDropFlavor() {
60         try {
61             return new DataFlavor JavaDoc("text/active_editor_flavor;class=org.openide.text.ActiveEditorDrop", // NOI18N
62
"Active Editor Flavor", // XXX missing I18N!
63
QuietEditorPane.class.getClassLoader());
64         } catch (ClassNotFoundException JavaDoc e) {
65             throw new AssertionError JavaDoc(e);
66         }
67     }
68     
69     final static int FIRE = 0x1;
70     final static int PAINT = 0x2;
71     final static int ALL = FIRE | PAINT;
72
73     // #21120. Caret was null while serializing CloneableEditor.
74

75     /** Saves last position of caret when, doing it's UI reinstallation. */
76     private int lastPosition = -1;
77
78     /** is firing of events enabled? */
79     int working = FIRE; // [Mila] firing since begining, otherwise doesn't work well
80

81     /** determines scroll unit */
82     private int fontHeight;
83     private int charWidth;
84
85     /**
86      * consturctor sets the initial values for horizontal
87      * and vertical scroll units.
88      * also listenes for font changes.
89      */

90     public QuietEditorPane() {
91         setFontHeightWidth(getFont());
92     }
93     
94     public void setFont(Font JavaDoc font) {
95         super.setFont(font);
96         setFontHeightWidth(getFont());
97     }
98
99
100     private void setFontHeightWidth(Font JavaDoc font) {
101         FontMetrics JavaDoc metrics=getFontMetrics(font);
102         fontHeight=metrics.getHeight();
103         charWidth=metrics.charWidth('m');
104     }
105
106     /**
107      * fix for #38139.
108      * returns height of a line for vertical scroll unit
109      * or width of a widest char for a horizontal scroll unit
110      */

111     public int getScrollableUnitIncrement(Rectangle JavaDoc visibleRect, int orientation, int direction) {
112         switch (orientation) {
113             case SwingConstants.VERTICAL:
114                 return fontHeight;
115             case SwingConstants.HORIZONTAL:
116                 return charWidth;
117             default:
118                 throw new IllegalArgumentException JavaDoc("Invalid orientation: " +orientation);
119         }
120     }
121     
122     public void setDocument(Document JavaDoc doc) {
123         super.setDocument(doc);
124         
125         // Setting DelegatingTransferHandler, where CallbackTransferable will
126
// be handled in importData method.
127
// For more details, please refer issue #53439
128
if (doc != null){
129             TransferHandler JavaDoc thn = getTransferHandler();
130             if( !(thn instanceof DelegatingTransferHandler) ) {
131                 DelegatingTransferHandler dth = new DelegatingTransferHandler(thn);
132                 setTransferHandler(dth);
133             }
134
135             DropTarget JavaDoc currDt = getDropTarget();
136             if( !(currDt instanceof DelegatingDropTarget ) ) {
137                 DropTarget JavaDoc dt = new DelegatingDropTarget( currDt );
138                 setDropTarget( dt );
139             }
140         }
141     }
142     
143     public void setWorking(int x) {
144         working = x;
145     }
146
147     public void firePropertyChange(String JavaDoc s, Object JavaDoc val1, Object JavaDoc val2) {
148         if ((working & FIRE) != 0) {
149             super.firePropertyChange(s, val1, val2);
150         }
151     }
152
153     /** Overrides superclass method, to keep old caret position.
154      * While is reinstallation of UI in progress, there
155      * is a gap between the uninstallUI
156      * and intstallUI when caret set to <code>null</code>. */

157     public void setCaret(Caret JavaDoc caret) {
158         if (caret == null) {
159             Caret JavaDoc oldCaret = getCaret();
160
161             if (oldCaret != null) {
162                 lastPosition = oldCaret.getDot();
163             }
164         }
165
166         super.setCaret(caret);
167     }
168
169     /** Gets the last caret position, for the case the serialization
170      * is done during the time of pane UI reinstallation. */

171     int getLastPosition() {
172         return lastPosition;
173     }
174
175     /*
176     public void setDocument(Document doc) {
177       if (working) {
178         super.setDocument(doc);
179       }
180     }
181
182     public void setUI(javax.swing.plaf.TextUI ui) {
183       if (working) {
184         super.setUI(ui);
185       }
186     }*/

187     public void revalidate() {
188         if ((working & PAINT) != 0) {
189             super.revalidate();
190         }
191     }
192
193     public void repaint() {
194         if ((working & PAINT) != 0) {
195             super.repaint();
196         }
197     }
198
199     /**
200      * Delegating TransferHandler.
201      * The main purpose is hooking on importData method where CallbackTransferable
202      * is handled. For more details, please refer issue #53439
203      */

204     private class DelegatingTransferHandler extends TransferHandler JavaDoc{
205         
206         TransferHandler JavaDoc delegator;
207         
208         public DelegatingTransferHandler(TransferHandler JavaDoc delegator){
209             this.delegator = delegator;
210         }
211         
212         public void exportAsDrag(JComponent JavaDoc comp, InputEvent JavaDoc e, int action) {
213             delegator.exportAsDrag(comp, e, action);
214         }
215
216         public void exportToClipboard(JComponent JavaDoc comp, Clipboard JavaDoc clip, int action) {
217             delegator.exportToClipboard(comp, clip, action);
218         }
219
220         public boolean importData(JComponent JavaDoc comp, Transferable JavaDoc t) {
221             try {
222                 if (t.isDataFlavorSupported(ActiveEditorDrop.FLAVOR)){
223                     Object JavaDoc obj = t.getTransferData(ActiveEditorDrop.FLAVOR);
224                     if (obj instanceof ActiveEditorDrop && comp instanceof JTextComponent JavaDoc){
225                         boolean success = false;
226                         try {
227                             success = ((ActiveEditorDrop)obj).handleTransfer((JTextComponent JavaDoc)comp);
228                         }
229                         finally {
230                             requestFocus(comp);
231                         }
232                         return success;
233                     }
234                 }
235             } catch (Exception JavaDoc exc){
236                 exc.printStackTrace();
237             }
238             return delegator.importData(comp, t);
239         }
240
241         private void requestFocus(JComponent JavaDoc comp) {
242             Container JavaDoc container = SwingUtilities.getAncestorOfClass(TopComponent.class, comp);
243             if (container != null) {
244                 ((TopComponent)container).requestActive();
245             }
246             else {
247                 Component JavaDoc f = comp;
248                 do {
249                     f = f.getParent();
250                     if (f instanceof Frame JavaDoc) {
251                         break;
252                     }
253                 } while (f != null);
254                 if (f != null) {
255                     f.requestFocus();
256                 }
257                 comp.requestFocus();
258             }
259         }
260         
261         public boolean canImport(JComponent JavaDoc comp, DataFlavor JavaDoc[] transferFlavors) {
262             for (int i=0; i<transferFlavors.length; i++){
263                 if (transferFlavors[i] == ActiveEditorDrop.FLAVOR){
264                     return true;
265                 }
266             }
267             return delegator.canImport(comp, transferFlavors);
268         }
269
270         public int getSourceActions(JComponent JavaDoc c) {
271             return delegator.getSourceActions(c);
272         }
273
274         public Icon JavaDoc getVisualRepresentation(Transferable JavaDoc t) {
275             return delegator.getVisualRepresentation(t);
276         }
277
278         protected void exportDone(JComponent JavaDoc source, Transferable JavaDoc data, int action) {
279             try {
280                 java.lang.reflect.Method JavaDoc method = delegator.getClass().getDeclaredMethod(
281                     "exportDone", // NOI18N
282
new Class JavaDoc[] {javax.swing.JComponent JavaDoc.class, Transferable JavaDoc.class, int.class});
283                 method.setAccessible(true);
284                 method.invoke(delegator, new Object JavaDoc[] {source, data, new Integer JavaDoc(action)});
285             } catch (NoSuchMethodException JavaDoc ex) {
286                 ex.printStackTrace();
287             } catch (IllegalAccessException JavaDoc ex) {
288                 ex.printStackTrace();
289             } catch (java.lang.reflect.InvocationTargetException JavaDoc ex) {
290                 ex.printStackTrace();
291             }
292         }
293         
294         protected Transferable JavaDoc createTransferable(JComponent JavaDoc comp) {
295             try {
296                 java.lang.reflect.Method JavaDoc method = delegator.getClass().getDeclaredMethod(
297                     "createTransferable", // NOI18N
298
new Class JavaDoc[] {javax.swing.JComponent JavaDoc.class});
299                 method.setAccessible(true);
300                 return (Transferable JavaDoc)method.invoke(delegator, new Object JavaDoc[] {comp});
301             } catch (NoSuchMethodException JavaDoc ex) {
302                 ex.printStackTrace();
303             } catch (IllegalAccessException JavaDoc ex) {
304                 ex.printStackTrace();
305             } catch (java.lang.reflect.InvocationTargetException JavaDoc ex) {
306                 ex.printStackTrace();
307             }
308             return null;
309     }
310     }
311     
312     private class DelegatingDropTarget extends DropTarget JavaDoc implements UIResource JavaDoc {
313         private DropTarget JavaDoc orig;
314         private boolean isDragging = false;
315
316         public DelegatingDropTarget( DropTarget JavaDoc orig ) {
317             this.orig = orig;
318         }
319         public void addDropTargetListener(DropTargetListener JavaDoc dtl) throws TooManyListenersException JavaDoc {
320             orig.addDropTargetListener( dtl );
321         }
322
323         public void removeDropTargetListener(DropTargetListener JavaDoc dtl) {
324             orig.removeDropTargetListener( dtl );
325         }
326
327         public void dragEnter(DropTargetDragEvent JavaDoc dtde) {
328             ExternalDropHandler handler = (ExternalDropHandler)Lookup.getDefault().lookup( ExternalDropHandler.class );
329             if( null != handler && handler.canDrop( dtde ) ) {
330                 dtde.acceptDrag( DnDConstants.ACTION_COPY );
331                 isDragging = false;
332             } else {
333                 orig.dragEnter( dtde );
334                 isDragging = true;
335             }
336         }
337
338         public void dragExit(DropTargetEvent JavaDoc dte) {
339             if( isDragging ) {
340                 orig.dragExit( dte );
341             }
342             isDragging = false;
343         }
344
345         public void dragOver(DropTargetDragEvent JavaDoc dtde) {
346             ExternalDropHandler handler = (ExternalDropHandler)Lookup.getDefault().lookup( ExternalDropHandler.class );
347             if( null != handler && handler.canDrop( dtde ) ) {
348                 dtde.acceptDrag( DnDConstants.ACTION_COPY );
349                 isDragging = false;
350             } else {
351                 orig.dragOver( dtde );
352                 isDragging = true;
353             }
354         }
355
356         public void drop(DropTargetDropEvent JavaDoc e) {
357             ExternalDropHandler handler = (ExternalDropHandler)Lookup.getDefault().lookup( ExternalDropHandler.class );
358             if( handler.canDrop( e ) ) {
359                 e.acceptDrop( DnDConstants.ACTION_COPY );
360
361                 e.dropComplete( handler.handleDrop( e ) );
362             } else {
363                 orig.drop( e );
364             }
365             isDragging = false;
366         }
367
368         public void dropActionChanged(DropTargetDragEvent JavaDoc dtde) {
369             if( isDragging )
370                 orig.dropActionChanged( dtde );
371         }
372     }
373 }
374
Popular Tags