OSDN Git Service

Imported GNU Classpath 0.90
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / JTextPane.java
1 /* JTextPane.java -- A powerful text widget supporting styled text
2    Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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)
9 any later version.
10
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.
15
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
19 02110-1301 USA.
20
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
24 combination.
25
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. */
37
38
39 package javax.swing;
40
41 import java.awt.Component;
42
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;
56
57 /**
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}.
61  *
62  * @author Roman Kennke (roman@kennke.org)
63  * @author Andrew Selkirk
64  */
65 public class JTextPane
66   extends JEditorPane
67 {
68   /**
69    * Creates a new <code>JTextPane</code> with a <code>null</code> document.
70    */
71   public JTextPane()
72   {
73     super();
74   }
75
76   /**
77    * Creates a new <code>JTextPane</code> and sets the specified
78    * <code>document</code>.
79    *
80    * @param document the content model to use
81    */
82   public JTextPane(StyledDocument document)
83   {
84     this();
85     setStyledDocument(document);
86   }
87
88   /**
89    * Returns the UI class ID. This is <code>TextPaneUI</code>.
90    *
91    * @return <code>TextPaneUI</code>
92    */
93   public String getUIClassID()
94   {
95     return "TextPaneUI";
96   }
97
98   /**
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.
103    *
104    * @param document the content model to set
105    *
106    * @throws IllegalArgumentException if <code>document</code> is not an
107    *         instance of <code>StyledDocument</code>
108    *
109    * @see #setStyledDocument
110    */
111   public void setDocument(Document document)
112   {
113     if (document != null && !(document instanceof StyledDocument))
114       throw new IllegalArgumentException
115         ("JTextPane can only handle StyledDocuments");
116
117     setStyledDocument((StyledDocument) document);
118   }
119
120   /**
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()}.
124    *
125    * @return the content model of this <code>JTextPane</code>
126    */
127   public StyledDocument getStyledDocument()
128   {
129     return (StyledDocument) super.getDocument();
130   }
131
132   /**
133    * Sets the content model for this <code>JTextPane</code>.
134    *
135    * @param document the content model to set
136    */
137   public void setStyledDocument(StyledDocument document)
138   {
139     super.setDocument(document);
140   }
141
142   /**
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
147    * beeing deleted.
148    *
149    * @param content the text with which the selection is replaced
150    */
151   public void replaceSelection(String content)
152   {
153     Caret caret = getCaret();
154     StyledDocument doc = getStyledDocument();
155     AttributeSet a = getInputAttributes().copyAttributes();
156     if (doc == null)
157       return;
158
159     int dot = caret.getDot();
160     int mark = caret.getMark();
161
162     int p0 = Math.min (dot, mark);
163     int p1 = Math.max (dot, mark);
164
165     try
166       {
167         if (doc instanceof AbstractDocument)
168           ((AbstractDocument)doc).replace(p0, p1 - p0, content, a);
169         else
170           {
171             // Remove selected text.
172             if (dot != mark)
173               doc.remove(p0, p1 - p0);
174             // Insert new text.
175             if (content != null && content.length() > 0)
176               doc.insertString(p0, content, a);
177           }
178       }
179     catch (BadLocationException e)
180       {
181         throw new AssertionError
182           ("No BadLocationException should be thrown here");      
183       }
184   }
185
186   /**
187    * Inserts an AWT or Swing component into the text at the current caret
188    * position.
189    *
190    * @param component the component to be inserted
191    */
192   public void insertComponent(Component component)
193   {
194     SimpleAttributeSet atts = new SimpleAttributeSet();
195     atts.addAttribute(StyleConstants.ComponentAttribute, component);
196     atts.addAttribute(StyleConstants.NameAttribute,
197                       StyleConstants.ComponentElementName);
198     try
199       {
200         getDocument().insertString(getCaret().getDot(), " ", atts);
201       }
202     catch (BadLocationException ex)
203       {
204         AssertionError err = new AssertionError("Unexpected bad location");
205         err.initCause(ex);
206         throw err;
207       }
208   }
209
210   /**
211    * Inserts an <code>Icon</code> into the text at the current caret position.
212    *
213    * @param icon the <code>Icon</code> to be inserted
214    */
215   public void insertIcon(Icon icon)
216   {
217     SimpleAttributeSet atts = new SimpleAttributeSet();
218     atts.addAttribute(StyleConstants.IconAttribute, icon);
219     atts.addAttribute(StyleConstants.NameAttribute,
220                       StyleConstants.IconElementName);
221     try
222       {
223         getDocument().insertString(getCaret().getDot(), " ", atts);
224       }
225     catch (BadLocationException ex)
226       {
227         AssertionError err = new AssertionError("Unexpected bad location");
228         err.initCause(ex);
229         throw err;
230       }
231   }
232
233   /**
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.
236    *
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.
241    *
242    * @param nm the name of the style or <code>null</code> if the style should
243    *           be unnamed
244    * @param parent the parent in which unspecified style attributes are
245    *           resolved, or <code>null</code> if that is not necessary
246    *
247    * @return the newly created <code>Style</code>
248    */
249   public Style addStyle(String nm, Style parent)
250   {
251     return getStyledDocument().addStyle(nm, parent);
252   }
253
254   /**
255    * Removes a named <code>Style</code> from the style hierarchy.
256    *
257    * @param nm the name of the <code>Style</code> to be removed
258    */
259   public void removeStyle(String nm)
260   {
261     getStyledDocument().removeStyle(nm);
262   }
263
264   /**
265    * Looks up and returns a named <code>Style</code>.
266    *
267    * @param nm the name of the <code>Style</code>
268    *
269    * @return the found <code>Style</code> of <code>null</code> if no such
270    *         <code>Style</code> exists
271    */
272   public Style getStyle(String nm)
273   {
274     return getStyledDocument().getStyle(nm);
275   }
276
277   /**
278    * Returns the logical style of the paragraph at the current caret position.
279    *
280    * @return the logical style of the paragraph at the current caret position
281    */
282   public Style getLogicalStyle()
283   {
284     return getStyledDocument().getLogicalStyle(getCaretPosition());
285   }
286
287   /**
288    * Sets the logical style for the paragraph at the current caret position.
289    *
290    * @param style the style to set for the current paragraph
291    */
292   public void setLogicalStyle(Style style)
293   {
294     getStyledDocument().setLogicalStyle(getCaretPosition(), style);
295   }
296
297   /**
298    * Returns the text attributes for the character at the current caret
299    * position.
300    *
301    * @return the text attributes for the character at the current caret
302    *         position
303    */
304   public AttributeSet getCharacterAttributes()
305   {
306     StyledDocument doc = getStyledDocument();
307     Element el = doc.getCharacterElement(getCaretPosition());
308     return el.getAttributes();
309   }
310
311   /**
312    * Sets text attributes for the current selection. If there is no selection
313    * the text attributes are applied to newly inserted text
314    *
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
318    *
319    * @see #getInputAttributes
320    */
321   public void setCharacterAttributes(AttributeSet attribute,
322                                      boolean replace)
323   {
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
329       {
330         MutableAttributeSet inputAttributes =
331           getStyledEditorKit().getInputAttributes();
332         if (replace)
333           inputAttributes.removeAttributes(inputAttributes);
334         inputAttributes.addAttributes(attribute);
335       }
336     else
337       getStyledDocument().setCharacterAttributes(start, end - start, attribute,
338                                                  replace);
339   }
340
341   /**
342    * Returns the text attributes of the paragraph at the current caret
343    * position.
344    *
345    * @return the attributes of the paragraph at the current caret position
346    */
347   public AttributeSet getParagraphAttributes()
348   {
349     StyledDocument doc = getStyledDocument();
350     Element el = doc.getParagraphElement(getCaretPosition());
351     return el.getAttributes();
352   }
353
354   /**
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.
358    *
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
362    */
363   public void setParagraphAttributes(AttributeSet attribute,
364                                      boolean replace)
365   {
366     // TODO
367   }
368
369   /**
370    * Returns the attributes that are applied to newly inserted text.
371    * This is a {@link MutableAttributeSet}, so you can easily modify these
372    * attributes.
373    *
374    * @return the attributes that are applied to newly inserted text
375    */
376   public MutableAttributeSet getInputAttributes()
377   {
378     return getStyledEditorKit().getInputAttributes();
379   }
380
381   /**
382    * Returns the {@link StyledEditorKit} that is currently used by this
383    * <code>JTextPane</code>.
384    *
385    * @return the current <code>StyledEditorKit</code> of this
386    *         <code>JTextPane</code>
387    */
388   protected final StyledEditorKit getStyledEditorKit()
389   {
390     return (StyledEditorKit) getEditorKit();
391   }
392
393   /**
394    * Creates the default {@link EditorKit} that is used in
395    * <code>JTextPane</code>s. This is an instance of {@link StyledEditorKit}.
396    *
397    * @return the default {@link EditorKit} that is used in
398    *         <code>JTextPane</code>s
399    */
400   protected EditorKit createDefaultEditorKit()
401   {
402     return new StyledEditorKit();
403   }
404
405   /**
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
410    *
411    * @param editor the <code>EditorKit</code> to set
412    *
413    * @throws IllegalArgumentException if <code>editor</code> is no
414    *         <code>StyledEditorKit</code>
415    */
416   public final void setEditorKit(EditorKit editor)
417   {
418     if (!(editor instanceof StyledEditorKit))
419       throw new IllegalArgumentException
420         ("JTextPanes can only handle StyledEditorKits");
421     super.setEditorKit(editor);
422   }
423
424   /**
425    * Returns a param string that can be used for debugging.
426    *
427    * @return a param string that can be used for debugging.
428    */
429   protected String paramString()
430   {
431     return super.paramString(); // TODO
432   }
433 }