GNU Classpath (0.19) | ||
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: 43: import javax.swing.text.AttributeSet; 44: import javax.swing.text.BadLocationException; 45: import javax.swing.text.Caret; 46: import javax.swing.text.Document; 47: import javax.swing.text.EditorKit; 48: import javax.swing.text.Element; 49: import javax.swing.text.MutableAttributeSet; 50: import javax.swing.text.Style; 51: import javax.swing.text.StyledDocument; 52: import javax.swing.text.StyledEditorKit; 53: 54: /** 55: * A powerful text component that supports styled content as well as 56: * embedding images and components. It is entirely based on a 57: * {@link StyledDocument} content model and a {@link StyledEditorKit}. 58: * 59: * @author Roman Kennke (roman@kennke.org) 60: * @author Andrew Selkirk 61: */ 62: public class JTextPane 63: extends JEditorPane 64: { 65: /** 66: * Creates a new <code>JTextPane</code> with a <code>null</code> document. 67: */ 68: public JTextPane() 69: { 70: super(); 71: } 72: 73: /** 74: * Creates a new <code>JTextPane</code> and sets the specified 75: * <code>document</code>. 76: * 77: * @param document the content model to use 78: */ 79: public JTextPane(StyledDocument document) 80: { 81: this(); 82: setStyledDocument(document); 83: } 84: 85: /** 86: * Returns the UI class ID. This is <code>TextPaneUI</code>. 87: * 88: * @return <code>TextPaneUI</code> 89: */ 90: public String getUIClassID() 91: { 92: return "TextPaneUI"; 93: } 94: 95: /** 96: * Sets the content model for this <code>JTextPane</code>. 97: * <code>JTextPane</code> can only be used with {@link StyledDocument}s, 98: * if you try to set a different type of <code>Document</code>, an 99: * <code>IllegalArgumentException</code> is thrown. 100: * 101: * @param document the content model to set 102: * 103: * @throws IllegalArgumentException if <code>document</code> is not an 104: * instance of <code>StyledDocument</code> 105: * 106: * @see #setStyledDocument 107: */ 108: public void setDocument(Document document) 109: { 110: if (document != null && !(document instanceof StyledDocument)) 111: throw new IllegalArgumentException 112: ("JTextPane can only handle StyledDocuments"); 113: 114: setStyledDocument((StyledDocument) document); 115: } 116: 117: /** 118: * Returns the {@link StyledDocument} that is the content model for 119: * this <code>JTextPane</code>. This is a typed wrapper for 120: * {@link #getDocument()}. 121: * 122: * @return the content model of this <code>JTextPane</code> 123: */ 124: public StyledDocument getStyledDocument() 125: { 126: return (StyledDocument) super.getDocument(); 127: } 128: 129: /** 130: * Sets the content model for this <code>JTextPane</code>. 131: * 132: * @param document the content model to set 133: */ 134: public void setStyledDocument(StyledDocument document) 135: { 136: super.setDocument(document); 137: } 138: 139: /** 140: * Replaces the currently selected text with the specified 141: * <code>content</code>. If there is no selected text, this results 142: * in a simple insertion at the current caret position. If there is 143: * no <code>content</code> specified, this results in the selection 144: * beeing deleted. 145: * 146: * @param content the text with which the selection is replaced 147: */ 148: public void replaceSelection(String content) 149: { 150: Caret caret = getCaret(); 151: StyledDocument doc = getStyledDocument(); 152: 153: int dot = caret.getDot(); 154: int mark = caret.getMark(); 155: 156: // If content is empty delete selection. 157: if (content == null) 158: { 159: caret.setDot(dot); 160: return; 161: } 162: 163: try 164: { 165: int start = getSelectionStart(); 166: int end = getSelectionEnd(); 167: int contentLength = content.length(); 168: 169: // Remove selected text. 170: if (dot != mark) 171: doc.remove(start, end - start); 172: 173: // Insert new text. 174: doc.insertString(start, content, null); 175: // Set attributes for inserted text 176: doc.setCharacterAttributes(start, contentLength, getInputAttributes(), 177: true); 178: 179: } 180: catch (BadLocationException e) 181: { 182: throw new AssertionError 183: ("No BadLocationException should be thrown here"); 184: } 185: } 186: 187: /** 188: * Inserts an AWT or Swing component into the text at the current caret 189: * position. 190: * 191: * @param component the component to be inserted 192: */ 193: public void insertComponent(Component component) 194: { 195: // TODO: One space must be inserted here with attributes set to indicate 196: // that the component must be displayed here. Have to figure out the 197: // attributes. 198: } 199: 200: /** 201: * Inserts an <code>Icon</code> into the text at the current caret position. 202: * 203: * @param icon the <code>Icon</code> to be inserted 204: */ 205: public void insertIcon(Icon icon) 206: { 207: // TODO: One space must be inserted here with attributes set to indicate 208: // that the icon must be displayed here. Have to figure out the 209: // attributes. 210: } 211: 212: /** 213: * Adds a style into the style hierarchy. Unspecified style attributes 214: * can be resolved in the <code>parent</code> style, if one is specified. 215: * 216: * While it is legal to add nameless styles (<code>nm == null</code), 217: * you must be aware that the client application is then responsible 218: * for managing the style hierarchy, since unnamed styles cannot be 219: * looked up by their name. 220: * 221: * @param nm the name of the style or <code>null</code> if the style should 222: * be unnamed 223: * @param parent the parent in which unspecified style attributes are 224: * resolved, or <code>null</code> if that is not necessary 225: * 226: * @return the newly created <code>Style</code> 227: */ 228: public Style addStyle(String nm, Style parent) 229: { 230: return getStyledDocument().addStyle(nm, parent); 231: } 232: 233: /** 234: * Removes a named <code>Style</code> from the style hierarchy. 235: * 236: * @param nm the name of the <code>Style</code> to be removed 237: */ 238: public void removeStyle(String nm) 239: { 240: getStyledDocument().removeStyle(nm); 241: } 242: 243: /** 244: * Looks up and returns a named <code>Style</code>. 245: * 246: * @param nm the name of the <code>Style</code> 247: * 248: * @return the found <code>Style</code> of <code>null</code> if no such 249: * <code>Style</code> exists 250: */ 251: public Style getStyle(String nm) 252: { 253: return getStyledDocument().getStyle(nm); 254: } 255: 256: /** 257: * Returns the logical style of the paragraph at the current caret position. 258: * 259: * @return the logical style of the paragraph at the current caret position 260: */ 261: public Style getLogicalStyle() 262: { 263: return getStyledDocument().getLogicalStyle(getCaretPosition()); 264: } 265: 266: /** 267: * Sets the logical style for the paragraph at the current caret position. 268: * 269: * @param style the style to set for the current paragraph 270: */ 271: public void setLogicalStyle(Style style) 272: { 273: getStyledDocument().setLogicalStyle(getCaretPosition(), style); 274: } 275: 276: /** 277: * Returns the text attributes for the character at the current caret 278: * position. 279: * 280: * @return the text attributes for the character at the current caret 281: * position 282: */ 283: public AttributeSet getCharacterAttributes() 284: { 285: StyledDocument doc = getStyledDocument(); 286: Element el = doc.getCharacterElement(getCaretPosition()); 287: return el.getAttributes(); 288: } 289: 290: /** 291: * Sets text attributes for the current selection. If there is no selection 292: * the text attributes are applied to newly inserted text 293: * 294: * @param attribute the text attributes to set 295: * @param replace if <code>true</code>, the attributes of the current 296: * selection are overridden, otherwise they are merged 297: * 298: * @see #getInputAttributes 299: */ 300: public void setCharacterAttributes(AttributeSet attribute, 301: boolean replace) 302: { 303: int dot = getCaret().getDot(); 304: int start = getSelectionStart(); 305: int end = getSelectionEnd(); 306: if (start == dot && end == dot) 307: // There is no selection, update insertAttributes instead 308: { 309: MutableAttributeSet inputAttributes = 310: getStyledEditorKit().getInputAttributes(); 311: inputAttributes.addAttributes(attribute); 312: } 313: else 314: getStyledDocument().setCharacterAttributes(start, end - start, attribute, 315: replace); 316: } 317: 318: /** 319: * Returns the text attributes of the paragraph at the current caret 320: * position. 321: * 322: * @return the attributes of the paragraph at the current caret position 323: */ 324: public AttributeSet getParagraphAttributes() 325: { 326: StyledDocument doc = getStyledDocument(); 327: Element el = doc.getParagraphElement(getCaretPosition()); 328: return el.getAttributes(); 329: } 330: 331: /** 332: * Sets text attributes for the paragraph at the current selection. 333: * If there is no selection the text attributes are applied to 334: * the paragraph at the current caret position. 335: * 336: * @param attribute the text attributes to set 337: * @param replace if <code>true</code>, the attributes of the current 338: * selection are overridden, otherwise they are merged 339: */ 340: public void setParagraphAttributes(AttributeSet attribute, 341: boolean replace) 342: { 343: // TODO 344: } 345: 346: /** 347: * Returns the attributes that are applied to newly inserted text. 348: * This is a {@link MutableAttributeSet}, so you can easily modify these 349: * attributes. 350: * 351: * @return the attributes that are applied to newly inserted text 352: */ 353: public MutableAttributeSet getInputAttributes() 354: { 355: return getStyledEditorKit().getInputAttributes(); 356: } 357: 358: /** 359: * Returns the {@link StyledEditorKit} that is currently used by this 360: * <code>JTextPane</code>. 361: * 362: * @return the current <code>StyledEditorKit</code> of this 363: * <code>JTextPane</code> 364: */ 365: protected final StyledEditorKit getStyledEditorKit() 366: { 367: return (StyledEditorKit) getEditorKit(); 368: } 369: 370: /** 371: * Creates the default {@link EditorKit} that is used in 372: * <code>JTextPane</code>s. This is an instance of {@link StyledEditorKit}. 373: * 374: * @return the default {@link EditorKit} that is used in 375: * <code>JTextPane</code>s 376: */ 377: protected EditorKit createDefaultEditorKit() 378: { 379: return new StyledEditorKit(); 380: } 381: 382: /** 383: * Sets the {@link EditorKit} to use for this <code>JTextPane</code>. 384: * <code>JTextPane</code>s can only handle {@link StyledEditorKit}s, 385: * if client programs try to set a different type of <code>EditorKit</code> 386: * then an IllegalArgumentException is thrown 387: * 388: * @param editor the <code>EditorKit</code> to set 389: * 390: * @throws IllegalArgumentException if <code>editor</code> is no 391: * <code>StyledEditorKit</code> 392: */ 393: public final void setEditorKit(EditorKit editor) 394: { 395: if (!(editor instanceof StyledEditorKit)) 396: throw new IllegalArgumentException 397: ("JTextPanes can only handle StyledEditorKits"); 398: super.setEditorKit(editor); 399: } 400: 401: /** 402: * Returns a param string that can be used for debugging. 403: * 404: * @return a param string that can be used for debugging. 405: */ 406: protected String paramString() 407: { 408: return super.paramString(); // TODO 409: } 410: }
GNU Classpath (0.19) |