1 /* JTextPane.java -- A powerful text widget supporting styled text
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java.awt.Component;
43 import javax.swing.text.AbstractDocument;
44 import javax.swing.text.AttributeSet;
45 import javax.swing.text.BadLocationException;
46 import javax.swing.text.Caret;
47 import javax.swing.text.Document;
48 import javax.swing.text.EditorKit;
49 import javax.swing.text.Element;
50 import javax.swing.text.MutableAttributeSet;
51 import javax.swing.text.SimpleAttributeSet;
52 import javax.swing.text.Style;
53 import javax.swing.text.StyleConstants;
54 import javax.swing.text.StyledDocument;
55 import javax.swing.text.StyledEditorKit;
58 * A powerful text component that supports styled content as well as
59 * embedding images and components. It is entirely based on a
60 * {@link StyledDocument} content model and a {@link StyledEditorKit}.
62 * @author Roman Kennke (roman@kennke.org)
63 * @author Andrew Selkirk
65 public class JTextPane
69 * Creates a new <code>JTextPane</code> with a <code>null</code> document.
77 * Creates a new <code>JTextPane</code> and sets the specified
78 * <code>document</code>.
80 * @param document the content model to use
82 public JTextPane(StyledDocument document)
85 setStyledDocument(document);
89 * Returns the UI class ID. This is <code>TextPaneUI</code>.
91 * @return <code>TextPaneUI</code>
93 public String getUIClassID()
99 * Sets the content model for this <code>JTextPane</code>.
100 * <code>JTextPane</code> can only be used with {@link StyledDocument}s,
101 * if you try to set a different type of <code>Document</code>, an
102 * <code>IllegalArgumentException</code> is thrown.
104 * @param document the content model to set
106 * @throws IllegalArgumentException if <code>document</code> is not an
107 * instance of <code>StyledDocument</code>
109 * @see #setStyledDocument
111 public void setDocument(Document document)
113 if (document != null && !(document instanceof StyledDocument))
114 throw new IllegalArgumentException
115 ("JTextPane can only handle StyledDocuments");
117 setStyledDocument((StyledDocument) document);
121 * Returns the {@link StyledDocument} that is the content model for
122 * this <code>JTextPane</code>. This is a typed wrapper for
123 * {@link #getDocument()}.
125 * @return the content model of this <code>JTextPane</code>
127 public StyledDocument getStyledDocument()
129 return (StyledDocument) super.getDocument();
133 * Sets the content model for this <code>JTextPane</code>.
135 * @param document the content model to set
137 public void setStyledDocument(StyledDocument document)
139 super.setDocument(document);
143 * Replaces the currently selected text with the specified
144 * <code>content</code>. If there is no selected text, this results
145 * in a simple insertion at the current caret position. If there is
146 * no <code>content</code> specified, this results in the selection
149 * @param content the text with which the selection is replaced
151 public void replaceSelection(String content)
153 Caret caret = getCaret();
154 StyledDocument doc = getStyledDocument();
155 AttributeSet a = getInputAttributes().copyAttributes();
159 int dot = caret.getDot();
160 int mark = caret.getMark();
162 int p0 = Math.min (dot, mark);
163 int p1 = Math.max (dot, mark);
167 if (doc instanceof AbstractDocument)
168 ((AbstractDocument)doc).replace(p0, p1 - p0, content, a);
171 // Remove selected text.
173 doc.remove(p0, p1 - p0);
175 if (content != null && content.length() > 0)
176 doc.insertString(p0, content, a);
179 catch (BadLocationException e)
181 throw new AssertionError
182 ("No BadLocationException should be thrown here");
187 * Inserts an AWT or Swing component into the text at the current caret
190 * @param component the component to be inserted
192 public void insertComponent(Component component)
194 SimpleAttributeSet atts = new SimpleAttributeSet();
195 atts.addAttribute(StyleConstants.ComponentAttribute, component);
196 atts.addAttribute(StyleConstants.NameAttribute,
197 StyleConstants.ComponentElementName);
200 getDocument().insertString(getCaret().getDot(), " ", atts);
202 catch (BadLocationException ex)
204 AssertionError err = new AssertionError("Unexpected bad location");
211 * Inserts an <code>Icon</code> into the text at the current caret position.
213 * @param icon the <code>Icon</code> to be inserted
215 public void insertIcon(Icon icon)
217 SimpleAttributeSet atts = new SimpleAttributeSet();
218 atts.addAttribute(StyleConstants.IconAttribute, icon);
219 atts.addAttribute(StyleConstants.NameAttribute,
220 StyleConstants.IconElementName);
223 getDocument().insertString(getCaret().getDot(), " ", atts);
225 catch (BadLocationException ex)
227 AssertionError err = new AssertionError("Unexpected bad location");
234 * Adds a style into the style hierarchy. Unspecified style attributes
235 * can be resolved in the <code>parent</code> style, if one is specified.
237 * While it is legal to add nameless styles (<code>nm == null</code),
238 * you must be aware that the client application is then responsible
239 * for managing the style hierarchy, since unnamed styles cannot be
240 * looked up by their name.
242 * @param nm the name of the style or <code>null</code> if the style should
244 * @param parent the parent in which unspecified style attributes are
245 * resolved, or <code>null</code> if that is not necessary
247 * @return the newly created <code>Style</code>
249 public Style addStyle(String nm, Style parent)
251 return getStyledDocument().addStyle(nm, parent);
255 * Removes a named <code>Style</code> from the style hierarchy.
257 * @param nm the name of the <code>Style</code> to be removed
259 public void removeStyle(String nm)
261 getStyledDocument().removeStyle(nm);
265 * Looks up and returns a named <code>Style</code>.
267 * @param nm the name of the <code>Style</code>
269 * @return the found <code>Style</code> of <code>null</code> if no such
270 * <code>Style</code> exists
272 public Style getStyle(String nm)
274 return getStyledDocument().getStyle(nm);
278 * Returns the logical style of the paragraph at the current caret position.
280 * @return the logical style of the paragraph at the current caret position
282 public Style getLogicalStyle()
284 return getStyledDocument().getLogicalStyle(getCaretPosition());
288 * Sets the logical style for the paragraph at the current caret position.
290 * @param style the style to set for the current paragraph
292 public void setLogicalStyle(Style style)
294 getStyledDocument().setLogicalStyle(getCaretPosition(), style);
298 * Returns the text attributes for the character at the current caret
301 * @return the text attributes for the character at the current caret
304 public AttributeSet getCharacterAttributes()
306 StyledDocument doc = getStyledDocument();
307 Element el = doc.getCharacterElement(getCaretPosition());
308 return el.getAttributes();
312 * Sets text attributes for the current selection. If there is no selection
313 * the text attributes are applied to newly inserted text
315 * @param attribute the text attributes to set
316 * @param replace if <code>true</code>, the attributes of the current
317 * selection are overridden, otherwise they are merged
319 * @see #getInputAttributes
321 public void setCharacterAttributes(AttributeSet attribute,
324 int dot = getCaret().getDot();
325 int start = getSelectionStart();
326 int end = getSelectionEnd();
327 if (start == dot && end == dot)
328 // There is no selection, update insertAttributes instead
330 MutableAttributeSet inputAttributes =
331 getStyledEditorKit().getInputAttributes();
333 inputAttributes.removeAttributes(inputAttributes);
334 inputAttributes.addAttributes(attribute);
337 getStyledDocument().setCharacterAttributes(start, end - start, attribute,
342 * Returns the text attributes of the paragraph at the current caret
345 * @return the attributes of the paragraph at the current caret position
347 public AttributeSet getParagraphAttributes()
349 StyledDocument doc = getStyledDocument();
350 Element el = doc.getParagraphElement(getCaretPosition());
351 return el.getAttributes();
355 * Sets text attributes for the paragraph at the current selection.
356 * If there is no selection the text attributes are applied to
357 * the paragraph at the current caret position.
359 * @param attribute the text attributes to set
360 * @param replace if <code>true</code>, the attributes of the current
361 * selection are overridden, otherwise they are merged
363 public void setParagraphAttributes(AttributeSet attribute,
370 * Returns the attributes that are applied to newly inserted text.
371 * This is a {@link MutableAttributeSet}, so you can easily modify these
374 * @return the attributes that are applied to newly inserted text
376 public MutableAttributeSet getInputAttributes()
378 return getStyledEditorKit().getInputAttributes();
382 * Returns the {@link StyledEditorKit} that is currently used by this
383 * <code>JTextPane</code>.
385 * @return the current <code>StyledEditorKit</code> of this
386 * <code>JTextPane</code>
388 protected final StyledEditorKit getStyledEditorKit()
390 return (StyledEditorKit) getEditorKit();
394 * Creates the default {@link EditorKit} that is used in
395 * <code>JTextPane</code>s. This is an instance of {@link StyledEditorKit}.
397 * @return the default {@link EditorKit} that is used in
398 * <code>JTextPane</code>s
400 protected EditorKit createDefaultEditorKit()
402 return new StyledEditorKit();
406 * Sets the {@link EditorKit} to use for this <code>JTextPane</code>.
407 * <code>JTextPane</code>s can only handle {@link StyledEditorKit}s,
408 * if client programs try to set a different type of <code>EditorKit</code>
409 * then an IllegalArgumentException is thrown
411 * @param editor the <code>EditorKit</code> to set
413 * @throws IllegalArgumentException if <code>editor</code> is no
414 * <code>StyledEditorKit</code>
416 public final void setEditorKit(EditorKit editor)
418 if (!(editor instanceof StyledEditorKit))
419 throw new IllegalArgumentException
420 ("JTextPanes can only handle StyledEditorKits");
421 super.setEditorKit(editor);
425 * Returns a param string that can be used for debugging.
427 * @return a param string that can be used for debugging.
429 protected String paramString()
431 return super.paramString(); // TODO