GNU Classpath (0.18) | ||
Frames | No Frames |
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: import java.io.IOException; 43: import java.io.ObjectOutputStream; 44: 45: import javax.swing.text.AttributeSet; 46: import javax.swing.text.BadLocationException; 47: import javax.swing.text.Caret; 48: import javax.swing.text.Document; 49: import javax.swing.text.EditorKit; 50: import javax.swing.text.Element; 51: import javax.swing.text.MutableAttributeSet; 52: import javax.swing.text.SimpleAttributeSet; 53: import javax.swing.text.Style; 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 {@link #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: 156: int dot = caret.getDot(); 157: int mark = caret.getMark(); 158: 159: // If content is empty delete selection. 160: if (content == null) 161: { 162: caret.setDot(dot); 163: return; 164: } 165: 166: try 167: { 168: int start = getSelectionStart(); 169: int end = getSelectionEnd(); 170: int contentLength = content.length(); 171: 172: // Remove selected text. 173: if (dot != mark) 174: doc.remove(start, end - start); 175: 176: // Insert new text. 177: doc.insertString(start, content, null); 178: // Set attributes for inserted text 179: doc.setCharacterAttributes(start, contentLength, getInputAttributes(), 180: true); 181: 182: // Set dot to new position. 183: setCaretPosition(start + contentLength); 184: } 185: catch (BadLocationException e) 186: { 187: throw new AssertionError 188: ("No BadLocationException should be thrown here"); 189: } 190: } 191: 192: /** 193: * Inserts an AWT or Swing component into the text at the current caret 194: * position. 195: * 196: * @param component the component to be inserted 197: */ 198: public void insertComponent(Component component) 199: { 200: // TODO: One space must be inserted here with attributes set to indicate 201: // that the component must be displayed here. Have to figure out the 202: // attributes. 203: } 204: 205: /** 206: * Inserts an <code>Icon</code> into the text at the current caret position. 207: * 208: * @param icon the <code>Icon</code> to be inserted 209: */ 210: public void insertIcon(Icon icon) 211: { 212: // TODO: One space must be inserted here with attributes set to indicate 213: // that the icon must be displayed here. Have to figure out the 214: // attributes. 215: } 216: 217: /** 218: * Adds a style into the style hierarchy. Unspecified style attributes 219: * can be resolved in the <code>parent</code> style, if one is specified. 220: * 221: * While it is legal to add nameless styles (<code>nm == null</code), 222: * you must be aware that the client application is then responsible 223: * for managing the style hierarchy, since unnamed styles cannot be 224: * looked up by their name. 225: * 226: * @param nm the name of the style or <code>null</code> if the style should 227: * be unnamed 228: * @param parent the parent in which unspecified style attributes are 229: * resolved, or <code>null</code> if that is not necessary 230: * 231: * @return the newly created <code>Style</code> 232: */ 233: public Style addStyle(String nm, Style parent) 234: { 235: return getStyledDocument().addStyle(nm, parent); 236: } 237: 238: /** 239: * Removes a named <code>Style</code> from the style hierarchy. 240: * 241: * @param nm the name of the <code>Style</code> to be removed 242: */ 243: public void removeStyle(String nm) 244: { 245: getStyledDocument().removeStyle(nm); 246: } 247: 248: /** 249: * Looks up and returns a named <code>Style</code>. 250: * 251: * @param nm the name of the <code>Style</code> 252: * 253: * @return the found <code>Style</code> of <code>null</code> if no such 254: * <code>Style</code> exists 255: */ 256: public Style getStyle(String nm) 257: { 258: return getStyledDocument().getStyle(nm); 259: } 260: 261: /** 262: * Returns the logical style of the paragraph at the current caret position. 263: * 264: * @return the logical style of the paragraph at the current caret position 265: */ 266: public Style getLogicalStyle() 267: { 268: return getStyledDocument().getLogicalStyle(getCaretPosition()); 269: } 270: 271: /** 272: * Sets the logical style for the paragraph at the current caret position. 273: * 274: * @param style the style to set for the current paragraph 275: */ 276: public void setLogicalStyle(Style style) 277: { 278: getStyledDocument().setLogicalStyle(getCaretPosition(), style); 279: } 280: 281: /** 282: * Returns the text attributes for the character at the current caret 283: * position. 284: * 285: * @return the text attributes for the character at the current caret 286: * position 287: */ 288: public AttributeSet getCharacterAttributes() 289: { 290: StyledDocument doc = getStyledDocument(); 291: Element el = doc.getCharacterElement(getCaretPosition()); 292: return el.getAttributes(); 293: } 294: 295: /** 296: * Sets text attributes for the current selection. If there is no selection 297: * the text attributes are applied to newly inserted text 298: * 299: * @param attribute the text attributes to set 300: * @param replace if <code>true</code>, the attributes of the current 301: * selection are overridden, otherwise they are merged 302: * 303: * @see {@link #getInputAttributes} 304: */ 305: public void setCharacterAttributes(AttributeSet attribute, 306: boolean replace) 307: { 308: int dot = getCaret().getDot(); 309: int start = getSelectionStart(); 310: int end = getSelectionEnd(); 311: if (start == dot && end == dot) 312: // There is no selection, update insertAttributes instead 313: { 314: MutableAttributeSet inputAttributes = 315: getStyledEditorKit().getInputAttributes(); 316: inputAttributes.addAttributes(attribute); 317: } 318: else 319: getStyledDocument().setCharacterAttributes(start, end - start, attribute, 320: replace); 321: } 322: 323: /** 324: * Returns the text attributes of the paragraph at the current caret 325: * position. 326: * 327: * @return the attributes of the paragraph at the current caret position 328: */ 329: public AttributeSet getParagraphAttributes() 330: { 331: StyledDocument doc = getStyledDocument(); 332: Element el = doc.getParagraphElement(getCaretPosition()); 333: return el.getAttributes(); 334: } 335: 336: /** 337: * Sets text attributes for the paragraph at the current selection. 338: * If there is no selection the text attributes are applied to 339: * the paragraph at the current caret position. 340: * 341: * @param attribute the text attributes to set 342: * @param replace if <code>true</code>, the attributes of the current 343: * selection are overridden, otherwise they are merged 344: */ 345: public void setParagraphAttributes(AttributeSet attribute, 346: boolean replace) 347: { 348: // TODO 349: } 350: 351: /** 352: * Returns the attributes that are applied to newly inserted text. 353: * This is a {@link MutableAttributeSet}, so you can easily modify these 354: * attributes. 355: * 356: * @return the attributes that are applied to newly inserted text 357: */ 358: public MutableAttributeSet getInputAttributes() 359: { 360: return getStyledEditorKit().getInputAttributes(); 361: } 362: 363: /** 364: * Returns the {@link StyledEditorKit} that is currently used by this 365: * <code>JTextPane</code>. 366: * 367: * @return the current <code>StyledEditorKit</code> of this 368: * <code>JTextPane</code> 369: */ 370: protected final StyledEditorKit getStyledEditorKit() 371: { 372: return (StyledEditorKit) getEditorKit(); 373: } 374: 375: /** 376: * Creates the default {@link EditorKit} that is used in 377: * <code>JTextPane</code>s. This is an instance of {@link StyledEditorKit}. 378: * 379: * @return the default {@link EditorKit} that is used in 380: * <code>JTextPane</code>s 381: */ 382: protected EditorKit createDefaultEditorKit() 383: { 384: return new StyledEditorKit(); 385: } 386: 387: /** 388: * Sets the {@link EditorKit} to use for this <code>JTextPane</code>. 389: * <code>JTextPane</code>s can only handle {@link StyledEditorKit}s, 390: * if client programs try to set a different type of <code>EditorKit</code> 391: * then an IllegalArgumentException is thrown 392: * 393: * @param editor the <code>EditorKit</code> to set 394: * 395: * @throws IllegalArgumentException if <code>editor</code> is no 396: * <code>StyledEditorKit</code> 397: */ 398: public final void setEditorKit(EditorKit editor) 399: { 400: if (!(editor instanceof StyledEditorKit)) 401: throw new IllegalArgumentException 402: ("JTextPanes can only handle StyledEditorKits"); 403: super.setEditorKit(editor); 404: } 405: 406: /** 407: * Returns a param string that can be used for debugging. 408: * 409: * @return a param string that can be used for debugging. 410: */ 411: protected String paramString() 412: { 413: return super.paramString(); // TODO 414: } 415: }
GNU Classpath (0.18) |