KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JTextPane


1 /*
2  * @(#)JTextPane.java 1.90 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing;
8
9 import java.awt.*;
10 import java.awt.event.ActionEvent JavaDoc;
11
12 import java.io.ObjectOutputStream JavaDoc;
13 import java.io.ObjectInputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15
16 import javax.swing.text.*;
17 import javax.swing.event.*;
18 import javax.swing.plaf.*;
19
20 /**
21  * A text component that can be marked up with attributes that are
22  * represented graphically.
23  * You can find how-to information and examples of using text panes in
24  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/text.html">Using Text Components</a>,
25  * a section in <em>The Java Tutorial.</em>
26  *
27  * <p>
28  * This component models paragraphs
29  * that are composed of runs of character level attributes. Each
30  * paragraph may have a logical style attached to it which contains
31  * the default attributes to use if not overridden by attributes set
32  * on the paragraph or character run. Components and images may
33  * be embedded in the flow of text.
34  * <p>
35  * <dt><b><font size=+1>Newlines</font></b>
36  * <dd>
37  * For a discussion on how newlines are handled, see
38  * <a HREF="text/DefaultEditorKit.html">DefaultEditorKit</a>.
39  * </dl>
40  *
41  * <p>
42  * <strong>Warning:</strong>
43  * Serialized objects of this class will not be compatible with
44  * future Swing releases. The current serialization support is
45  * appropriate for short term storage or RMI between applications running
46  * the same version of Swing. As of 1.4, support for long term storage
47  * of all JavaBeans<sup><font size="-2">TM</font></sup>
48  * has been added to the <code>java.beans</code> package.
49  * Please see {@link java.beans.XMLEncoder}.
50  *
51  * @beaninfo
52  * attribute: isContainer true
53  * description: A text component that can be marked up with attributes that are graphically represented.
54  *
55  * @author Timothy Prinzing
56  * @version 1.90 12/19/03
57  * @see javax.swing.text.StyledEditorKit
58  */

59 public class JTextPane extends JEditorPane JavaDoc {
60
61     /**
62      * Creates a new <code>JTextPane</code>. A new instance of
63      * <code>StyledEditorKit</code> is
64      * created and set, and the document model set to <code>null</code>.
65      */

66     public JTextPane() {
67         super();
68         setEditorKit(createDefaultEditorKit());
69     }
70
71     /**
72      * Creates a new <code>JTextPane</code>, with a specified document model.
73      * A new instance of <code>javax.swing.text.StyledEditorKit</code>
74      * is created and set.
75      *
76      * @param doc the document model
77      */

78     public JTextPane(StyledDocument doc) {
79         this();
80         setStyledDocument(doc);
81     }
82
83     /**
84      * Returns the class ID for the UI.
85      *
86      * @return the string "TextPaneUI"
87      *
88      * @see JComponent#getUIClassID
89      * @see UIDefaults#getUI
90      */

91     public String JavaDoc getUIClassID() {
92         return uiClassID;
93     }
94
95     /**
96      * Associates the editor with a text document. This
97      * must be a <code>StyledDocument</code>.
98      *
99      * @param doc the document to display/edit
100      * @exception IllegalArgumentException if <code>doc</code> can't
101      * be narrowed to a <code>StyledDocument</code> which is the
102      * required type of model for this text component
103      */

104     public void setDocument(Document doc) {
105         if (doc instanceof StyledDocument) {
106             super.setDocument(doc);
107         } else {
108             throw new IllegalArgumentException JavaDoc("Model must be StyledDocument");
109         }
110     }
111
112     /**
113      * Associates the editor with a text document.
114      * The currently registered factory is used to build a view for
115      * the document, which gets displayed by the editor.
116      *
117      * @param doc the document to display/edit
118      */

119     public void setStyledDocument(StyledDocument doc) {
120         super.setDocument(doc);
121     }
122
123     /**
124      * Fetches the model associated with the editor.
125      *
126      * @return the model
127      */

128     public StyledDocument getStyledDocument() {
129         return (StyledDocument) getDocument();
130     }
131
132     /**
133      * Replaces the currently selected content with new content
134      * represented by the given string. If there is no selection
135      * this amounts to an insert of the given text. If there
136      * is no replacement text this amounts to a removal of the
137      * current selection. The replacement text will have the
138      * attributes currently defined for input at the point of
139      * insertion. If the document is not editable, beep and return.
140      * <p>
141      * This method is thread safe, although most Swing methods
142      * are not. Please see
143      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
144      * and Swing</A> for more information.
145      *
146      * @param content the content to replace the selection with
147      */

148     public void replaceSelection(String JavaDoc content) {
149         replaceSelection(content, true);
150     }
151
152     private void replaceSelection(String JavaDoc content, boolean checkEditable) {
153         if (checkEditable && !isEditable()) {
154         UIManager.getLookAndFeel().provideErrorFeedback(JTextPane.this);
155             return;
156         }
157         Document doc = getStyledDocument();
158         if (doc != null) {
159             try {
160                 Caret caret = getCaret();
161                 int p0 = Math.min(caret.getDot(), caret.getMark());
162                 int p1 = Math.max(caret.getDot(), caret.getMark());
163         AttributeSet attr = getInputAttributes().copyAttributes();
164                 if (doc instanceof AbstractDocument) {
165                     ((AbstractDocument)doc).replace(p0, p1 - p0, content,attr);
166                 }
167                 else {
168                     if (p0 != p1) {
169                         doc.remove(p0, p1 - p0);
170                     }
171                     if (content != null && content.length() > 0) {
172                         doc.insertString(p0, content, attr);
173                     }
174                 }
175             } catch (BadLocationException e) {
176             UIManager.getLookAndFeel().provideErrorFeedback(JTextPane.this);
177             }
178         }
179     }
180
181     /**
182      * Inserts a component into the document as a replacement
183      * for the currently selected content. If there is no
184      * selection the component is effectively inserted at the
185      * current position of the caret. This is represented in
186      * the associated document as an attribute of one character
187      * of content.
188      * <p>
189      * The component given is the actual component used by the
190      * JTextPane. Since components cannot be a child of more than
191      * one container, this method should not be used in situations
192      * where the model is shared by text components.
193      * <p>
194      * The component is placed relative to the text baseline
195      * according to the value returned by
196      * <code>Component.getAlignmentY</code>. For Swing components
197      * this value can be conveniently set using the method
198      * <code>JComponent.setAlignmentY</code>. For example, setting
199      * a value of <code>0.75</code> will cause 75 percent of the
200      * component to be above the baseline, and 25 percent of the
201      * component to be below the baseline.
202      * <p>
203      * This method is thread safe, although most Swing methods
204      * are not. Please see
205      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
206      * and Swing</A> for more information.
207      *
208      * @param c the component to insert
209      */

210     public void insertComponent(Component c) {
211         MutableAttributeSet inputAttributes = getInputAttributes();
212         inputAttributes.removeAttributes(inputAttributes);
213         StyleConstants.setComponent(inputAttributes, c);
214         replaceSelection(" ", false);
215         inputAttributes.removeAttributes(inputAttributes);
216     }
217
218     /**
219      * Inserts an icon into the document as a replacement
220      * for the currently selected content. If there is no
221      * selection the icon is effectively inserted at the
222      * current position of the caret. This is represented in
223      * the associated document as an attribute of one character
224      * of content.
225      * <p>
226      * This method is thread safe, although most Swing methods
227      * are not. Please see
228      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
229      * and Swing</A> for more information.
230      *
231      * @param g the icon to insert
232      * @see Icon
233      */

234     public void insertIcon(Icon JavaDoc g) {
235         MutableAttributeSet inputAttributes = getInputAttributes();
236         inputAttributes.removeAttributes(inputAttributes);
237         StyleConstants.setIcon(inputAttributes, g);
238         replaceSelection(" ", false);
239         inputAttributes.removeAttributes(inputAttributes);
240     }
241
242     /**
243      * Adds a new style into the logical style hierarchy. Style attributes
244      * resolve from bottom up so an attribute specified in a child
245      * will override an attribute specified in the parent.
246      *
247      * @param nm the name of the style (must be unique within the
248      * collection of named styles). The name may be <code>null</code>
249      * if the style is unnamed, but the caller is responsible
250      * for managing the reference returned as an unnamed style can't
251      * be fetched by name. An unnamed style may be useful for things
252      * like character attribute overrides such as found in a style
253      * run.
254      * @param parent the parent style. This may be <code>null</code>
255      * if unspecified
256      * attributes need not be resolved in some other style.
257      * @return the new <code>Style</code>
258      */

259     public Style addStyle(String JavaDoc nm, Style parent) {
260         StyledDocument doc = getStyledDocument();
261         return doc.addStyle(nm, parent);
262     }
263
264     /**
265      * Removes a named non-<code>null</code> style previously added to
266      * the document.
267      *
268      * @param nm the name of the style to remove
269      */

270     public void removeStyle(String JavaDoc nm) {
271         StyledDocument doc = getStyledDocument();
272         doc.removeStyle(nm);
273     }
274
275     /**
276      * Fetches a named non-<code>null</code> style previously added.
277      *
278      * @param nm the name of the style
279      * @return the <code>Style</code>
280      */

281     public Style getStyle(String JavaDoc nm) {
282         StyledDocument doc = getStyledDocument();
283         return doc.getStyle(nm);
284     }
285
286     /**
287      * Sets the logical style to use for the paragraph at the
288      * current caret position. If attributes aren't explicitly set
289      * for character and paragraph attributes they will resolve
290      * through the logical style assigned to the paragraph, which
291      * in term may resolve through some hierarchy completely
292      * independent of the element hierarchy in the document.
293      * <p>
294      * This method is thread safe, although most Swing methods
295      * are not. Please see
296      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
297      * and Swing</A> for more information.
298      *
299      * @param s the logical style to assign to the paragraph,
300      * or <code>null</code> for no style
301      */

302     public void setLogicalStyle(Style s) {
303         StyledDocument doc = getStyledDocument();
304         doc.setLogicalStyle(getCaretPosition(), s);
305     }
306
307     /**
308      * Fetches the logical style assigned to the paragraph represented
309      * by the current position of the caret, or <code>null</code>.
310      *
311      * @return the <code>Style</code>
312      */

313     public Style getLogicalStyle() {
314         StyledDocument doc = getStyledDocument();
315         return doc.getLogicalStyle(getCaretPosition());
316     }
317
318     /**
319      * Fetches the character attributes in effect at the
320      * current location of the caret, or <code>null</code>.
321      *
322      * @return the attributes, or <code>null</code>
323      */

324     public AttributeSet getCharacterAttributes() {
325         StyledDocument doc = getStyledDocument();
326         Element run = doc.getCharacterElement(getCaretPosition());
327         if (run != null) {
328             return run.getAttributes();
329         }
330         return null;
331     }
332
333     /**
334      * Applies the given attributes to character
335      * content. If there is a selection, the attributes
336      * are applied to the selection range. If there
337      * is no selection, the attributes are applied to
338      * the input attribute set which defines the attributes
339      * for any new text that gets inserted.
340      * <p>
341      * This method is thread safe, although most Swing methods
342      * are not. Please see
343      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
344      * and Swing</A> for more information.
345      *
346      * @param attr the attributes
347      * @param replace if true, then replace the existing attributes first
348      */

349     public void setCharacterAttributes(AttributeSet attr, boolean replace) {
350         int p0 = getSelectionStart();
351         int p1 = getSelectionEnd();
352         if (p0 != p1) {
353             StyledDocument doc = getStyledDocument();
354             doc.setCharacterAttributes(p0, p1 - p0, attr, replace);
355         } else {
356             MutableAttributeSet inputAttributes = getInputAttributes();
357             if (replace) {
358                 inputAttributes.removeAttributes(inputAttributes);
359             }
360             inputAttributes.addAttributes(attr);
361         }
362     }
363
364     /**
365      * Fetches the current paragraph attributes in effect
366      * at the location of the caret, or <code>null</code> if none.
367      *
368      * @return the attributes
369      */

370     public AttributeSet getParagraphAttributes() {
371         StyledDocument doc = getStyledDocument();
372         Element paragraph = doc.getParagraphElement(getCaretPosition());
373         if (paragraph != null) {
374             return paragraph.getAttributes();
375         }
376         return null;
377     }
378
379     /**
380      * Applies the given attributes to paragraphs. If
381      * there is a selection, the attributes are applied
382      * to the paragraphs that intersect the selection.
383      * If there is no selection, the attributes are applied
384      * to the paragraph at the current caret position.
385      * <p>
386      * This method is thread safe, although most Swing methods
387      * are not. Please see
388      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
389      * and Swing</A> for more information.
390      *
391      * @param attr the non-<code>null</code> attributes
392      * @param replace if true, replace the existing attributes first
393      */

394     public void setParagraphAttributes(AttributeSet attr, boolean replace) {
395         int p0 = getSelectionStart();
396         int p1 = getSelectionEnd();
397         StyledDocument doc = getStyledDocument();
398         doc.setParagraphAttributes(p0, p1 - p0, attr, replace);
399     }
400
401     /**
402      * Gets the input attributes for the pane.
403      *
404      * @return the attributes
405      */

406     public MutableAttributeSet getInputAttributes() {
407         return getStyledEditorKit().getInputAttributes();
408     }
409
410     /**
411      * Gets the editor kit.
412      *
413      * @return the editor kit
414      */

415     protected final StyledEditorKit getStyledEditorKit() {
416         return (StyledEditorKit) getEditorKit();
417     }
418
419     /**
420      * @see #getUIClassID
421      * @see #readObject
422      */

423     private static final String JavaDoc uiClassID = "TextPaneUI";
424
425
426     /**
427      * See <code>readObject</code> and <code>writeObject</code> in
428      * <code>JComponent</code> for more
429      * information about serialization in Swing.
430      *
431      * @param s the output stream
432      */

433     private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
434         s.defaultWriteObject();
435         if (getUIClassID().equals(uiClassID)) {
436             byte count = JComponent.getWriteObjCounter(this);
437             JComponent.setWriteObjCounter(this, --count);
438             if (count == 0 && ui != null) {
439                 ui.installUI(this);
440             }
441         }
442     }
443
444
445     // --- JEditorPane ------------------------------------
446

447     /**
448      * Creates the <code>EditorKit</code> to use by default. This
449      * is implemented to return <code>javax.swing.text.StyledEditorKit</code>.
450      *
451      * @return the editor kit
452      */

453     protected EditorKit createDefaultEditorKit() {
454         return new StyledEditorKit();
455     }
456
457     /**
458      * Sets the currently installed kit for handling
459      * content. This is the bound property that
460      * establishes the content type of the editor.
461      *
462      * @param kit the desired editor behavior
463      * @exception IllegalArgumentException if kit is not a
464      * <code>StyledEditorKit</code>
465      */

466     public final void setEditorKit(EditorKit kit) {
467         if (kit instanceof StyledEditorKit) {
468             super.setEditorKit(kit);
469         } else {
470             throw new IllegalArgumentException JavaDoc("Must be StyledEditorKit");
471         }
472     }
473
474     /**
475      * Returns a string representation of this <code>JTextPane</code>.
476      * This method
477      * is intended to be used only for debugging purposes, and the
478      * content and format of the returned string may vary between
479      * implementations. The returned string may be empty but may not
480      * be <code>null</code>.
481      *
482      * @return a string representation of this <code>JTextPane</code>
483      */

484     protected String JavaDoc paramString() {
485         return super.paramString();
486     }
487
488 }
489
Popular Tags