JAL-1807 includes ?j2sdebug flag and DebugJS._(msg)
[jalviewjs.git] / site / j2s / swingjs / plaf / JSTextUI.java
1 /*\r
2  * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.\r
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\r
4  *\r
5  * This code is free software; you can redistribute it and/or modify it\r
6  * under the terms of the GNU General Public License version 2 only, as\r
7  * published by the Free Software Foundation.  Oracle designates this\r
8  * particular file as subject to the "Classpath" exception as provided\r
9  * by Oracle in the LICENSE file that accompanied this code.\r
10  *\r
11  * This code is distributed in the hope that it will be useful, but WITHOUT\r
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
14  * version 2 for more details (a copy is included in the LICENSE file that\r
15  * accompanied this code).\r
16  *\r
17  * You should have received a copy of the GNU General Public License version\r
18  * 2 along with this work; if not, write to the Free Software Foundation,\r
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\r
22  * or visit www.oracle.com if you need additional information or have any\r
23  * questions.\r
24  */\r
25 package swingjs.plaf;\r
26 \r
27 import swingjs.JSToolkit;\r
28 import swingjs.api.DOMNode;\r
29 import swingjs.api.JQueryObject;\r
30 import swingjs.api.JSFunction;\r
31 import jsjava.awt.Dimension;\r
32 import jsjava.awt.Insets;\r
33 import jsjava.awt.LayoutManager;\r
34 import jsjava.awt.event.ActionEvent;\r
35 import jsjavax.swing.AbstractAction;\r
36 import jsjavax.swing.Action;\r
37 import jsjavax.swing.ActionMap;\r
38 import jsjavax.swing.InputMap;\r
39 import jsjavax.swing.JComponent;\r
40 import jsjavax.swing.SwingUtilities;\r
41 import jsjavax.swing.UIManager;\r
42 import jsjavax.swing.plaf.ActionMapUIResource;\r
43 import jsjavax.swing.plaf.ComponentUI;\r
44 import jsjavax.swing.plaf.InputMapUIResource;\r
45 import jsjavax.swing.plaf.TextUI;\r
46 import jsjavax.swing.plaf.UIResource;\r
47 import jsjavax.swing.text.Caret;\r
48 import jsjavax.swing.text.DefaultEditorKit;\r
49 import jsjavax.swing.text.EditorKit;\r
50 import jsjavax.swing.text.JTextComponent;\r
51 import jsjavax.swing.text.TextAction;\r
52 //import jsjava.awt.KeyboardFocusManager;\r
53 //import jsjava.awt.datatransfer.DataFlavor;\r
54 //import jsjava.awt.datatransfer.Transferable;\r
55 //import jsjava.awt.datatransfer.UnsupportedFlavorException;\r
56 //import jsjava.awt.im.InputContext;\r
57 //import jsjava.io.IOException;\r
58 //import jsjava.io.InputStream;\r
59 //import jsjava.io.Reader;\r
60 //import jsjava.io.StringBufferInputStream;\r
61 //import jsjava.io.StringReader;\r
62 //import jsjava.io.StringWriter;\r
63 //import jsjavax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag;\r
64 \r
65 /**\r
66  * <p>\r
67  * Basis of a text components look-and-feel. This provides the basic editor view\r
68  * and controller services that may be useful when creating a look-and-feel for\r
69  * an extension of <code>JTextComponent</code>.\r
70  * <p>\r
71  * Most state is held in the associated <code>JTextComponent</code> as bound\r
72  * properties, and the UI installs default values for the various properties.\r
73  * This default will install something for all of the properties. Typically, a\r
74  * LAF implementation will do more however. At a minimum, a LAF would generally\r
75  * install key bindings.\r
76  * <p>\r
77  * This class also provides some concurrency support if the\r
78  * <code>Document</code> associated with the JTextComponent is a subclass of\r
79  * <code>AbstractDocument</code>. Access to the View (or View hierarchy) is\r
80  * serialized between any thread mutating the model and the Swing event thread\r
81  * (which is expected to render, do model/view coordinate translation, etc).\r
82  * <em>Any access to the root view should first\r
83  * acquire a read-lock on the AbstractDocument and release that lock\r
84  * in a finally block.</em>\r
85  * <p>\r
86  * An important method to define is the {@link #getPropertyPrefix} method which\r
87  * is used as the basis of the keys used to fetch defaults from the UIManager.\r
88  * The string should reflect the type of TextUI (eg. TextField, TextArea, etc)\r
89  * without the particular LAF part of the name (eg Metal, Motif, etc).\r
90  * <p>\r
91  * To build a view of the model, one of the following strategies can be\r
92  * employed.\r
93  * <ol>\r
94  * <li>\r
95  * One strategy is to simply redefine the ViewFactory interface in the UI. By\r
96  * default, this UI itself acts as the factory for View implementations. This is\r
97  * useful for simple factories. To do this reimplement the {@link #create}\r
98  * method.\r
99  * <li>\r
100  * A common strategy for creating more complex types of documents is to have the\r
101  * EditorKit implementation return a factory. Since the EditorKit ties all of\r
102  * the pieces necessary to maintain a type of document, the factory is typically\r
103  * an important part of that and should be produced by the EditorKit\r
104  * implementation.\r
105  * </ol>\r
106  * <p>\r
107  * <strong>Warning:</strong> Serialized objects of this class will not be\r
108  * compatible with future Swing releases. The current serialization support is\r
109  * appropriate for short term storage or RMI between applications running the\r
110  * same version of Swing. As of 1.4, support for long term storage of all\r
111  * JavaBeans<sup><font size="-2">TM</font></sup> has been added to the\r
112  * <code>java.beans</code> package. Please see {@link jsjava.beans.XMLEncoder}.\r
113  * \r
114  * @author Timothy Prinzing\r
115  * @author Shannon Hickey (drag and drop)\r
116  */\r
117 public abstract class JSTextUI extends JSComponentUI {// implements {ViewFactory\r
118                                                                                                                                                                                                                         // {\r
119         @SuppressWarnings("unused")\r
120         protected void setFocusable() {\r
121                 JQueryObject node = $(focusNode);\r
122                 Object me = this;\r
123 \r
124                 /**\r
125                  * @j2sNative\r
126                  * \r
127                  * node.focus(function() {me.notifyFocus(true)});\r
128                  * node.blur(function() {me.notifyFocus(false)});\r
129                  */\r
130                 {}\r
131         }\r
132         \r
133 \r
134         protected String getComponentText() {\r
135                 return currentText = ((JTextComponent) c).getText();\r
136         }\r
137 \r
138         protected void bindKeys(DOMNode domNode) {\r
139                 JSFunction f = null;\r
140                 JSEventHandler me = this;\r
141                 if (!((JTextComponent) c).isEditable())\r
142                         return;\r
143                 /**\r
144                  * @j2sNative\r
145                  * \r
146                  *            f = function(event) { me.handleJSEvent(me.domNode, 401, event)\r
147                  *            }\r
148                  */\r
149                 {\r
150                         System.out.println(me);\r
151                 }\r
152                 $(domNode).bind("keydown keypress keyup", f);\r
153 \r
154                 // TODO Auto-generated method stub\r
155 \r
156         }\r
157 \r
158         /**\r
159          * Initializes component properties, e.g. font, foreground, background, caret\r
160          * color, selection color, selected text color, disabled text color, and\r
161          * border color. The font, foreground, and background properties are only set\r
162          * if their current value is either null or a UIResource, other properties are\r
163          * set if the current value is null.\r
164          * \r
165          * @see #uninstallDefaults\r
166          * @see #installUI\r
167          */\r
168         protected void installDefaults() {\r
169                 // String prefix = getPropertyPrefix();\r
170                 // Font f = editor.getFont();\r
171                 // if ((f == null) || (f instanceof UIResource)) {\r
172                 // editor.setFont(UIManager.getFont(prefix + ".font"));\r
173                 // }\r
174                 //\r
175                 // Color bg = editor.getBackground();\r
176                 // if ((bg == null) || (bg instanceof UIResource)) {\r
177                 // editor.setBackground(UIManager.getColor(prefix + ".background"));\r
178                 // }\r
179                 //\r
180                 // Color fg = editor.getForeground();\r
181                 // if ((fg == null) || (fg instanceof UIResource)) {\r
182                 // editor.setForeground(UIManager.getColor(prefix + ".foreground"));\r
183                 // }\r
184                 //\r
185                 // Color color = editor.getCaretColor();\r
186                 // if ((color == null) || (color instanceof UIResource)) {\r
187                 // editor.setCaretColor(UIManager.getColor(prefix + ".caretForeground"));\r
188                 // }\r
189                 //\r
190                 // Color s = editor.getSelectionColor();\r
191                 // if ((s == null) || (s instanceof UIResource)) {\r
192                 // editor.setSelectionColor(UIManager.getColor(prefix +\r
193                 // ".selectionBackground"));\r
194                 // }\r
195                 //\r
196                 // Color sfg = editor.getSelectedTextColor();\r
197                 // if ((sfg == null) || (sfg instanceof UIResource)) {\r
198                 // editor.setSelectedTextColor(UIManager.getColor(prefix +\r
199                 // ".selectionForeground"));\r
200                 // }\r
201                 //\r
202                 // Color dfg = editor.getDisabledTextColor();\r
203                 // if ((dfg == null) || (dfg instanceof UIResource)) {\r
204                 // editor.setDisabledTextColor(UIManager.getColor(prefix +\r
205                 // ".inactiveForeground"));\r
206                 // }\r
207                 //\r
208                 // Border b = editor.getBorder();\r
209                 // if ((b == null) || (b instanceof UIResource)) {\r
210                 // editor.setBorder(UIManager.getBorder(prefix + ".border"));\r
211                 // }\r
212                 //\r
213                 // Insets margin = editor.getMargin();\r
214                 // if (margin == null || margin instanceof UIResource) {\r
215                 // editor.setMargin(UIManager.getInsets(prefix + ".margin"));\r
216                 // }\r
217                 //\r
218                 // updateCursor();\r
219         }\r
220 \r
221         private void installDefaults2() {\r
222                 // editor.addMouseListener(dragListener);\r
223                 // editor.addMouseMotionListener(dragListener);\r
224                 //\r
225                 // String prefix = getPropertyPrefix();\r
226 \r
227                 Caret caret = editor.getCaret();\r
228                 if (caret == null || caret instanceof UIResource) {\r
229                         editor.setCaret(new JSCaret());\r
230                 }\r
231                 //\r
232                 // Highlighter highlighter = editor.getHighlighter();\r
233                 // if (highlighter == null || highlighter instanceof UIResource) {\r
234                 // editor.setHighlighter(createHighlighter());\r
235                 // }\r
236                 //\r
237                 // TransferHandler th = editor.getTransferHandler();\r
238                 // if (th == null || th instanceof UIResource) {\r
239                 // editor.setTransferHandler(getTransferHandler());\r
240                 // }\r
241         }\r
242 \r
243         /**\r
244          * called by JmolCore.js\r
245          * \r
246          * @return handled\r
247          */\r
248         public boolean handleJSEvent(Object target, int eventType, Object jQueryEvent) {\r
249                 System.out.println("Handling for " + id + " " + eventType + " "\r
250                                 + jQueryEvent);\r
251                 return updateHandler.handleJSEvent(this, eventType, jQueryEvent);\r
252         }\r
253 \r
254         /**\r
255          * Sets the component properties that haven't been explicitly overridden to\r
256          * null. A property is considered overridden if its current value is not a\r
257          * UIResource.\r
258          * \r
259          * @see #installDefaults\r
260          * @see #uninstallUI\r
261          */\r
262         protected void uninstallDefaults() {\r
263                 // editor.removeMouseListener(dragListener);\r
264                 // editor.removeMouseMotionListener(dragListener);\r
265                 //\r
266                 if (editor.getCaretColor() instanceof UIResource) {\r
267                         editor.setCaretColor(null);\r
268                 }\r
269 \r
270                 if (editor.getSelectionColor() instanceof UIResource) {\r
271                         editor.setSelectionColor(null);\r
272                 }\r
273 \r
274                 if (editor.getDisabledTextColor() instanceof UIResource) {\r
275                         editor.setDisabledTextColor(null);\r
276                 }\r
277 \r
278                 if (editor.getSelectedTextColor() instanceof UIResource) {\r
279                         editor.setSelectedTextColor(null);\r
280                 }\r
281 \r
282                 if (editor.getBorder() instanceof UIResource) {\r
283                         editor.setBorder(null);\r
284                 }\r
285 \r
286                 if (editor.getMargin() instanceof UIResource) {\r
287                         editor.setMargin(null);\r
288                 }\r
289 \r
290                 // if (editor.getCaret() instanceof UIResource) {\r
291                 // editor.setCaret(null);\r
292                 // }\r
293                 //\r
294                 // if (editor.getHighlighter() instanceof UIResource) {\r
295                 // editor.setHighlighter(null);\r
296                 // }\r
297                 //\r
298                 // if (editor.getTransferHandler() instanceof UIResource) {\r
299                 // editor.setTransferHandler(null);\r
300                 // }\r
301                 //\r
302                 // if (editor.getCursor() instanceof UIResource) {\r
303                 // editor.setCursor(null);\r
304                 // }\r
305         }\r
306 \r
307         protected void installKeyboardActions() {\r
308                 // backward compatibility support... keymaps for the UI\r
309                 // are now installed in the more friendly input map.\r
310                 // editor.setKeymap(createKeymap());\r
311 \r
312                 InputMap km = getInputMap();\r
313                 if (km != null) {\r
314                         SwingUtilities.replaceUIInputMap(editor, JComponent.WHEN_FOCUSED, km);\r
315                 }\r
316 \r
317                 ActionMap map = getActionMap();\r
318                 if (map != null) {\r
319                         SwingUtilities.replaceUIActionMap(editor, map);\r
320                 }\r
321 \r
322                 // updateFocusAcceleratorBinding(false);\r
323         }\r
324 \r
325         /**\r
326          * Get the InputMap to use for the UI.\r
327          */\r
328         InputMap getInputMap() {\r
329                 InputMap map = new InputMapUIResource();\r
330 \r
331                 // InputMap shared =\r
332                 // (InputMap)DefaultLookup.get(editor, this,\r
333                 // getPropertyPrefix() + ".focusInputMap");\r
334                 // if (shared != null) {\r
335                 // map.setParent(shared);\r
336                 // }\r
337                 return map;\r
338         }\r
339 \r
340         // /**\r
341         // * Invoked when the focus accelerator changes, this will update the\r
342         // * key bindings as necessary.\r
343         // */\r
344         // void updateFocusAcceleratorBinding(boolean changed) {\r
345         // char accelerator = editor.getFocusAccelerator();\r
346         //\r
347         // if (changed || accelerator != '\0') {\r
348         // InputMap km = SwingUtilities.getUIInputMap\r
349         // (editor, JComponent.WHEN_IN_FOCUSED_WINDOW);\r
350         //\r
351         // if (km == null && accelerator != '\0') {\r
352         // km = new ComponentInputMapUIResource(editor);\r
353         // SwingUtilities.replaceUIInputMap(editor, JComponent.\r
354         // WHEN_IN_FOCUSED_WINDOW, km);\r
355         // ActionMap am = getActionMap();\r
356         // SwingUtilities.replaceUIActionMap(editor, am);\r
357         // }\r
358         // if (km != null) {\r
359         // km.clear();\r
360         // if (accelerator != '\0') {\r
361         // km.put(KeyStroke.getKeyStroke(accelerator,\r
362         // ActionEvent.ALT_MASK),\r
363         // "requestFocus");\r
364         // }\r
365         // }\r
366         // }\r
367         // }\r
368         //\r
369         //\r
370         // /**\r
371         // * Invoked when editable property is changed.\r
372         // *\r
373         // * removing 'TAB' and 'SHIFT-TAB' from traversalKeysSet in case\r
374         // * editor is editable\r
375         // * adding 'TAB' and 'SHIFT-TAB' to traversalKeysSet in case\r
376         // * editor is non editable\r
377         // */\r
378         //\r
379         // void updateFocusTraversalKeys() {\r
380         // /*\r
381         // * Fix for 4514331 Non-editable JTextArea and similar\r
382         // * should allow Tab to keyboard - accessibility\r
383         // */\r
384         // EditorKit editorKit = getEditorKit(editor);\r
385         // if ( editorKit != null\r
386         // && editorKit instanceof DefaultEditorKit) {\r
387         // Set storedForwardTraversalKeys = editor.\r
388         // getFocusTraversalKeys(KeyboardFocusManager.\r
389         // FORWARD_TRAVERSAL_KEYS);\r
390         // Set storedBackwardTraversalKeys = editor.\r
391         // getFocusTraversalKeys(KeyboardFocusManager.\r
392         // BACKWARD_TRAVERSAL_KEYS);\r
393         // Set forwardTraversalKeys =\r
394         // new HashSet(storedForwardTraversalKeys);\r
395         // Set backwardTraversalKeys =\r
396         // new HashSet(storedBackwardTraversalKeys);\r
397         // if (editor.isEditable()) {\r
398         // forwardTraversalKeys.\r
399         // remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\r
400         // backwardTraversalKeys.\r
401         // remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,\r
402         // InputEvent.SHIFT_MASK));\r
403         // } else {\r
404         // forwardTraversalKeys.add(KeyStroke.\r
405         // getKeyStroke(KeyEvent.VK_TAB, 0));\r
406         // backwardTraversalKeys.\r
407         // add(KeyStroke.\r
408         // getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\r
409         // }\r
410         // LookAndFeel.installProperty(editor,\r
411         // "focusTraversalKeysForward",\r
412         // forwardTraversalKeys);\r
413         // LookAndFeel.installProperty(editor,\r
414         // "focusTraversalKeysBackward",\r
415         // backwardTraversalKeys);\r
416         // }\r
417         //\r
418         // }\r
419 \r
420         // /**\r
421         // * As needed updates cursor for the target editor.\r
422         // */\r
423         // private void updateCursor() {\r
424         // if ((! editor.isCursorSet())\r
425         // || editor.getCursor() instanceof UIResource) {\r
426         // Cursor cursor = (editor.isEditable()) ? textCursor : null;\r
427         // editor.setCursor(cursor);\r
428         // }\r
429         // }\r
430         //\r
431         // /**\r
432         // * Returns the <code>TransferHandler</code> that will be installed if\r
433         // * their isn't one installed on the <code>JTextComponent</code>.\r
434         // */\r
435         // TransferHandler getTransferHandler() {\r
436         // return defaultTransferHandler;\r
437         // }\r
438         //\r
439         /**\r
440          * Fetch an action map to use.\r
441          */\r
442         ActionMap getActionMap() {\r
443                 String mapName = classID + ".actionMap";\r
444                 ActionMap map = (ActionMap) UIManager.get(mapName);\r
445                 if (map == null) {\r
446                         map = createActionMap();\r
447                         if (map != null) {\r
448                                 UIManager.getLookAndFeelDefaults().put(mapName, map); \r
449                         }\r
450                 }\r
451                 return map;\r
452         }\r
453         // ActionMap componentMap = new ActionMapUIResource();\r
454         // componentMap.put("requestFocus", new FocusAction());\r
455         // /*\r
456         // * fix for bug 4515750\r
457         // * JTextField & non-editable JTextArea bind return key - default btn not\r
458         // accessible\r
459         // *\r
460         // * Wrap the return action so that it is only enabled when the\r
461         // * component is editable. This allows the default button to be\r
462         // * processed when the text component has focus and isn't editable.\r
463         // *\r
464         // */\r
465         // if (getEditorKit(editor) instanceof DefaultEditorKit) {\r
466         // if (map != null) {\r
467         // Object obj = map.get(DefaultEditorKit.insertBreakAction);\r
468         // if (obj != null\r
469         // && obj instanceof DefaultEditorKit.InsertBreakAction) {\r
470         // Action action = new TextActionWrapper((TextAction)obj);\r
471         // componentMap.put(action.getValue(Action.NAME),action);\r
472         // }\r
473         // }\r
474         // }\r
475         // if (map != null) {\r
476         // componentMap.setParent(map);\r
477         // }\r
478         // return componentMap;\r
479         // }\r
480         //\r
481         /**\r
482          * Create a default action map. This is basically the set of actions found\r
483          * exported by the component.\r
484          */\r
485         /**\r
486          * @return\r
487          */\r
488         ActionMap createActionMap() {\r
489                 ActionMap map = new ActionMapUIResource();\r
490                 Action[] actions = editor.getActions();//defaultKit.getActions(); // SwingJS was editor.getEditorKit().getActions()\r
491                 // System.out.println("building map for UI: " + getPropertyPrefix());\r
492                 int n = actions.length;\r
493                 for (int i = 0; i < n; i++) {\r
494                         Action a = actions[i];\r
495                         map.put(a.getValue(Action.NAME), a);\r
496                         // System.out.println("  " + a.getValue(Action.NAME));\r
497                 }\r
498                 // map.put(TransferHandler.getCutAction().getValue(Action.NAME),\r
499                 // TransferHandler.getCutAction());\r
500                 // map.put(TransferHandler.getCopyAction().getValue(Action.NAME),\r
501                 // TransferHandler.getCopyAction());\r
502                 // map.put(TransferHandler.getPasteAction().getValue(Action.NAME),\r
503                 // TransferHandler.getPasteAction());\r
504                 return map;\r
505         }\r
506 \r
507         protected void uninstallKeyboardActions() {\r
508                 editor.setKeymap(null);\r
509                 SwingUtilities.replaceUIInputMap(editor, JComponent.WHEN_IN_FOCUSED_WINDOW,\r
510                                 null);\r
511                 SwingUtilities.replaceUIActionMap(editor, null);\r
512         }\r
513 \r
514         // /**\r
515         // * Paints a background for the view. This will only be\r
516         // * called if isOpaque() on the associated component is\r
517         // * true. The default is to paint the background color\r
518         // * of the component.\r
519         // *\r
520         // * @param g the graphics context\r
521         // */\r
522         // protected void paintBackground(Graphics g) {\r
523         // g.setColor(editor.getBackground());\r
524         // g.fillRect(0, 0, editor.getWidth(), editor.getHeight());\r
525         // }\r
526         //\r
527         /**\r
528          * Fetches the text component associated with this UI implementation. This\r
529          * will be null until the ui has been installed.\r
530          * \r
531          * @return the editor component\r
532          */\r
533         protected final JTextComponent getComponent() {\r
534                 return editor;\r
535         }\r
536 \r
537         // /**\r
538         // * Flags model changes.\r
539         // * This is called whenever the model has changed.\r
540         // * It is implemented to rebuild the view hierarchy\r
541         // * to represent the default root element of the\r
542         // * associated model.\r
543         // */\r
544         // protected void modelChanged() {\r
545         // // create a view hierarchy\r
546         // ViewFactory f = rootView.getViewFactory();\r
547         // Document doc = editor.getDocument();\r
548         // Element elem = doc.getDefaultRootElement();\r
549         // setView(f.create(elem));\r
550         // }\r
551         //\r
552         // /**\r
553         // * Sets the current root of the view hierarchy and calls invalidate().\r
554         // * If there were any child components, they will be removed (i.e.\r
555         // * there are assumed to have come from components embedded in views).\r
556         // *\r
557         // * @param v the root view\r
558         // */\r
559         // protected final void setView(View v) {\r
560         // rootView.setView(v);\r
561         // painted = false;\r
562         // editor.revalidate();\r
563         // editor.repaint();\r
564         // }\r
565         //\r
566         // /**\r
567         // * Paints the interface safely with a guarantee that\r
568         // * the model won't change from the view of this thread.\r
569         // * This does the following things, rendering from\r
570         // * back to front.\r
571         // * <ol>\r
572         // * <li>\r
573         // * If the component is marked as opaque, the background\r
574         // * is painted in the current background color of the\r
575         // * component.\r
576         // * <li>\r
577         // * The highlights (if any) are painted.\r
578         // * <li>\r
579         // * The view hierarchy is painted.\r
580         // * <li>\r
581         // * The caret is painted.\r
582         // * </ol>\r
583         // *\r
584         // * @param g the graphics context\r
585         // */\r
586         // protected void paintSafely(Graphics g) {\r
587         // painted = true;\r
588         // Highlighter highlighter = editor.getHighlighter();\r
589         // Caret caret = editor.getCaret();\r
590         //\r
591         // // paint the background\r
592         // if (editor.isOpaque()) {\r
593         // paintBackground(g);\r
594         // }\r
595         //\r
596         // // paint the highlights\r
597         // if (highlighter != null) {\r
598         // highlighter.paint(g);\r
599         // }\r
600         //\r
601         // // paint the view hierarchy\r
602         // Rectangle alloc = getVisibleEditorRect();\r
603         // if (alloc != null) {\r
604         // rootView.paint(g, alloc);\r
605         // }\r
606         //\r
607         // // paint the caret\r
608         // if (caret != null) {\r
609         // caret.paint(g);\r
610         // }\r
611         //\r
612         // if (dropCaret != null) {\r
613         // dropCaret.paint(g);\r
614         // }\r
615         // }\r
616 \r
617         // --- ComponentUI methods --------------------------------------------\r
618 \r
619         TextListener updateHandler;\r
620 \r
621         /**\r
622          * Installs the UI for a component. This does the following things.\r
623          * <ol>\r
624          * <li>\r
625          * Set the associated component to opaque (can be changed easily by a subclass\r
626          * or on JTextComponent directly), which is the most common case. This will\r
627          * cause the component's background color to be painted.\r
628          * <li>\r
629          * Install the default caret and highlighter into the associated component.\r
630          * <li>\r
631          * Attach to the editor and model. If there is no model, a default one is\r
632          * created.\r
633          * <li>\r
634          * create the view factory and the view hierarchy used to represent the model.\r
635          * </ol>\r
636          * \r
637          * @param c\r
638          *          the editor component\r
639          * @see ComponentUI#installUI\r
640          */\r
641         protected void installJSUI() {\r
642                 editor = (JTextComponent) c;\r
643                 updateHandler = new TextListener(this, editor);\r
644 \r
645                 // install defaults\r
646                 installDefaults();\r
647                 installDefaults2();\r
648 \r
649                 // // This is a workaround as these should not override what synth has\r
650                 // // set them to\r
651                 // if (!(this instanceof sun.swing.plaf.synth.SynthUI)){\r
652                 // // common case is background painted... this can\r
653                 // // easily be changed by subclasses or from outside\r
654                 // // of the component.\r
655                 // LookAndFeel.installProperty(editor, "opaque", Boolean.TRUE);\r
656                 // LookAndFeel.installProperty(editor, "autoscrolls", Boolean.TRUE);\r
657                 // }\r
658                 //\r
659                 // attach to the model and editor\r
660                 // Document doc = editor.getDocument();\r
661                 // if (doc == null) {\r
662                 // // no model, create a default one. This will\r
663                 // // fire a notification to the updateHandler\r
664                 // // which takes care of the rest.\r
665                 // editor.setDocument(getEditorKit(editor).createDefaultDocument());\r
666                 // } else {\r
667                 // // doc.addDocumentListener(updateHandler);\r
668                 // // modelChanged();\r
669                 // }\r
670 \r
671                 // install keymap\r
672                 installListeners(editor);\r
673                 installKeyboardActions();\r
674 \r
675                 // LayoutManager oldLayout = editor.getLayout();\r
676                 // if ((oldLayout == null) || (oldLayout instanceof UIResource)) {\r
677                 // // by default, use default LayoutManger implementation that\r
678                 // // will position the components associated with a View object.\r
679                 // editor.setLayout(updateHandler);\r
680                 // }\r
681                 //\r
682                 // updateBackground(editor);\r
683         }\r
684 \r
685         /**\r
686          * Deinstalls the UI for a component. This removes the listeners, uninstalls\r
687          * the highlighter, removes views, and nulls out the keymap.\r
688          * \r
689          * @param c\r
690          *          the editor component\r
691          * @see ComponentUI#uninstallUI\r
692          */\r
693         public void uninstallJSUI() {\r
694                 // detach from the model\r
695                 // editor.removePropertyChangeListener(updateHandler);\r
696                 // editor.getDocument().removeDocumentListener(updateHandler);\r
697 \r
698                 // view part\r
699                 // painted = false;\r
700                 uninstallDefaults();\r
701                 // rootView.setView(null);\r
702                 c.removeAll();\r
703                 LayoutManager lm = c.getLayout();\r
704                 if (lm instanceof UIResource) {\r
705                         c.setLayout(null);\r
706                 }\r
707 \r
708                 // controller part\r
709                 uninstallKeyboardActions();\r
710                 uninstallListeners(editor);\r
711 \r
712                 editor = null;\r
713                 updateHandler = null;\r
714         }\r
715 \r
716         protected void installListeners(JTextComponent b) {\r
717                 TextListener listener = updateHandler;\r
718                 b.addMouseListener(listener);\r
719                 b.addMouseMotionListener(listener);\r
720                 b.addFocusListener(listener);\r
721                 b.addPropertyChangeListener(listener);\r
722                 // SwingJS there won't be a document yet; this is in constructor\r
723                 // b.getDocument().addDocumentListener(listener);\r
724         }\r
725 \r
726         protected void uninstallListeners(JTextComponent b) {\r
727                 TextListener listener = updateHandler;\r
728                 b.removeMouseListener(listener);\r
729                 b.removeMouseMotionListener(listener);\r
730                 b.removeFocusListener(listener);\r
731                 b.removePropertyChangeListener(listener);\r
732                 b.getDocument().removeDocumentListener(listener);\r
733         }\r
734 \r
735         // /**\r
736         // * Superclass paints background in an uncontrollable way\r
737         // * (i.e. one might want an image tiled into the background).\r
738         // * To prevent this from happening twice, this method is\r
739         // * reimplemented to simply paint.\r
740         // * <p>\r
741         // * <em>NOTE:</em> Superclass is also not thread-safe in\r
742         // * it's rendering of the background, although that's not\r
743         // * an issue with the default rendering.\r
744         // */\r
745         // public void update(Graphics g, JComponent c) {\r
746         // paint(g, c);\r
747         // }\r
748         //\r
749         // /**\r
750         // * Paints the interface. This is routed to the\r
751         // * paintSafely method under the guarantee that\r
752         // * the model won't change from the view of this thread\r
753         // * while it's rendering (if the associated model is\r
754         // * derived from AbstractDocument). This enables the\r
755         // * model to potentially be updated asynchronously.\r
756         // *\r
757         // * @param g the graphics context\r
758         // * @param c the editor component\r
759         // */\r
760         // public final void paint(Graphics g, JComponent c) {\r
761         // if ((rootView.getViewCount() > 0) && (rootView.getView(0) != null)) {\r
762         // Document doc = editor.getDocument();\r
763         // if (doc instanceof AbstractDocument) {\r
764         // ((AbstractDocument)doc).readLock();\r
765         // }\r
766         // try {\r
767         // paintSafely(g);\r
768         // } finally {\r
769         // if (doc instanceof AbstractDocument) {\r
770         // ((AbstractDocument)doc).readUnlock();\r
771         // }\r
772         // }\r
773         // }\r
774         // }\r
775 \r
776         // /**\r
777         // * Gets the preferred size for the editor component. If the component\r
778         // * has been given a size prior to receiving this request, it will\r
779         // * set the size of the view hierarchy to reflect the size of the component\r
780         // * before requesting the preferred size of the view hierarchy. This\r
781         // * allows formatted views to format to the current component size before\r
782         // * answering the request. Other views don't care about currently formatted\r
783         // * size and give the same answer either way.\r
784         // *\r
785         // * @param c the editor component\r
786         // * @return the size\r
787         // */\r
788         // public Dimension getPreferredSize(JComponent c) {\r
789         // Dimension d = c.getSize();\r
790         // // Document doc = editor.getDocument();\r
791         // // Insets i = c.getInsets();\r
792         // //\r
793         // // if (doc instanceof AbstractDocument) {\r
794         // // ((AbstractDocument)doc).readLock();\r
795         // // }\r
796         // // try {\r
797         // // if ((d.width > (i.left + i.right)) && (d.height > (i.top + i.bottom))) {\r
798         // // rootView.setSize(d.width - i.left - i.right, d.height - i.top -\r
799         // i.bottom);\r
800         // // }\r
801         // // else if (d.width == 0 && d.height == 0) {\r
802         // // // Probably haven't been layed out yet, force some sort of\r
803         // // // initial sizing.\r
804         // // rootView.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);\r
805         // // }\r
806         // // d.width = (int) Math.min((long) rootView.getPreferredSpan(View.X_AXIS) +\r
807         // // (long) i.left + (long) i.right, Integer.MAX_VALUE);\r
808         // // d.height = (int) Math.min((long) rootView.getPreferredSpan(View.Y_AXIS)\r
809         // +\r
810         // // (long) i.top + (long) i.bottom, Integer.MAX_VALUE);\r
811         // // } finally {\r
812         // // if (doc instanceof AbstractDocument) {\r
813         // // ((AbstractDocument)doc).readUnlock();\r
814         // // }\r
815         // // }\r
816         // return d;\r
817         // }\r
818 \r
819         /**\r
820          * Gets the minimum size for the editor component.\r
821          * \r
822          * @param c\r
823          *          the editor component\r
824          * @return the size\r
825          */\r
826         public Dimension getMinimumSize(JComponent c) {\r
827                 Dimension d = getPreferredSize();// new Dimension();\r
828                 // Document doc = editor.getDocument();\r
829                 Insets i = c.getInsets();\r
830                 // if (doc instanceof AbstractDocument) {\r
831                 // ((AbstractDocument)doc).readLock();\r
832                 // }\r
833                 // try {\r
834 \r
835                 d.width += i.left + i.right;\r
836                 d.height += i.top + i.bottom;\r
837 \r
838                 // d.width = (int) rootView.getMinimumSpan(View.X_AXIS) + i.left + i.right;\r
839                 // d.height = (int) rootView.getMinimumSpan(View.Y_AXIS) + i.top + i.bottom;\r
840                 // } finally {\r
841                 // if (doc instanceof AbstractDocument) {\r
842                 // ((AbstractDocument)doc).readUnlock();\r
843                 // }\r
844                 // }\r
845                 return d;\r
846         }\r
847 \r
848         /**\r
849          * Gets the maximum size for the editor component.\r
850          * \r
851          * @param c\r
852          *          the editor component\r
853          * @return the size\r
854          */\r
855         public Dimension getMaximumSize(JComponent c) {\r
856                 // SwingJS TODO\r
857                 return getMinimumSize(c);\r
858 \r
859                 // Document doc = editor.getDocument();\r
860                 // Insets i = c.getInsets();\r
861                 // Dimension d = new Dimension();\r
862                 // if (doc instanceof AbstractDocument) {\r
863                 // ((AbstractDocument)doc).readLock();\r
864                 // }\r
865                 // try {\r
866                 // d.width = (int) Math.min((long) rootView.getMaximumSpan(View.X_AXIS) +\r
867                 // (long) i.left + (long) i.right, Integer.MAX_VALUE);\r
868                 // d.height = (int) Math.min((long) rootView.getMaximumSpan(View.Y_AXIS) +\r
869                 // (long) i.top + (long) i.bottom, Integer.MAX_VALUE);\r
870                 // } finally {\r
871                 // if (doc instanceof AbstractDocument) {\r
872                 // ((AbstractDocument)doc).readUnlock();\r
873                 // }\r
874                 // }\r
875                 // return d;\r
876         }\r
877 \r
878         // ---- TextUI methods -------------------------------------------\r
879 \r
880         //\r
881         // /**\r
882         // * Gets the allocation to give the root View. Due\r
883         // * to an unfortunate set of historical events this\r
884         // * method is inappropriately named. The Rectangle\r
885         // * returned has nothing to do with visibility.\r
886         // * The component must have a non-zero positive size for\r
887         // * this translation to be computed.\r
888         // *\r
889         // * @return the bounding box for the root view\r
890         // */\r
891         // protected Rectangle getVisibleEditorRect() {\r
892         // Rectangle alloc = editor.getBounds();\r
893         // if ((alloc.width > 0) && (alloc.height > 0)) {\r
894         // alloc.x = alloc.y = 0;\r
895         // Insets insets = editor.getInsets();\r
896         // alloc.x += insets.left;\r
897         // alloc.y += insets.top;\r
898         // alloc.width -= insets.left + insets.right;\r
899         // alloc.height -= insets.top + insets.bottom;\r
900         // return alloc;\r
901         // }\r
902         // return null;\r
903         // }\r
904         //\r
905         // /**\r
906         // * Converts the given location in the model to a place in\r
907         // * the view coordinate system.\r
908         // * The component must have a non-zero positive size for\r
909         // * this translation to be computed.\r
910         // *\r
911         // * @param tc the text component for which this UI is installed\r
912         // * @param pos the local location in the model to translate >= 0\r
913         // * @return the coordinates as a rectangle, null if the model is not painted\r
914         // * @exception BadLocationException if the given position does not\r
915         // * represent a valid location in the associated document\r
916         // * @see TextUI#modelToView\r
917         // */\r
918         // public Rectangle modelToView(JTextComponent tc, int pos) throws\r
919         // BadLocationException {\r
920         // return modelToView(tc, pos, Position.Bias.Forward);\r
921         // }\r
922         //\r
923         // /**\r
924         // * Converts the given location in the model to a place in\r
925         // * the view coordinate system.\r
926         // * The component must have a non-zero positive size for\r
927         // * this translation to be computed.\r
928         // *\r
929         // * @param tc the text component for which this UI is installed\r
930         // * @param pos the local location in the model to translate >= 0\r
931         // * @return the coordinates as a rectangle, null if the model is not painted\r
932         // * @exception BadLocationException if the given position does not\r
933         // * represent a valid location in the associated document\r
934         // * @see TextUI#modelToView\r
935         // */\r
936         // public Rectangle modelToView(JTextComponent tc, int pos, Position.Bias\r
937         // bias) throws BadLocationException {\r
938         // Document doc = editor.getDocument();\r
939         // if (doc instanceof AbstractDocument) {\r
940         // ((AbstractDocument)doc).readLock();\r
941         // }\r
942         // try {\r
943         // Rectangle alloc = getVisibleEditorRect();\r
944         // if (alloc != null) {\r
945         // rootView.setSize(alloc.width, alloc.height);\r
946         // Shape s = rootView.modelToView(pos, alloc, bias);\r
947         // if (s != null) {\r
948         // return s.getBounds();\r
949         // }\r
950         // }\r
951         // } finally {\r
952         // if (doc instanceof AbstractDocument) {\r
953         // ((AbstractDocument)doc).readUnlock();\r
954         // }\r
955         // }\r
956         // return null;\r
957         // }\r
958         //\r
959         // /**\r
960         // * Converts the given place in the view coordinate system\r
961         // * to the nearest representative location in the model.\r
962         // * The component must have a non-zero positive size for\r
963         // * this translation to be computed.\r
964         // *\r
965         // * @param tc the text component for which this UI is installed\r
966         // * @param pt the location in the view to translate. This\r
967         // * should be in the same coordinate system as the mouse events.\r
968         // * @return the offset from the start of the document >= 0,\r
969         // * -1 if not painted\r
970         // * @see TextUI#viewToModel\r
971         // */\r
972         // public int viewToModel(JTextComponent tc, Point pt) {\r
973         // return viewToModel(tc, pt, discardBias);\r
974         // }\r
975         //\r
976         // /**\r
977         // * Converts the given place in the view coordinate system\r
978         // * to the nearest representative location in the model.\r
979         // * The component must have a non-zero positive size for\r
980         // * this translation to be computed.\r
981         // *\r
982         // * @param tc the text component for which this UI is installed\r
983         // * @param pt the location in the view to translate. This\r
984         // * should be in the same coordinate system as the mouse events.\r
985         // * @return the offset from the start of the document >= 0,\r
986         // * -1 if the component doesn't yet have a positive size.\r
987         // * @see TextUI#viewToModel\r
988         // */\r
989         // public int viewToModel(JTextComponent tc, Point pt,\r
990         // Position.Bias[] biasReturn) {\r
991         // int offs = -1;\r
992         // Document doc = editor.getDocument();\r
993         // if (doc instanceof AbstractDocument) {\r
994         // ((AbstractDocument)doc).readLock();\r
995         // }\r
996         // try {\r
997         // Rectangle alloc = getVisibleEditorRect();\r
998         // if (alloc != null) {\r
999         // rootView.setSize(alloc.width, alloc.height);\r
1000         // offs = rootView.viewToModel(pt.x, pt.y, alloc, biasReturn);\r
1001         // }\r
1002         // } finally {\r
1003         // if (doc instanceof AbstractDocument) {\r
1004         // ((AbstractDocument)doc).readUnlock();\r
1005         // }\r
1006         // }\r
1007         // return offs;\r
1008         // }\r
1009 \r
1010         // /**\r
1011         // * {@inheritDoc}\r
1012         // */\r
1013         // public int getNextVisualPositionFrom(JTextComponent t, int pos,\r
1014         // Position.Bias b, int direction, Position.Bias[] biasRet)\r
1015         // throws BadLocationException{\r
1016         // Document doc = editor.getDocument();\r
1017         // if (doc instanceof AbstractDocument) {\r
1018         // ((AbstractDocument)doc).readLock();\r
1019         // }\r
1020         // try {\r
1021         // if (painted) {\r
1022         // Rectangle alloc = getVisibleEditorRect();\r
1023         // if (alloc != null) {\r
1024         // rootView.setSize(alloc.width, alloc.height);\r
1025         // }\r
1026         // return rootView.getNextVisualPositionFrom(pos, b, alloc, direction,\r
1027         // biasRet);\r
1028         // }\r
1029         // } finally {\r
1030         // if (doc instanceof AbstractDocument) {\r
1031         // ((AbstractDocument)doc).readUnlock();\r
1032         // }\r
1033         // }\r
1034         // return -1;\r
1035         // }\r
1036         //\r
1037         // /**\r
1038         // * Causes the portion of the view responsible for the\r
1039         // * given part of the model to be repainted. Does nothing if\r
1040         // * the view is not currently painted.\r
1041         // *\r
1042         // * @param tc the text component for which this UI is installed\r
1043         // * @param p0 the beginning of the range >= 0\r
1044         // * @param p1 the end of the range >= p0\r
1045         // * @see TextUI#damageRange\r
1046         // */\r
1047         // public void damageRange(JTextComponent tc, int p0, int p1) {\r
1048         // damageRange(tc, p0, p1, Position.Bias.Forward, Position.Bias.Backward);\r
1049         // }\r
1050         //\r
1051         // /**\r
1052         // * Causes the portion of the view responsible for the\r
1053         // * given part of the model to be repainted.\r
1054         // *\r
1055         // * @param p0 the beginning of the range >= 0\r
1056         // * @param p1 the end of the range >= p0\r
1057         // */\r
1058         // public void damageRange(JTextComponent t, int p0, int p1,\r
1059         // Position.Bias p0Bias, Position.Bias p1Bias) {\r
1060         // if (painted) {\r
1061         // Rectangle alloc = getVisibleEditorRect();\r
1062         // if (alloc != null) {\r
1063         // Document doc = t.getDocument();\r
1064         // if (doc instanceof AbstractDocument) {\r
1065         // ((AbstractDocument)doc).readLock();\r
1066         // }\r
1067         // try {\r
1068         // rootView.setSize(alloc.width, alloc.height);\r
1069         // Shape toDamage = rootView.modelToView(p0, p0Bias,\r
1070         // p1, p1Bias, alloc);\r
1071         // Rectangle rect = (toDamage instanceof Rectangle) ?\r
1072         // (Rectangle)toDamage : toDamage.getBounds();\r
1073         // editor.repaint(rect.x, rect.y, rect.width, rect.height);\r
1074         // } catch (BadLocationException e) {\r
1075         // } finally {\r
1076         // if (doc instanceof AbstractDocument) {\r
1077         // ((AbstractDocument)doc).readUnlock();\r
1078         // }\r
1079         // }\r
1080         // }\r
1081         // }\r
1082         // }\r
1083 \r
1084         /**\r
1085          * Fetches the EditorKit for the UI.\r
1086          * \r
1087          * @param tc\r
1088          *          the text component for which this UI is installed\r
1089          * @return the editor capabilities\r
1090          * @see TextUI#getEditorKit\r
1091          */\r
1092         public EditorKit getEditorKit(JTextComponent tc) {\r
1093                 return defaultKit;\r
1094         }\r
1095 \r
1096         // /**\r
1097         // * Fetches a View with the allocation of the associated\r
1098         // * text component (i.e. the root of the hierarchy) that\r
1099         // * can be traversed to determine how the model is being\r
1100         // * represented spatially.\r
1101         // * <p>\r
1102         // * <font color=red><b>NOTE:</b>The View hierarchy can\r
1103         // * be traversed from the root view, and other things\r
1104         // * can be done as well. Things done in this way cannot\r
1105         // * be protected like simple method calls through the TextUI.\r
1106         // * Therefore, proper operation in the presence of concurrency\r
1107         // * must be arranged by any logic that calls this method!\r
1108         // * </font>\r
1109         // *\r
1110         // * @param tc the text component for which this UI is installed\r
1111         // * @return the view\r
1112         // * @see TextUI#getRootView\r
1113         // */\r
1114         // public View getRootView(JTextComponent tc) {\r
1115         // return rootView;\r
1116         // }\r
1117 \r
1118         // /**\r
1119         // * Returns the string to be used as the tooltip at the passed in location.\r
1120         // * This forwards the method onto the root View.\r
1121         // *\r
1122         // * @see jsjavax.swing.text.JTextComponent#getToolTipText\r
1123         // * @see jsjavax.swing.text.View#getToolTipText\r
1124         // * @since 1.4\r
1125         // */\r
1126         // public String getToolTipText(JTextComponent t, Point pt) {\r
1127         // if (!painted) {\r
1128         // return null;\r
1129         // }\r
1130         // Document doc = editor.getDocument();\r
1131         // String tt = null;\r
1132         // Rectangle alloc = getVisibleEditorRect();\r
1133         //\r
1134         // if (alloc != null) {\r
1135         // if (doc instanceof AbstractDocument) {\r
1136         // ((AbstractDocument)doc).readLock();\r
1137         // }\r
1138         // try {\r
1139         // tt = rootView.getToolTipText(pt.x, pt.y, alloc);\r
1140         // } finally {\r
1141         // if (doc instanceof AbstractDocument) {\r
1142         // ((AbstractDocument)doc).readUnlock();\r
1143         // }\r
1144         // }\r
1145         // }\r
1146         // return tt;\r
1147         // }\r
1148         //\r
1149         // --- ViewFactory methods ------------------------------\r
1150         //\r
1151         // /**\r
1152         // * Creates a view for an element.\r
1153         // * If a subclass wishes to directly implement the factory\r
1154         // * producing the view(s), it should reimplement this\r
1155         // * method. By default it simply returns null indicating\r
1156         // * it is unable to represent the element.\r
1157         // *\r
1158         // * @param elem the element\r
1159         // * @return the view\r
1160         // */\r
1161         // public View create(Element elem) {\r
1162         // return null;\r
1163         // }\r
1164         //\r
1165         // /**\r
1166         // * Creates a view for an element.\r
1167         // * If a subclass wishes to directly implement the factory\r
1168         // * producing the view(s), it should reimplement this\r
1169         // * method. By default it simply returns null indicating\r
1170         // * it is unable to represent the part of the element.\r
1171         // *\r
1172         // * @param elem the element\r
1173         // * @param p0 the starting offset >= 0\r
1174         // * @param p1 the ending offset >= p0\r
1175         // * @return the view\r
1176         // */\r
1177         // public View create(Element elem, int p0, int p1) {\r
1178         // return null;\r
1179         // }\r
1180         //\r
1181         // public static class BasicCaret extends DefaultCaret implements UIResource\r
1182         // {}\r
1183         //\r
1184         // public static class BasicHighlighter extends DefaultHighlighter implements\r
1185         // UIResource {}\r
1186         //\r
1187         // static class BasicCursor extends Cursor implements UIResource {\r
1188         // BasicCursor(int type) {\r
1189         // super(type);\r
1190         // }\r
1191         //\r
1192         // BasicCursor(String name) {\r
1193         // super(name);\r
1194         // }\r
1195         // }\r
1196         //\r
1197         // private static BasicCursor textCursor = new\r
1198         // BasicCursor(Cursor.TEXT_CURSOR);\r
1199         // ----- member variables ---------------------------------------\r
1200 \r
1201         private static final EditorKit defaultKit = new DefaultEditorKit();\r
1202         transient JTextComponent editor;\r
1203         protected boolean editable = true;\r
1204 \r
1205         // transient boolean painted;\r
1206         // transient RootView rootView = new RootView();\r
1207         // transient UpdateHandler updateHandler = new UpdateHandler();\r
1208         // private static final TransferHandler defaultTransferHandler = new\r
1209         // TextTransferHandler();\r
1210         // private final DragListener dragListener = getDragListener();\r
1211         // private static final Position.Bias[] discardBias = new Position.Bias[1];\r
1212         // private DefaultCaret dropCaret;\r
1213 \r
1214         // /**\r
1215         // * Root view that acts as a gateway between the component\r
1216         // * and the View hierarchy.\r
1217         // */\r
1218         // class RootView extends View {\r
1219         //\r
1220         // RootView() {\r
1221         // super(null);\r
1222         // }\r
1223         //\r
1224         // void setView(View v) {\r
1225         // View oldView = view;\r
1226         // view = null;\r
1227         // if (oldView != null) {\r
1228         // // get rid of back reference so that the old\r
1229         // // hierarchy can be garbage collected.\r
1230         // oldView.setParent(null);\r
1231         // }\r
1232         // if (v != null) {\r
1233         // v.setParent(this);\r
1234         // }\r
1235         // view = v;\r
1236         // }\r
1237         //\r
1238         // /**\r
1239         // * Fetches the attributes to use when rendering. At the root\r
1240         // * level there are no attributes. If an attribute is resolved\r
1241         // * up the view hierarchy this is the end of the line.\r
1242         // */\r
1243         // public AttributeSet getAttributes() {\r
1244         // return null;\r
1245         // }\r
1246         //\r
1247         // /**\r
1248         // * Determines the preferred span for this view along an axis.\r
1249         // *\r
1250         // * @param axis may be either X_AXIS or Y_AXIS\r
1251         // * @return the span the view would like to be rendered into.\r
1252         // * Typically the view is told to render into the span\r
1253         // * that is returned, although there is no guarantee.\r
1254         // * The parent may choose to resize or break the view.\r
1255         // */\r
1256         // public float getPreferredSpan(int axis) {\r
1257         // if (view != null) {\r
1258         // return view.getPreferredSpan(axis);\r
1259         // }\r
1260         // return 10;\r
1261         // }\r
1262         //\r
1263         // /**\r
1264         // * Determines the minimum span for this view along an axis.\r
1265         // *\r
1266         // * @param axis may be either X_AXIS or Y_AXIS\r
1267         // * @return the span the view would like to be rendered into.\r
1268         // * Typically the view is told to render into the span\r
1269         // * that is returned, although there is no guarantee.\r
1270         // * The parent may choose to resize or break the view.\r
1271         // */\r
1272         // public float getMinimumSpan(int axis) {\r
1273         // if (view != null) {\r
1274         // return view.getMinimumSpan(axis);\r
1275         // }\r
1276         // return 10;\r
1277         // }\r
1278         //\r
1279         // /**\r
1280         // * Determines the maximum span for this view along an axis.\r
1281         // *\r
1282         // * @param axis may be either X_AXIS or Y_AXIS\r
1283         // * @return the span the view would like to be rendered into.\r
1284         // * Typically the view is told to render into the span\r
1285         // * that is returned, although there is no guarantee.\r
1286         // * The parent may choose to resize or break the view.\r
1287         // */\r
1288         // public float getMaximumSpan(int axis) {\r
1289         // return Integer.MAX_VALUE;\r
1290         // }\r
1291         //\r
1292         // /**\r
1293         // * Specifies that a preference has changed.\r
1294         // * Child views can call this on the parent to indicate that\r
1295         // * the preference has changed. The root view routes this to\r
1296         // * invalidate on the hosting component.\r
1297         // * <p>\r
1298         // * This can be called on a different thread from the\r
1299         // * event dispatching thread and is basically unsafe to\r
1300         // * propagate into the component. To make this safe,\r
1301         // * the operation is transferred over to the event dispatching\r
1302         // * thread for completion. It is a design goal that all view\r
1303         // * methods be safe to call without concern for concurrency,\r
1304         // * and this behavior helps make that true.\r
1305         // *\r
1306         // * @param child the child view\r
1307         // * @param width true if the width preference has changed\r
1308         // * @param height true if the height preference has changed\r
1309         // */\r
1310         // public void preferenceChanged(View child, boolean width, boolean height) {\r
1311         // editor.revalidate();\r
1312         // }\r
1313         //\r
1314         // /**\r
1315         // * Determines the desired alignment for this view along an axis.\r
1316         // *\r
1317         // * @param axis may be either X_AXIS or Y_AXIS\r
1318         // * @return the desired alignment, where 0.0 indicates the origin\r
1319         // * and 1.0 the full span away from the origin\r
1320         // */\r
1321         // public float getAlignment(int axis) {\r
1322         // if (view != null) {\r
1323         // return view.getAlignment(axis);\r
1324         // }\r
1325         // return 0;\r
1326         // }\r
1327         //\r
1328         // /**\r
1329         // * Renders the view.\r
1330         // *\r
1331         // * @param g the graphics context\r
1332         // * @param allocation the region to render into\r
1333         // */\r
1334         // public void paint(Graphics g, Shape allocation) {\r
1335         // if (view != null) {\r
1336         // Rectangle alloc = (allocation instanceof Rectangle) ?\r
1337         // (Rectangle)allocation : allocation.getBounds();\r
1338         // setSize(alloc.width, alloc.height);\r
1339         // view.paint(g, allocation);\r
1340         // }\r
1341         // }\r
1342         //\r
1343         // /**\r
1344         // * Sets the view parent.\r
1345         // *\r
1346         // * @param parent the parent view\r
1347         // */\r
1348         // public void setParent(View parent) {\r
1349         // throw new Error("Can't set parent on root view");\r
1350         // }\r
1351         //\r
1352         // /**\r
1353         // * Returns the number of views in this view. Since\r
1354         // * this view simply wraps the root of the view hierarchy\r
1355         // * it has exactly one child.\r
1356         // *\r
1357         // * @return the number of views\r
1358         // * @see #getView\r
1359         // */\r
1360         // public int getViewCount() {\r
1361         // return 1;\r
1362         // }\r
1363         //\r
1364         // /**\r
1365         // * Gets the n-th view in this container.\r
1366         // *\r
1367         // * @param n the number of the view to get\r
1368         // * @return the view\r
1369         // */\r
1370         // public View getView(int n) {\r
1371         // return view;\r
1372         // }\r
1373         //\r
1374         // /**\r
1375         // * Returns the child view index representing the given position in\r
1376         // * the model. This is implemented to return the index of the only\r
1377         // * child.\r
1378         // *\r
1379         // * @param pos the position >= 0\r
1380         // * @return index of the view representing the given position, or\r
1381         // * -1 if no view represents that position\r
1382         // * @since 1.3\r
1383         // */\r
1384         // public int getViewIndex(int pos, Position.Bias b) {\r
1385         // return 0;\r
1386         // }\r
1387         //\r
1388         // /**\r
1389         // * Fetches the allocation for the given child view.\r
1390         // * This enables finding out where various views\r
1391         // * are located, without assuming the views store\r
1392         // * their location. This returns the given allocation\r
1393         // * since this view simply acts as a gateway between\r
1394         // * the view hierarchy and the associated component.\r
1395         // *\r
1396         // * @param index the index of the child\r
1397         // * @param a the allocation to this view.\r
1398         // * @return the allocation to the child\r
1399         // */\r
1400         // public Shape getChildAllocation(int index, Shape a) {\r
1401         // return a;\r
1402         // }\r
1403         //\r
1404         // /**\r
1405         // * Provides a mapping from the document model coordinate space\r
1406         // * to the coordinate space of the view mapped to it.\r
1407         // *\r
1408         // * @param pos the position to convert\r
1409         // * @param a the allocated region to render into\r
1410         // * @return the bounding box of the given position\r
1411         // */\r
1412         // public Shape modelToView(int pos, Shape a, Position.Bias b) throws\r
1413         // BadLocationException {\r
1414         // if (view != null) {\r
1415         // return view.modelToView(pos, a, b);\r
1416         // }\r
1417         // return null;\r
1418         // }\r
1419         //\r
1420         // /**\r
1421         // * Provides a mapping from the document model coordinate space\r
1422         // * to the coordinate space of the view mapped to it.\r
1423         // *\r
1424         // * @param p0 the position to convert >= 0\r
1425         // * @param b0 the bias toward the previous character or the\r
1426         // * next character represented by p0, in case the\r
1427         // * position is a boundary of two views.\r
1428         // * @param p1 the position to convert >= 0\r
1429         // * @param b1 the bias toward the previous character or the\r
1430         // * next character represented by p1, in case the\r
1431         // * position is a boundary of two views.\r
1432         // * @param a the allocated region to render into\r
1433         // * @return the bounding box of the given position is returned\r
1434         // * @exception BadLocationException if the given position does\r
1435         // * not represent a valid location in the associated document\r
1436         // * @exception IllegalArgumentException for an invalid bias argument\r
1437         // * @see View#viewToModel\r
1438         // */\r
1439         // public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias\r
1440         // b1, Shape a) throws BadLocationException {\r
1441         // if (view != null) {\r
1442         // return view.modelToView(p0, b0, p1, b1, a);\r
1443         // }\r
1444         // return null;\r
1445         // }\r
1446         //\r
1447         // /**\r
1448         // * Provides a mapping from the view coordinate space to the logical\r
1449         // * coordinate space of the model.\r
1450         // *\r
1451         // * @param x x coordinate of the view location to convert\r
1452         // * @param y y coordinate of the view location to convert\r
1453         // * @param a the allocated region to render into\r
1454         // * @return the location within the model that best represents the\r
1455         // * given point in the view\r
1456         // */\r
1457         // public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {\r
1458         // if (view != null) {\r
1459         // int retValue = view.viewToModel(x, y, a, bias);\r
1460         // return retValue;\r
1461         // }\r
1462         // return -1;\r
1463         // }\r
1464         //\r
1465         // /**\r
1466         // * Provides a way to determine the next visually represented model\r
1467         // * location that one might place a caret. Some views may not be visible,\r
1468         // * they might not be in the same order found in the model, or they just\r
1469         // * might not allow access to some of the locations in the model.\r
1470         // *\r
1471         // * @param pos the position to convert >= 0\r
1472         // * @param a the allocated region to render into\r
1473         // * @param direction the direction from the current position that can\r
1474         // * be thought of as the arrow keys typically found on a keyboard.\r
1475         // * This may be SwingConstants.WEST, SwingConstants.EAST,\r
1476         // * SwingConstants.NORTH, or SwingConstants.SOUTH.\r
1477         // * @return the location within the model that best represents the next\r
1478         // * location visual position.\r
1479         // * @exception BadLocationException\r
1480         // * @exception IllegalArgumentException for an invalid direction\r
1481         // */\r
1482         // public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a,\r
1483         // int direction,\r
1484         // Position.Bias[] biasRet)\r
1485         // throws BadLocationException {\r
1486         // if( view != null ) {\r
1487         // int nextPos = view.getNextVisualPositionFrom(pos, b, a,\r
1488         // direction, biasRet);\r
1489         // if(nextPos != -1) {\r
1490         // pos = nextPos;\r
1491         // }\r
1492         // else {\r
1493         // biasRet[0] = b;\r
1494         // }\r
1495         // }\r
1496         // return pos;\r
1497         // }\r
1498         //\r
1499         // /**\r
1500         // * Gives notification that something was inserted into the document\r
1501         // * in a location that this view is responsible for.\r
1502         // *\r
1503         // * @param e the change information from the associated document\r
1504         // * @param a the current allocation of the view\r
1505         // * @param f the factory to use to rebuild if the view has children\r
1506         // */\r
1507         // public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) {\r
1508         // if (view != null) {\r
1509         // view.insertUpdate(e, a, f);\r
1510         // }\r
1511         // }\r
1512         //\r
1513         // /**\r
1514         // * Gives notification that something was removed from the document\r
1515         // * in a location that this view is responsible for.\r
1516         // *\r
1517         // * @param e the change information from the associated document\r
1518         // * @param a the current allocation of the view\r
1519         // * @param f the factory to use to rebuild if the view has children\r
1520         // */\r
1521         // public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) {\r
1522         // if (view != null) {\r
1523         // view.removeUpdate(e, a, f);\r
1524         // }\r
1525         // }\r
1526         //\r
1527         // /**\r
1528         // * Gives notification from the document that attributes were changed\r
1529         // * in a location that this view is responsible for.\r
1530         // *\r
1531         // * @param e the change information from the associated document\r
1532         // * @param a the current allocation of the view\r
1533         // * @param f the factory to use to rebuild if the view has children\r
1534         // */\r
1535         // public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {\r
1536         // if (view != null) {\r
1537         // view.changedUpdate(e, a, f);\r
1538         // }\r
1539         // }\r
1540         //\r
1541         // /**\r
1542         // * Returns the document model underlying the view.\r
1543         // *\r
1544         // * @return the model\r
1545         // */\r
1546         // public Document getDocument() {\r
1547         // return editor.getDocument();\r
1548         // }\r
1549         //\r
1550         // /**\r
1551         // * Returns the starting offset into the model for this view.\r
1552         // *\r
1553         // * @return the starting offset\r
1554         // */\r
1555         // public int getStartOffset() {\r
1556         // if (view != null) {\r
1557         // return view.getStartOffset();\r
1558         // }\r
1559         // return getElement().getStartOffset();\r
1560         // }\r
1561         //\r
1562         // /**\r
1563         // * Returns the ending offset into the model for this view.\r
1564         // *\r
1565         // * @return the ending offset\r
1566         // */\r
1567         // public int getEndOffset() {\r
1568         // if (view != null) {\r
1569         // return view.getEndOffset();\r
1570         // }\r
1571         // return getElement().getEndOffset();\r
1572         // }\r
1573         //\r
1574         // /**\r
1575         // * Gets the element that this view is mapped to.\r
1576         // *\r
1577         // * @return the view\r
1578         // */\r
1579         // public Element getElement() {\r
1580         // if (view != null) {\r
1581         // return view.getElement();\r
1582         // }\r
1583         // return editor.getDocument().getDefaultRootElement();\r
1584         // }\r
1585         //\r
1586         // /**\r
1587         // * Breaks this view on the given axis at the given length.\r
1588         // *\r
1589         // * @param axis may be either X_AXIS or Y_AXIS\r
1590         // * @param len specifies where a break is desired in the span\r
1591         // * @param the current allocation of the view\r
1592         // * @return the fragment of the view that represents the given span\r
1593         // * if the view can be broken, otherwise null\r
1594         // */\r
1595         // public View breakView(int axis, float len, Shape a) {\r
1596         // throw new Error("Can't break root view");\r
1597         // }\r
1598         //\r
1599         // /**\r
1600         // * Determines the resizability of the view along the\r
1601         // * given axis. A value of 0 or less is not resizable.\r
1602         // *\r
1603         // * @param axis may be either X_AXIS or Y_AXIS\r
1604         // * @return the weight\r
1605         // */\r
1606         // public int getResizeWeight(int axis) {\r
1607         // if (view != null) {\r
1608         // return view.getResizeWeight(axis);\r
1609         // }\r
1610         // return 0;\r
1611         // }\r
1612         //\r
1613         // /**\r
1614         // * Sets the view size.\r
1615         // *\r
1616         // * @param width the width\r
1617         // * @param height the height\r
1618         // */\r
1619         // public void setSize(float width, float height) {\r
1620         // if (view != null) {\r
1621         // view.setSize(width, height);\r
1622         // }\r
1623         // }\r
1624         //\r
1625         // /**\r
1626         // * Fetches the container hosting the view. This is useful for\r
1627         // * things like scheduling a repaint, finding out the host\r
1628         // * components font, etc. The default implementation\r
1629         // * of this is to forward the query to the parent view.\r
1630         // *\r
1631         // * @return the container\r
1632         // */\r
1633         // public Container getContainer() {\r
1634         // return editor;\r
1635         // }\r
1636         //\r
1637         // /**\r
1638         // * Fetches the factory to be used for building the\r
1639         // * various view fragments that make up the view that\r
1640         // * represents the model. This is what determines\r
1641         // * how the model will be represented. This is implemented\r
1642         // * to fetch the factory provided by the associated\r
1643         // * EditorKit unless that is null, in which case this\r
1644         // * simply returns the BasicTextUI itself which allows\r
1645         // * subclasses to implement a simple factory directly without\r
1646         // * creating extra objects.\r
1647         // *\r
1648         // * @return the factory\r
1649         // */\r
1650         // public ViewFactory getViewFactory() {\r
1651         // EditorKit kit = getEditorKit(editor);\r
1652         // ViewFactory f = kit.getViewFactory();\r
1653         // if (f != null) {\r
1654         // return f;\r
1655         // }\r
1656         // return BasicTextUI.this;\r
1657         // }\r
1658         //\r
1659         // private View view;\r
1660         //\r
1661         // }\r
1662 \r
1663         // /**\r
1664         // * Handles updates from various places. If the model is changed,\r
1665         // * this class unregisters as a listener to the old model and\r
1666         // * registers with the new model. If the document model changes,\r
1667         // * the change is forwarded to the root view. If the focus\r
1668         // * accelerator changes, a new keystroke is registered to request\r
1669         // * focus.\r
1670         // */\r
1671         // class UpdateHandler implements PropertyChangeListener, DocumentListener,\r
1672         // LayoutManager2, UIResource {\r
1673         //\r
1674         // // --- PropertyChangeListener methods -----------------------\r
1675         //\r
1676         // /**\r
1677         // * This method gets called when a bound property is changed.\r
1678         // * We are looking for document changes on the editor.\r
1679         // */\r
1680         // public final void propertyChange(PropertyChangeEvent evt) {\r
1681         // Object oldValue = evt.getOldValue();\r
1682         // Object newValue = evt.getNewValue();\r
1683         // String propertyName = evt.getPropertyName();\r
1684         // if ((oldValue instanceof Document) || (newValue instanceof Document)) {\r
1685         // if (oldValue != null) {\r
1686         // ((Document)oldValue).removeDocumentListener(this);\r
1687         // i18nView = false;\r
1688         // }\r
1689         // if (newValue != null) {\r
1690         // ((Document)newValue).addDocumentListener(this);\r
1691         // if ("document" == propertyName) {\r
1692         // setView(null);\r
1693         // BasicTextUI.this.propertyChange(evt);\r
1694         // modelChanged();\r
1695         // return;\r
1696         // }\r
1697         // }\r
1698         // modelChanged();\r
1699         // }\r
1700         // if ("focusAccelerator" == propertyName) {\r
1701         // updateFocusAcceleratorBinding(true);\r
1702         // } else if ("componentOrientation" == propertyName) {\r
1703         // // Changes in ComponentOrientation require the views to be\r
1704         // // rebuilt.\r
1705         // modelChanged();\r
1706         // } else if ("font" == propertyName) {\r
1707         // modelChanged();\r
1708         // } else if ("dropLocation" == propertyName) {\r
1709         // dropIndexChanged();\r
1710         // } else if ("editable" == propertyName) {\r
1711         // updateCursor();\r
1712         // modelChanged();\r
1713         // }\r
1714         // BasicTextUI.this.propertyChange(evt);\r
1715         // }\r
1716         //\r
1717         // private void dropIndexChanged() {\r
1718         // if (editor.getDropMode() == DropMode.USE_SELECTION) {\r
1719         // return;\r
1720         // }\r
1721         //\r
1722         // JTextComponent.DropLocation dropLocation = editor.getDropLocation();\r
1723         //\r
1724         // if (dropLocation == null) {\r
1725         // if (dropCaret != null) {\r
1726         // dropCaret.deinstall(editor);\r
1727         // editor.repaint(dropCaret);\r
1728         // dropCaret = null;\r
1729         // }\r
1730         // } else {\r
1731         // if (dropCaret == null) {\r
1732         // dropCaret = new BasicCaret();\r
1733         // dropCaret.install(editor);\r
1734         // dropCaret.setVisible(true);\r
1735         // }\r
1736         //\r
1737         // dropCaret.setDot(dropLocation.getIndex(),\r
1738         // dropLocation.getBias());\r
1739         // }\r
1740         // }\r
1741         //\r
1742         // // --- DocumentListener methods -----------------------\r
1743         //\r
1744         // /**\r
1745         // * The insert notification. Gets sent to the root of the view structure\r
1746         // * that represents the portion of the model being represented by the\r
1747         // * editor. The factory is added as an argument to the update so that\r
1748         // * the views can update themselves in a dynamic (not hardcoded) way.\r
1749         // *\r
1750         // * @param e The change notification from the currently associated\r
1751         // * document.\r
1752         // * @see DocumentListener#insertUpdate\r
1753         // */\r
1754         // public final void insertUpdate(DocumentEvent e) {\r
1755         // Document doc = e.getDocument();\r
1756         // Object o = doc.getProperty("i18n");\r
1757         // if (o instanceof Boolean) {\r
1758         // Boolean i18nFlag = (Boolean) o;\r
1759         // if (i18nFlag.booleanValue() != i18nView) {\r
1760         // // i18n flag changed, rebuild the view\r
1761         // i18nView = i18nFlag.booleanValue();\r
1762         // modelChanged();\r
1763         // return;\r
1764         // }\r
1765         // }\r
1766         //\r
1767         // // normal insert update\r
1768         // Rectangle alloc = (painted) ? getVisibleEditorRect() : null;\r
1769         // rootView.insertUpdate(e, alloc, rootView.getViewFactory());\r
1770         // }\r
1771         //\r
1772         // /**\r
1773         // * The remove notification. Gets sent to the root of the view structure\r
1774         // * that represents the portion of the model being represented by the\r
1775         // * editor. The factory is added as an argument to the update so that\r
1776         // * the views can update themselves in a dynamic (not hardcoded) way.\r
1777         // *\r
1778         // * @param e The change notification from the currently associated\r
1779         // * document.\r
1780         // * @see DocumentListener#removeUpdate\r
1781         // */\r
1782         // public final void removeUpdate(DocumentEvent e) {\r
1783         // Rectangle alloc = (painted) ? getVisibleEditorRect() : null;\r
1784         // rootView.removeUpdate(e, alloc, rootView.getViewFactory());\r
1785         // }\r
1786         //\r
1787         // /**\r
1788         // * The change notification. Gets sent to the root of the view structure\r
1789         // * that represents the portion of the model being represented by the\r
1790         // * editor. The factory is added as an argument to the update so that\r
1791         // * the views can update themselves in a dynamic (not hardcoded) way.\r
1792         // *\r
1793         // * @param e The change notification from the currently associated\r
1794         // * document.\r
1795         // * @see DocumentListener#changeUpdate\r
1796         // */\r
1797         // public final void changedUpdate(DocumentEvent e) {\r
1798         // Rectangle alloc = (painted) ? getVisibleEditorRect() : null;\r
1799         // rootView.changedUpdate(e, alloc, rootView.getViewFactory());\r
1800         // }\r
1801         //\r
1802         // // --- LayoutManager2 methods --------------------------------\r
1803         //\r
1804         // /**\r
1805         // * Adds the specified component with the specified name to\r
1806         // * the layout.\r
1807         // * @param name the component name\r
1808         // * @param comp the component to be added\r
1809         // */\r
1810         // public void addLayoutComponent(String name, Component comp) {\r
1811         // // not supported\r
1812         // }\r
1813         //\r
1814         // /**\r
1815         // * Removes the specified component from the layout.\r
1816         // * @param comp the component to be removed\r
1817         // */\r
1818         // public void removeLayoutComponent(Component comp) {\r
1819         // if (constraints != null) {\r
1820         // // remove the constraint record\r
1821         // constraints.remove(comp);\r
1822         // }\r
1823         // }\r
1824         //\r
1825         // /**\r
1826         // * Calculates the preferred size dimensions for the specified\r
1827         // * panel given the components in the specified parent container.\r
1828         // * @param parent the component to be laid out\r
1829         // *\r
1830         // * @see #minimumLayoutSize\r
1831         // */\r
1832         // public Dimension preferredLayoutSize(Container parent) {\r
1833         // // should not be called (JComponent uses UI instead)\r
1834         // return null;\r
1835         // }\r
1836         //\r
1837         // /**\r
1838         // * Calculates the minimum size dimensions for the specified\r
1839         // * panel given the components in the specified parent container.\r
1840         // * @param parent the component to be laid out\r
1841         // * @see #preferredLayoutSize\r
1842         // */\r
1843         // public Dimension minimumLayoutSize(Container parent) {\r
1844         // // should not be called (JComponent uses UI instead)\r
1845         // return null;\r
1846         // }\r
1847         //\r
1848         // /**\r
1849         // * Lays out the container in the specified panel. This is\r
1850         // * implemented to position all components that were added\r
1851         // * with a View object as a constraint. The current allocation\r
1852         // * of the associated View is used as the location of the\r
1853         // * component.\r
1854         // * <p>\r
1855         // * A read-lock is acquired on the document to prevent the\r
1856         // * view tree from being modified while the layout process\r
1857         // * is active.\r
1858         // *\r
1859         // * @param parent the component which needs to be laid out\r
1860         // */\r
1861         // public void layoutContainer(Container parent) {\r
1862         // if ((constraints != null) && (! constraints.isEmpty())) {\r
1863         // Rectangle alloc = getVisibleEditorRect();\r
1864         // if (alloc != null) {\r
1865         // Document doc = editor.getDocument();\r
1866         // if (doc instanceof AbstractDocument) {\r
1867         // ((AbstractDocument)doc).readLock();\r
1868         // }\r
1869         // try {\r
1870         // rootView.setSize(alloc.width, alloc.height);\r
1871         // Enumeration components = constraints.keys();\r
1872         // while (components.hasMoreElements()) {\r
1873         // Component comp = (Component) components.nextElement();\r
1874         // View v = (View) constraints.get(comp);\r
1875         // Shape ca = calculateViewPosition(alloc, v);\r
1876         // if (ca != null) {\r
1877         // Rectangle compAlloc = (ca instanceof Rectangle) ?\r
1878         // (Rectangle) ca : ca.getBounds();\r
1879         // comp.setBounds(compAlloc);\r
1880         // }\r
1881         // }\r
1882         // } finally {\r
1883         // if (doc instanceof AbstractDocument) {\r
1884         // ((AbstractDocument)doc).readUnlock();\r
1885         // }\r
1886         // }\r
1887         // }\r
1888         // }\r
1889         // }\r
1890         //\r
1891         // /**\r
1892         // * Find the Shape representing the given view.\r
1893         // */\r
1894         // Shape calculateViewPosition(Shape alloc, View v) {\r
1895         // int pos = v.getStartOffset();\r
1896         // View child = null;\r
1897         // for (View parent = rootView; (parent != null) && (parent != v); parent =\r
1898         // child) {\r
1899         // int index = parent.getViewIndex(pos, Position.Bias.Forward);\r
1900         // alloc = parent.getChildAllocation(index, alloc);\r
1901         // child = parent.getView(index);\r
1902         // }\r
1903         // return (child != null) ? alloc : null;\r
1904         // }\r
1905         //\r
1906         // /**\r
1907         // * Adds the specified component to the layout, using the specified\r
1908         // * constraint object. We only store those components that were added\r
1909         // * with a constraint that is of type View.\r
1910         // *\r
1911         // * @param comp the component to be added\r
1912         // * @param constraint where/how the component is added to the layout.\r
1913         // */\r
1914         // public void addLayoutComponent(Component comp, Object constraint) {\r
1915         // if (constraint instanceof View) {\r
1916         // if (constraints == null) {\r
1917         // constraints = new Hashtable(7);\r
1918         // }\r
1919         // constraints.put(comp, constraint);\r
1920         // }\r
1921         // }\r
1922         //\r
1923         // /**\r
1924         // * Returns the maximum size of this component.\r
1925         // * @see jsjava.awt.Component#getMinimumSize()\r
1926         // * @see jsjava.awt.Component#getPreferredSize()\r
1927         // * @see LayoutManager\r
1928         // */\r
1929         // public Dimension maximumLayoutSize(Container target) {\r
1930         // // should not be called (JComponent uses UI instead)\r
1931         // return null;\r
1932         // }\r
1933         //\r
1934         // /**\r
1935         // * Returns the alignment along the x axis. This specifies how\r
1936         // * the component would like to be aligned relative to other\r
1937         // * components. The value should be a number between 0 and 1\r
1938         // * where 0 represents alignment along the origin, 1 is aligned\r
1939         // * the furthest away from the origin, 0.5 is centered, etc.\r
1940         // */\r
1941         // public float getLayoutAlignmentX(Container target) {\r
1942         // return 0.5f;\r
1943         // }\r
1944         //\r
1945         // /**\r
1946         // * Returns the alignment along the y axis. This specifies how\r
1947         // * the component would like to be aligned relative to other\r
1948         // * components. The value should be a number between 0 and 1\r
1949         // * where 0 represents alignment along the origin, 1 is aligned\r
1950         // * the furthest away from the origin, 0.5 is centered, etc.\r
1951         // */\r
1952         // public float getLayoutAlignmentY(Container target) {\r
1953         // return 0.5f;\r
1954         // }\r
1955         //\r
1956         // /**\r
1957         // * Invalidates the layout, indicating that if the layout manager\r
1958         // * has cached information it should be discarded.\r
1959         // */\r
1960         // public void invalidateLayout(Container target) {\r
1961         // }\r
1962         //\r
1963         // /**\r
1964         // * The "layout constraints" for the LayoutManager2 implementation.\r
1965         // * These are View objects for those components that are represented\r
1966         // * by a View in the View tree.\r
1967         // */\r
1968         // private Hashtable constraints;\r
1969         //\r
1970         // private boolean i18nView = false;\r
1971         // }\r
1972 \r
1973         /**\r
1974          * Wrapper for text actions to return isEnabled false in case editor is non\r
1975          * editable\r
1976          */\r
1977         class TextActionWrapper extends TextAction {\r
1978                 public TextActionWrapper(TextAction action) {\r
1979                         super((String) action.getValue(Action.NAME));\r
1980                         this.action = action;\r
1981                 }\r
1982 \r
1983                 /**\r
1984                  * The operation to perform when this action is triggered.\r
1985                  * \r
1986                  * @param e\r
1987                  *          the action event\r
1988                  */\r
1989                 public void actionPerformed(ActionEvent e) {\r
1990                         action.actionPerformed(e);\r
1991                 }\r
1992 \r
1993                 public boolean isEnabled() {\r
1994                         return (editor == null || editor.isEditable()) ? action.isEnabled()\r
1995                                         : false;\r
1996                 }\r
1997 \r
1998                 TextAction action = null;\r
1999         }\r
2000 \r
2001         /**\r
2002          * Registered in the ActionMap.\r
2003          */\r
2004         class FocusAction extends AbstractAction {\r
2005 \r
2006                 public void actionPerformed(ActionEvent e) {\r
2007                         editor.requestFocus();\r
2008                 }\r
2009 \r
2010                 public boolean isEnabled() {\r
2011                         return editor.isEditable();\r
2012                 }\r
2013         }\r
2014 \r
2015         boolean handleEnter(int eventType) {\r
2016                 return false;\r
2017         }\r
2018 \r
2019         String bgcolor0;\r
2020         \r
2021         public void setEditable(boolean editable) {\r
2022                 \r
2023                 this.editable = editable;\r
2024                 if (domNode == null)\r
2025                         return;\r
2026                 if (c.isBackgroundSet())\r
2027                         bgcolor0 = JSToolkit.getCSSColor(c.getBackground());\r
2028                 if (editable) {\r
2029                         domNode.removeAttribute("readOnly");\r
2030                         if (bgcolor0 != null)\r
2031                                 DOMNode.setStyles(domNode, "background-color", bgcolor0);\r
2032                 } else {\r
2033                         DOMNode.setAttr(domNode, "readOnly", "true");\r
2034                         if (c.isBackgroundSet()) {\r
2035                                 bgcolor0 = JSToolkit.getCSSColor(c.getBackground());\r
2036                         } else {\r
2037                                 if (bgcolor0 == null)\r
2038                                         bgcolor0 = domNode.getStyle("background-color");\r
2039                         }\r
2040                         DOMNode.setStyles(domNode, "background-color", "rgba(0,0,0,0)");\r
2041                 }\r
2042 \r
2043         }\r
2044 \r
2045         // private static DragListener getDragListener() {\r
2046         // synchronized(DragListener.class) {\r
2047         // DragListener listener =\r
2048         // (DragListener)AppContext.getAppContext().\r
2049         // get(DragListener.class);\r
2050         //\r
2051         // if (listener == null) {\r
2052         // listener = new DragListener();\r
2053         // AppContext.getAppContext().put(DragListener.class, listener);\r
2054         // }\r
2055         //\r
2056         // return listener;\r
2057         // }\r
2058         // }\r
2059         //\r
2060         // /**\r
2061         // * Listens for mouse events for the purposes of detecting drag gestures.\r
2062         // * BasicTextUI will maintain one of these per AppContext.\r
2063         // */\r
2064         // static class DragListener extends MouseInputAdapter\r
2065         // implements BeforeDrag {\r
2066         //\r
2067         // private boolean dragStarted;\r
2068         //\r
2069         // public void dragStarting(MouseEvent me) {\r
2070         // dragStarted = true;\r
2071         // }\r
2072         //\r
2073         // public void mousePressed(MouseEvent e) {\r
2074         // JTextComponent c = (JTextComponent)e.getSource();\r
2075         // if (c.getDragEnabled()) {\r
2076         // dragStarted = false;\r
2077         // if (isDragPossible(e) && DragRecognitionSupport.mousePressed(e)) {\r
2078         // e.consume();\r
2079         // }\r
2080         // }\r
2081         // }\r
2082         //\r
2083         // public void mouseReleased(MouseEvent e) {\r
2084         // JTextComponent c = (JTextComponent)e.getSource();\r
2085         // if (c.getDragEnabled()) {\r
2086         // if (dragStarted) {\r
2087         // e.consume();\r
2088         // }\r
2089         //\r
2090         // DragRecognitionSupport.mouseReleased(e);\r
2091         // }\r
2092         // }\r
2093         //\r
2094         // public void mouseDragged(MouseEvent e) {\r
2095         // JTextComponent c = (JTextComponent)e.getSource();\r
2096         // if (c.getDragEnabled()) {\r
2097         // if (dragStarted || DragRecognitionSupport.mouseDragged(e, this)) {\r
2098         // e.consume();\r
2099         // }\r
2100         // }\r
2101         // }\r
2102         //\r
2103         // /**\r
2104         // * Determines if the following are true:\r
2105         // * <ul>\r
2106         // * <li>the component is enabled\r
2107         // * <li>the press event is located over a selection\r
2108         // * </ul>\r
2109         // */\r
2110         // protected boolean isDragPossible(MouseEvent e) {\r
2111         // JTextComponent c = (JTextComponent)e.getSource();\r
2112         // if (c.isEnabled()) {\r
2113         // Caret caret = c.getCaret();\r
2114         // int dot = caret.getDot();\r
2115         // int mark = caret.getMark();\r
2116         // if (dot != mark) {\r
2117         // Point p = new Point(e.getX(), e.getY());\r
2118         // int pos = c.viewToModel(p);\r
2119         //\r
2120         // int p0 = Math.min(dot, mark);\r
2121         // int p1 = Math.max(dot, mark);\r
2122         // if ((pos >= p0) && (pos < p1)) {\r
2123         // return true;\r
2124         // }\r
2125         // }\r
2126         // }\r
2127         // return false;\r
2128         // }\r
2129         // }\r
2130 \r
2131         // static class TextTransferHandler extends TransferHandler implements\r
2132         // UIResource {\r
2133         //\r
2134         // private JTextComponent exportComp;\r
2135         // private boolean shouldRemove;\r
2136         // private int p0;\r
2137         // private int p1;\r
2138         //\r
2139         // /**\r
2140         // * Whether or not this is a drop using\r
2141         // * <code>DropMode.INSERT</code>.\r
2142         // */\r
2143         // private boolean modeBetween = false;\r
2144         //\r
2145         // /**\r
2146         // * Whether or not this is a drop.\r
2147         // */\r
2148         // private boolean isDrop = false;\r
2149         //\r
2150         // /**\r
2151         // * The drop action.\r
2152         // */\r
2153         // private int dropAction = MOVE;\r
2154         //\r
2155         // /**\r
2156         // * The drop bias.\r
2157         // */\r
2158         // private Position.Bias dropBias;\r
2159         //\r
2160         // /**\r
2161         // * Try to find a flavor that can be used to import a Transferable.\r
2162         // * The set of usable flavors are tried in the following order:\r
2163         // * <ol>\r
2164         // * <li>First, an attempt is made to find a flavor matching the content type\r
2165         // * of the EditorKit for the component.\r
2166         // * <li>Second, an attempt to find a text/plain flavor is made.\r
2167         // * <li>Third, an attempt to find a flavor representing a String reference\r
2168         // * in the same VM is made.\r
2169         // * <li>Lastly, DataFlavor.stringFlavor is searched for.\r
2170         // * </ol>\r
2171         // */\r
2172         // protected DataFlavor getImportFlavor(DataFlavor[] flavors, JTextComponent\r
2173         // c) {\r
2174         // DataFlavor plainFlavor = null;\r
2175         // DataFlavor refFlavor = null;\r
2176         // DataFlavor stringFlavor = null;\r
2177         //\r
2178         // if (c instanceof JEditorPane) {\r
2179         // for (int i = 0; i < flavors.length; i++) {\r
2180         // String mime = flavors[i].getMimeType();\r
2181         // if (mime.startsWith(((JEditorPane)c).getEditorKit().getContentType())) {\r
2182         // return flavors[i];\r
2183         // } else if (plainFlavor == null && mime.startsWith("text/plain")) {\r
2184         // plainFlavor = flavors[i];\r
2185         // } else if (refFlavor == null &&\r
2186         // mime.startsWith("application/x-java-jvm-local-objectref")\r
2187         // && flavors[i].getRepresentationClass() == jsjava.lang.String.class) {\r
2188         // refFlavor = flavors[i];\r
2189         // } else if (stringFlavor == null &&\r
2190         // flavors[i].equals(DataFlavor.stringFlavor)) {\r
2191         // stringFlavor = flavors[i];\r
2192         // }\r
2193         // }\r
2194         // if (plainFlavor != null) {\r
2195         // return plainFlavor;\r
2196         // } else if (refFlavor != null) {\r
2197         // return refFlavor;\r
2198         // } else if (stringFlavor != null) {\r
2199         // return stringFlavor;\r
2200         // }\r
2201         // return null;\r
2202         // }\r
2203         //\r
2204         //\r
2205         // for (int i = 0; i < flavors.length; i++) {\r
2206         // String mime = flavors[i].getMimeType();\r
2207         // if (mime.startsWith("text/plain")) {\r
2208         // return flavors[i];\r
2209         // } else if (refFlavor == null &&\r
2210         // mime.startsWith("application/x-java-jvm-local-objectref")\r
2211         // && flavors[i].getRepresentationClass() == jsjava.lang.String.class) {\r
2212         // refFlavor = flavors[i];\r
2213         // } else if (stringFlavor == null &&\r
2214         // flavors[i].equals(DataFlavor.stringFlavor)) {\r
2215         // stringFlavor = flavors[i];\r
2216         // }\r
2217         // }\r
2218         // if (refFlavor != null) {\r
2219         // return refFlavor;\r
2220         // } else if (stringFlavor != null) {\r
2221         // return stringFlavor;\r
2222         // }\r
2223         // return null;\r
2224         // }\r
2225         //\r
2226         // /**\r
2227         // * Import the given stream data into the text component.\r
2228         // */\r
2229         // protected void handleReaderImport(Reader in, JTextComponent c, boolean\r
2230         // useRead)\r
2231         // throws BadLocationException, IOException {\r
2232         // if (useRead) {\r
2233         // int startPosition = c.getSelectionStart();\r
2234         // int endPosition = c.getSelectionEnd();\r
2235         // int length = endPosition - startPosition;\r
2236         // EditorKit kit = c.getUI().getEditorKit(c);\r
2237         // Document doc = c.getDocument();\r
2238         // if (length > 0) {\r
2239         // doc.remove(startPosition, length);\r
2240         // }\r
2241         // kit.read(in, doc, startPosition);\r
2242         // } else {\r
2243         // char[] buff = new char[1024];\r
2244         // int nch;\r
2245         // boolean lastWasCR = false;\r
2246         // int last;\r
2247         // StringBuffer sbuff = null;\r
2248         //\r
2249         // // Read in a block at a time, mapping \r\n to \n, as well as single\r
2250         // // \r to \n.\r
2251         // while ((nch = in.read(buff, 0, buff.length)) != -1) {\r
2252         // if (sbuff == null) {\r
2253         // sbuff = new StringBuffer(nch);\r
2254         // }\r
2255         // last = 0;\r
2256         // for(int counter = 0; counter < nch; counter++) {\r
2257         // switch(buff[counter]) {\r
2258         // case '\r':\r
2259         // if (lastWasCR) {\r
2260         // if (counter == 0) {\r
2261         // sbuff.append('\n');\r
2262         // } else {\r
2263         // buff[counter - 1] = '\n';\r
2264         // }\r
2265         // } else {\r
2266         // lastWasCR = true;\r
2267         // }\r
2268         // break;\r
2269         // case '\n':\r
2270         // if (lastWasCR) {\r
2271         // if (counter > (last + 1)) {\r
2272         // sbuff.append(buff, last, counter - last - 1);\r
2273         // }\r
2274         // // else nothing to do, can skip \r, next write will\r
2275         // // write \n\r
2276         // lastWasCR = false;\r
2277         // last = counter;\r
2278         // }\r
2279         // break;\r
2280         // default:\r
2281         // if (lastWasCR) {\r
2282         // if (counter == 0) {\r
2283         // sbuff.append('\n');\r
2284         // } else {\r
2285         // buff[counter - 1] = '\n';\r
2286         // }\r
2287         // lastWasCR = false;\r
2288         // }\r
2289         // break;\r
2290         // }\r
2291         // }\r
2292         // if (last < nch) {\r
2293         // if (lastWasCR) {\r
2294         // if (last < (nch - 1)) {\r
2295         // sbuff.append(buff, last, nch - last - 1);\r
2296         // }\r
2297         // } else {\r
2298         // sbuff.append(buff, last, nch - last);\r
2299         // }\r
2300         // }\r
2301         // }\r
2302         // if (lastWasCR) {\r
2303         // sbuff.append('\n');\r
2304         // }\r
2305         // c.replaceSelection(sbuff != null ? sbuff.toString() : "");\r
2306         // }\r
2307         // }\r
2308         //\r
2309         // // --- TransferHandler methods ------------------------------------\r
2310         //\r
2311         // /**\r
2312         // * This is the type of transfer actions supported by the source. Some models\r
2313         // are\r
2314         // * not mutable, so a transfer operation of COPY only should\r
2315         // * be advertised in that case.\r
2316         // *\r
2317         // * @param c The component holding the data to be transfered. This\r
2318         // * argument is provided to enable sharing of TransferHandlers by\r
2319         // * multiple components.\r
2320         // * @return This is implemented to return NONE if the component is a\r
2321         // JPasswordField\r
2322         // * since exporting data via user gestures is not allowed. If the text\r
2323         // component is\r
2324         // * editable, COPY_OR_MOVE is returned, otherwise just COPY is allowed.\r
2325         // */\r
2326         // public int getSourceActions(JComponent c) {\r
2327         // if (c instanceof JPasswordField &&\r
2328         // c.getClientProperty("JPasswordField.cutCopyAllowed") !=\r
2329         // Boolean.TRUE) {\r
2330         // return NONE;\r
2331         // }\r
2332         //\r
2333         // return ((JTextComponent)c).isEditable() ? COPY_OR_MOVE : COPY;\r
2334         // }\r
2335         //\r
2336         // /**\r
2337         // * Create a Transferable to use as the source for a data transfer.\r
2338         // *\r
2339         // * @param comp The component holding the data to be transfered. This\r
2340         // * argument is provided to enable sharing of TransferHandlers by\r
2341         // * multiple components.\r
2342         // * @return The representation of the data to be transfered.\r
2343         // *\r
2344         // */\r
2345         // protected Transferable createTransferable(JComponent comp) {\r
2346         // exportComp = (JTextComponent)comp;\r
2347         // shouldRemove = true;\r
2348         // p0 = exportComp.getSelectionStart();\r
2349         // p1 = exportComp.getSelectionEnd();\r
2350         // return (p0 != p1) ? (new TextTransferable(exportComp, p0, p1)) : null;\r
2351         // }\r
2352         //\r
2353         // /**\r
2354         // * This method is called after data has been exported. This method should\r
2355         // remove\r
2356         // * the data that was transfered if the action was MOVE.\r
2357         // *\r
2358         // * @param source The component that was the source of the data.\r
2359         // * @param data The data that was transferred or possibly null\r
2360         // * if the action is <code>NONE</code>.\r
2361         // * @param action The actual action that was performed.\r
2362         // */\r
2363         // protected void exportDone(JComponent source, Transferable data, int action)\r
2364         // {\r
2365         // // only remove the text if shouldRemove has not been set to\r
2366         // // false by importData and only if the action is a move\r
2367         // if (shouldRemove && action == MOVE) {\r
2368         // TextTransferable t = (TextTransferable)data;\r
2369         // t.removeText();\r
2370         // }\r
2371         //\r
2372         // exportComp = null;\r
2373         // }\r
2374         //\r
2375         // public boolean importData(TransferSupport support) {\r
2376         // isDrop = support.isDrop();\r
2377         //\r
2378         // if (isDrop) {\r
2379         // modeBetween =\r
2380         // ((JTextComponent)support.getComponent()).getDropMode() == DropMode.INSERT;\r
2381         //\r
2382         // dropBias =\r
2383         // ((JTextComponent.DropLocation)support.getDropLocation()).getBias();\r
2384         //\r
2385         // dropAction = support.getDropAction();\r
2386         // }\r
2387         //\r
2388         // try {\r
2389         // return super.importData(support);\r
2390         // } finally {\r
2391         // isDrop = false;\r
2392         // modeBetween = false;\r
2393         // dropBias = null;\r
2394         // dropAction = MOVE;\r
2395         // }\r
2396         // }\r
2397         //\r
2398         // /**\r
2399         // * This method causes a transfer to a component from a clipboard or a\r
2400         // * DND drop operation. The Transferable represents the data to be\r
2401         // * imported into the component.\r
2402         // *\r
2403         // * @param comp The component to receive the transfer. This\r
2404         // * argument is provided to enable sharing of TransferHandlers by\r
2405         // * multiple components.\r
2406         // * @param t The data to import\r
2407         // * @return true if the data was inserted into the component, false\r
2408         // otherwise.\r
2409         // */\r
2410         // public boolean importData(JComponent comp, Transferable t) {\r
2411         // JTextComponent c = (JTextComponent)comp;\r
2412         //\r
2413         // int pos = modeBetween\r
2414         // ? ((JTextComponent.DropLocation)c.getDropLocation()).getIndex()\r
2415         // : c.getCaretPosition();\r
2416         //\r
2417         // // if we are importing to the same component that we exported from\r
2418         // // then don't actually do anything if the drop location is inside\r
2419         // // the drag location and set shouldRemove to false so that exportDone\r
2420         // // knows not to remove any data\r
2421         // if (dropAction == MOVE && c == exportComp && pos >= p0 && pos <= p1) {\r
2422         // shouldRemove = false;\r
2423         // return true;\r
2424         // }\r
2425         //\r
2426         // boolean imported = false;\r
2427         // DataFlavor importFlavor = getImportFlavor(t.getTransferDataFlavors(), c);\r
2428         // if (importFlavor != null) {\r
2429         // try {\r
2430         // boolean useRead = false;\r
2431         // if (comp instanceof JEditorPane) {\r
2432         // JEditorPane ep = (JEditorPane)comp;\r
2433         // if (!ep.getContentType().startsWith("text/plain") &&\r
2434         // importFlavor.getMimeType().startsWith(ep.getContentType())) {\r
2435         // useRead = true;\r
2436         // }\r
2437         // }\r
2438         // InputContext ic = c.getInputContext();\r
2439         // if (ic != null) {\r
2440         // ic.endComposition();\r
2441         // }\r
2442         // Reader r = importFlavor.getReaderForText(t);\r
2443         //\r
2444         // if (modeBetween) {\r
2445         // Caret caret = c.getCaret();\r
2446         // if (caret instanceof DefaultCaret) {\r
2447         // ((DefaultCaret)caret).setDot(pos, dropBias);\r
2448         // } else {\r
2449         // c.setCaretPosition(pos);\r
2450         // }\r
2451         // }\r
2452         //\r
2453         // handleReaderImport(r, c, useRead);\r
2454         //\r
2455         // if (isDrop) {\r
2456         // c.requestFocus();\r
2457         // Caret caret = c.getCaret();\r
2458         // if (caret instanceof DefaultCaret) {\r
2459         // int newPos = caret.getDot();\r
2460         // Position.Bias newBias = ((DefaultCaret)caret).getDotBias();\r
2461         //\r
2462         // ((DefaultCaret)caret).setDot(pos, dropBias);\r
2463         // ((DefaultCaret)caret).moveDot(newPos, newBias);\r
2464         // } else {\r
2465         // c.select(pos, c.getCaretPosition());\r
2466         // }\r
2467         // }\r
2468         //\r
2469         // imported = true;\r
2470         // } catch (UnsupportedFlavorException ufe) {\r
2471         // } catch (BadLocationException ble) {\r
2472         // } catch (IOException ioe) {\r
2473         // }\r
2474         // }\r
2475         // return imported;\r
2476         // }\r
2477         //\r
2478         // /**\r
2479         // * This method indicates if a component would accept an import of the given\r
2480         // * set of data flavors prior to actually attempting to import it.\r
2481         // *\r
2482         // * @param comp The component to receive the transfer. This\r
2483         // * argument is provided to enable sharing of TransferHandlers by\r
2484         // * multiple components.\r
2485         // * @param flavors The data formats available\r
2486         // * @return true if the data can be inserted into the component, false\r
2487         // otherwise.\r
2488         // */\r
2489         // public boolean canImport(JComponent comp, DataFlavor[] flavors) {\r
2490         // JTextComponent c = (JTextComponent)comp;\r
2491         // if (!(c.isEditable() && c.isEnabled())) {\r
2492         // return false;\r
2493         // }\r
2494         // return (getImportFlavor(flavors, c) != null);\r
2495         // }\r
2496         //\r
2497         // /**\r
2498         // * A possible implementation of the Transferable interface\r
2499         // * for text components. For a JEditorPane with a rich set\r
2500         // * of EditorKit implementations, conversions could be made\r
2501         // * giving a wider set of formats. This is implemented to\r
2502         // * offer up only the active content type and text/plain\r
2503         // * (if that is not the active format) since that can be\r
2504         // * extracted from other formats.\r
2505         // */\r
2506         // static class TextTransferable extends BasicTransferable {\r
2507         //\r
2508         // TextTransferable(JTextComponent c, int start, int end) {\r
2509         // super(null, null);\r
2510         //\r
2511         // this.c = c;\r
2512         //\r
2513         // Document doc = c.getDocument();\r
2514         //\r
2515         // try {\r
2516         // p0 = doc.createPosition(start);\r
2517         // p1 = doc.createPosition(end);\r
2518         //\r
2519         // plainData = c.getSelectedText();\r
2520         //\r
2521         // if (c instanceof JEditorPane) {\r
2522         // JEditorPane ep = (JEditorPane)c;\r
2523         //\r
2524         // mimeType = ep.getContentType();\r
2525         //\r
2526         // if (mimeType.startsWith("text/plain")) {\r
2527         // return;\r
2528         // }\r
2529         //\r
2530         // StringWriter sw = new StringWriter(p1.getOffset() - p0.getOffset());\r
2531         // ep.getEditorKit().write(sw, doc, p0.getOffset(), p1.getOffset() -\r
2532         // p0.getOffset());\r
2533         //\r
2534         // if (mimeType.startsWith("text/html")) {\r
2535         // htmlData = sw.toString();\r
2536         // } else {\r
2537         // richText = sw.toString();\r
2538         // }\r
2539         // }\r
2540         // } catch (BadLocationException ble) {\r
2541         // } catch (IOException ioe) {\r
2542         // }\r
2543         // }\r
2544         //\r
2545         // void removeText() {\r
2546         // if ((p0 != null) && (p1 != null) && (p0.getOffset() != p1.getOffset())) {\r
2547         // try {\r
2548         // Document doc = c.getDocument();\r
2549         // doc.remove(p0.getOffset(), p1.getOffset() - p0.getOffset());\r
2550         // } catch (BadLocationException e) {\r
2551         // }\r
2552         // }\r
2553         // }\r
2554         //\r
2555         // // ---- EditorKit other than plain or HTML text -----------------------\r
2556         //\r
2557         // /**\r
2558         // * If the EditorKit is not for text/plain or text/html, that format\r
2559         // * is supported through the "richer flavors" part of BasicTransferable.\r
2560         // */\r
2561         // protected DataFlavor[] getRicherFlavors() {\r
2562         // if (richText == null) {\r
2563         // return null;\r
2564         // }\r
2565         //\r
2566         // try {\r
2567         // DataFlavor[] flavors = new DataFlavor[3];\r
2568         // flavors[0] = new DataFlavor(mimeType + ";class=java.lang.String");\r
2569         // flavors[1] = new DataFlavor(mimeType + ";class=java.io.Reader");\r
2570         // flavors[2] = new DataFlavor(mimeType +\r
2571         // ";class=java.io.InputStream;charset=unicode");\r
2572         // return flavors;\r
2573         // } catch (ClassNotFoundException cle) {\r
2574         // // fall through to unsupported (should not happen)\r
2575         // }\r
2576         //\r
2577         // return null;\r
2578         // }\r
2579         //\r
2580         // /**\r
2581         // * The only richer format supported is the file list flavor\r
2582         // */\r
2583         // protected Object getRicherData(DataFlavor flavor) throws\r
2584         // UnsupportedFlavorException {\r
2585         // if (richText == null) {\r
2586         // return null;\r
2587         // }\r
2588         //\r
2589         // if (String.class.equals(flavor.getRepresentationClass())) {\r
2590         // return richText;\r
2591         // } else if (Reader.class.equals(flavor.getRepresentationClass())) {\r
2592         // return new StringReader(richText);\r
2593         // } else if (InputStream.class.equals(flavor.getRepresentationClass())) {\r
2594         // return new StringBufferInputStream(richText);\r
2595         // }\r
2596         // throw new UnsupportedFlavorException(flavor);\r
2597         // }\r
2598         //\r
2599         // Position p0;\r
2600         // Position p1;\r
2601         // String mimeType;\r
2602         // String richText;\r
2603         // JTextComponent c;\r
2604         // }\r
2605         //\r
2606         // }\r
2607 \r
2608         // /**\r
2609         // * Creates a new UI.\r
2610         // */\r
2611         // public JSTextUI() {\r
2612         // // painted = false;\r
2613         // }\r
2614         //\r
2615         // /**\r
2616         // * Creates the object to use for a caret. By default an\r
2617         // * instance of BasicCaret is created. This method\r
2618         // * can be redefined to provide something else that implements\r
2619         // * the InputPosition interface or a subclass of JCaret.\r
2620         // *\r
2621         // * @return the caret object\r
2622         // */\r
2623         // protected Caret createCaret() {\r
2624         // return new BasicCaret();\r
2625         // }\r
2626         //\r
2627         // /**\r
2628         // * Creates the object to use for adding highlights. By default\r
2629         // * an instance of BasicHighlighter is created. This method\r
2630         // * can be redefined to provide something else that implements\r
2631         // * the Highlighter interface or a subclass of DefaultHighlighter.\r
2632         // *\r
2633         // * @return the highlighter\r
2634         // */\r
2635         // protected Highlighter createHighlighter() {\r
2636         // return new BasicHighlighter();\r
2637         // }\r
2638         //\r
2639         // /**\r
2640         // * Fetches the name of the keymap that will be installed/used\r
2641         // * by default for this UI. This is implemented to create a\r
2642         // * name based upon the classname. The name is the the name\r
2643         // * of the class with the package prefix removed.\r
2644         // *\r
2645         // * @return the name\r
2646         // */\r
2647         // protected String getKeymapName() {\r
2648         // String nm = getClass().getName();\r
2649         // int index = nm.lastIndexOf('.');\r
2650         // if (index >= 0) {\r
2651         // nm = nm.substring(index+1, nm.length());\r
2652         // }\r
2653         // return nm;\r
2654         // }\r
2655         //\r
2656         // /**\r
2657         // * Creates the keymap to use for the text component, and installs\r
2658         // * any necessary bindings into it. By default, the keymap is\r
2659         // * shared between all instances of this type of TextUI. The\r
2660         // * keymap has the name defined by the getKeymapName method. If the\r
2661         // * keymap is not found, then DEFAULT_KEYMAP from JTextComponent is used.\r
2662         // * <p>\r
2663         // * The set of bindings used to create the keymap is fetched\r
2664         // * from the UIManager using a key formed by combining the\r
2665         // * {@link #getPropertyPrefix} method\r
2666         // * and the string <code>.keyBindings</code>. The type is expected\r
2667         // * to be <code>JTextComponent.KeyBinding[]</code>.\r
2668         // *\r
2669         // * @return the keymap\r
2670         // * @see #getKeymapName\r
2671         // * @see jsjavax.swing.text.JTextComponent\r
2672         // */\r
2673         // protected Keymap createKeymap() {\r
2674         // String nm = getKeymapName();\r
2675         // Keymap map = JTextComponent.getKeymap(nm);\r
2676         // if (map == null) {\r
2677         // Keymap parent = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);\r
2678         // map = JTextComponent.addKeymap(nm, parent);\r
2679         // String prefix = getPropertyPrefix();\r
2680         // Object o = DefaultLookup.get(editor, this,\r
2681         // prefix + ".keyBindings");\r
2682         // if ((o != null) && (o instanceof JTextComponent.KeyBinding[])) {\r
2683         // JTextComponent.KeyBinding[] bindings = (JTextComponent.KeyBinding[]) o;\r
2684         // JTextComponent.loadKeymap(map, bindings, getComponent().getActions());\r
2685         // }\r
2686         // }\r
2687         // return map;\r
2688         // }\r
2689         //\r
2690         // /**\r
2691         // * This method gets called when a bound property is changed\r
2692         // * on the associated JTextComponent. This is a hook\r
2693         // * which UI implementations may change to reflect how the\r
2694         // * UI displays bound properties of JTextComponent subclasses.\r
2695         // * This is implemented to do nothing (i.e. the response to\r
2696         // * properties in JTextComponent itself are handled prior\r
2697         // * to calling this method).\r
2698         // *\r
2699         // * This implementation updates the background of the text\r
2700         // * component if the editable and/or enabled state changes.\r
2701         // *\r
2702         // * @param evt the property change event\r
2703         // */\r
2704         // protected void propertyChange(PropertyChangeEvent evt) {\r
2705         // if (evt.getPropertyName().equals("editable") ||\r
2706         // evt.getPropertyName().equals("enabled")) {\r
2707         //\r
2708         // updateBackground((JTextComponent)evt.getSource());\r
2709         // }\r
2710         // }\r
2711         //\r
2712         // /**\r
2713         // * Updates the background of the text component based on whether the\r
2714         // * text component is editable and/or enabled.\r
2715         // *\r
2716         // * @param c the JTextComponent that needs its background color updated\r
2717         // */\r
2718         // private void updateBackground(JTextComponent c) {\r
2719         // // This is a temporary workaround.\r
2720         // // This code does not correctly deal with Synth (Synth doesn't use\r
2721         // // properties like this), nor does it deal with the situation where\r
2722         // // the developer grabs the color from a JLabel and sets it as\r
2723         // // the background for a JTextArea in all look and feels. The problem\r
2724         // // scenario results if the Color obtained for the Label and TextArea\r
2725         // // is ==, which is the case for the windows look and feel.\r
2726         // // Until an appropriate solution is found, the code is being\r
2727         // // reverted to what it was before the original fix.\r
2728         // if (this instanceof sun.swing.plaf.synth.SynthUI ||\r
2729         // (c instanceof JTextArea)) {\r
2730         // return;\r
2731         // }\r
2732         // Color background = c.getBackground();\r
2733         // if (background instanceof UIResource) {\r
2734         // String prefix = getPropertyPrefix();\r
2735         //\r
2736         // Color disabledBG =\r
2737         // DefaultLookup.getColor(c, this, prefix + ".disabledBackground", null);\r
2738         // Color inactiveBG =\r
2739         // DefaultLookup.getColor(c, this, prefix + ".inactiveBackground", null);\r
2740         // Color bg =\r
2741         // DefaultLookup.getColor(c, this, prefix + ".background", null);\r
2742         //\r
2743         // /* In an ideal situation, the following check would not be necessary\r
2744         // * and we would replace the color any time the previous color was a\r
2745         // * UIResouce. However, it turns out that there is existing code that\r
2746         // * uses the following inadvisable pattern to turn a text area into\r
2747         // * what appears to be a multi-line label:\r
2748         // *\r
2749         // * JLabel label = new JLabel();\r
2750         // * JTextArea area = new JTextArea();\r
2751         // * area.setBackground(label.getBackground());\r
2752         // * area.setEditable(false);\r
2753         // *\r
2754         // * JLabel's default background is a UIResource. As such, just\r
2755         // * checking for UIResource would have us always changing the\r
2756         // * background away from what the developer wanted.\r
2757         // *\r
2758         // * Therefore, for JTextArea/JEditorPane, we'll additionally check\r
2759         // * that the color we're about to replace matches one that was\r
2760         // * installed by us from the UIDefaults.\r
2761         // */\r
2762         // if ((c instanceof JTextArea || c instanceof JEditorPane)\r
2763         // && background != disabledBG\r
2764         // && background != inactiveBG\r
2765         // && background != bg) {\r
2766         //\r
2767         // return;\r
2768         // }\r
2769         //\r
2770         // Color newColor = null;\r
2771         // if (!c.isEnabled()) {\r
2772         // newColor = disabledBG;\r
2773         // }\r
2774         // if (newColor == null && !c.isEditable()) {\r
2775         // newColor = inactiveBG;\r
2776         // }\r
2777         // if (newColor == null) {\r
2778         // newColor = bg;\r
2779         // }\r
2780         // if (newColor != null && newColor != background) {\r
2781         // c.setBackground(newColor);\r
2782         // }\r
2783         // }\r
2784         // }\r
2785         //\r
2786         // /**\r
2787         // * Gets the name used as a key to look up properties through the\r
2788         // * UIManager. This is used as a prefix to all the standard\r
2789         // * text properties.\r
2790         // *\r
2791         // * @return the name\r
2792         // */\r
2793         // protected abstract String getPropertyPrefix();\r
2794 \r
2795 }\r