Source for javax.swing.text.StyledEditorKit

   1: /* StyledEditorKit.java --
   2:    Copyright (C) 2002, 2004 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.text;
  40: 
  41: import java.awt.Color;
  42: import java.awt.event.ActionEvent;
  43: 
  44: import javax.swing.Action;
  45: import javax.swing.JEditorPane;
  46: import javax.swing.event.CaretEvent;
  47: import javax.swing.event.CaretListener;
  48: 
  49: /**
  50:  * An {@link EditorKit} that supports editing styled text.
  51:  *
  52:  * @author Andrew Selkirk
  53:  * @author Roman Kennke (roman@kennke.org)
  54:  */
  55: public class StyledEditorKit extends DefaultEditorKit
  56: {
  57:   /** The serialVersionUID. */
  58:   private static final long serialVersionUID = 7002391892985555948L;
  59: 
  60:   /**
  61:    * Toggles the underline attribute for the selected text.
  62:    */
  63:   public static class UnderlineAction extends StyledEditorKit.StyledTextAction
  64:   {
  65:     /**
  66:      * Creates an instance of <code>UnderlineAction</code>.
  67:      */
  68:     public UnderlineAction()
  69:     {
  70:       super("font-underline");
  71:     }
  72: 
  73:     /**
  74:      * Performs the action.
  75:      *
  76:      * @param event the <code>ActionEvent</code> that describes the action
  77:      */
  78:     public void actionPerformed(ActionEvent event)
  79:     {
  80:       JEditorPane editor = getEditor(event);
  81:       StyledDocument doc = getStyledDocument(editor);
  82:       Element el = doc.getCharacterElement(editor.getSelectionStart());
  83:       boolean isUnderline = StyleConstants.isUnderline(el.getAttributes());
  84:       SimpleAttributeSet atts = new SimpleAttributeSet();
  85:       StyleConstants.setUnderline(atts, ! isUnderline);
  86:       setCharacterAttributes(editor, atts, false);
  87:     }
  88:   }
  89: 
  90:   /**
  91:    * Toggles the italic attribute for the selected text.
  92:    */
  93:   public static class ItalicAction extends StyledEditorKit.StyledTextAction
  94:   {
  95:     /**
  96:      * Creates an instance of <code>ItalicAction</code>.
  97:      */
  98:     public ItalicAction()
  99:     {
 100:       super("font-italic");
 101:     }
 102: 
 103:     /**
 104:      * Performs the action.
 105:      *
 106:      * @param event the <code>ActionEvent</code> that describes the action
 107:      */
 108:     public void actionPerformed(ActionEvent event)
 109:     {
 110:       JEditorPane editor = getEditor(event);
 111:       StyledDocument doc = getStyledDocument(editor);
 112:       Element el = doc.getCharacterElement(editor.getSelectionStart());
 113:       boolean isItalic = StyleConstants.isItalic(el.getAttributes());
 114:       SimpleAttributeSet atts = new SimpleAttributeSet();
 115:       StyleConstants.setItalic(atts, ! isItalic);
 116:       setCharacterAttributes(editor, atts, false);
 117:     }
 118:   }
 119: 
 120:   /**
 121:    * Toggles the bold attribute for the selected text.
 122:    */
 123:   public static class BoldAction extends StyledEditorKit.StyledTextAction
 124:   {
 125:     /**
 126:      * Creates an instance of <code>BoldAction</code>.
 127:      */
 128:     public BoldAction()
 129:     {
 130:       super("font-bold");
 131:     }
 132: 
 133:     /**
 134:      * Performs the action.
 135:      *
 136:      * @param event the <code>ActionEvent</code> that describes the action
 137:      */
 138:     public void actionPerformed(ActionEvent event)
 139:     {
 140:       JEditorPane editor = getEditor(event);
 141:       StyledDocument doc = getStyledDocument(editor);
 142:       Element el = doc.getCharacterElement(editor.getSelectionStart());
 143:       boolean isBold = StyleConstants.isBold(el.getAttributes());
 144:       SimpleAttributeSet atts = new SimpleAttributeSet();
 145:       StyleConstants.setItalic(atts, ! isBold);
 146:       setCharacterAttributes(editor, atts, false);
 147:     }
 148:   }
 149: 
 150:   /**
 151:    * Sets the alignment attribute on the selected text.
 152:    */
 153:   public static class AlignmentAction extends StyledEditorKit.StyledTextAction
 154:   {
 155:     /**
 156:      * The aligment to set.
 157:      */
 158:     private int a;
 159: 
 160:     /**
 161:      * Creates a new instance of <code>AlignmentAction</code> to set the
 162:      * alignment to <code>a</code>.
 163:      *
 164:      * @param nm the name of the Action
 165:      * @param a the alignment to set
 166:      */
 167:     public AlignmentAction(String nm, int a)
 168:     {
 169:       super(nm);
 170:       this.a = a;
 171:     }
 172: 
 173:     /**
 174:      * Performs the action.
 175:      *
 176:      * @param event the <code>ActionEvent</code> that describes the action
 177:      */
 178:     public void actionPerformed(ActionEvent event)
 179:     {
 180:       SimpleAttributeSet atts = new SimpleAttributeSet();
 181:       StyleConstants.setAlignment(atts, a);
 182:       setParagraphAttributes(getEditor(event), atts, false);
 183:     }
 184:   }
 185: 
 186:   /**
 187:    * Sets the foreground color attribute on the selected text.
 188:    */
 189:   public static class ForegroundAction extends StyledEditorKit.StyledTextAction
 190:   {
 191:     /**
 192:      * The foreground color to set.
 193:      */
 194:     private Color fg;
 195: 
 196:     /**
 197:      * Creates a new instance of <code>ForegroundAction</code> to set the
 198:      * foreground color to <code>fg</code>.
 199:      *
 200:      * @param nm the name of the Action
 201:      * @param fg the foreground color to set
 202:      */
 203:     public ForegroundAction(String nm, Color fg)
 204:     {
 205:       super(nm);
 206:       this.fg = fg;
 207:     }
 208: 
 209:     /**
 210:      * Performs the action.
 211:      *
 212:      * @param event the <code>ActionEvent</code> that describes the action
 213:      */
 214:     public void actionPerformed(ActionEvent event)
 215:     {
 216:       SimpleAttributeSet atts = new SimpleAttributeSet();
 217:       StyleConstants.setForeground(atts, fg);
 218:       setCharacterAttributes(getEditor(event), atts, false);
 219:     }
 220:   }
 221: 
 222:   /**
 223:    * Sets the font size attribute on the selected text.
 224:    */
 225:   public static class FontSizeAction extends StyledEditorKit.StyledTextAction
 226:   {
 227:     /**
 228:      * The font size to set.
 229:      */
 230:     private int size;
 231: 
 232:     /**
 233:      * Creates a new instance of <code>FontSizeAction</code> to set the
 234:      * font size to <code>size</code>.
 235:      *
 236:      * @param nm the name of the Action
 237:      * @param size the font size to set
 238:      */
 239:     public FontSizeAction(String nm, int size)
 240:     {
 241:       super(nm);
 242:       this.size = size;
 243:     }
 244: 
 245:     /**
 246:      * Performs the action.
 247:      *
 248:      * @param event the <code>ActionEvent</code> that describes the action
 249:      */
 250:     public void actionPerformed(ActionEvent event)
 251:     {
 252:       SimpleAttributeSet atts = new SimpleAttributeSet();
 253:       StyleConstants.setFontSize(atts, size);
 254:       setCharacterAttributes(getEditor(event), atts, false);
 255:     }
 256:   }
 257: 
 258:   /**
 259:    * Sets the font family attribute on the selected text.
 260:    */
 261:   public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
 262:   {
 263:     /**
 264:      * The font family to set.
 265:      */
 266:     private String family;
 267: 
 268:     /**
 269:      * Creates a new instance of <code>FontFamilyAction</code> to set the
 270:      * font family to <code>family</code>.
 271:      *
 272:      * @param nm the name of the Action
 273:      * @param family the font family to set
 274:      */
 275:     public FontFamilyAction(String nm, String family)
 276:     {
 277:       super(nm);
 278:       this.family = family;
 279:     }
 280: 
 281:     /**
 282:      * Performs the action.
 283:      *
 284:      * @param event the <code>ActionEvent</code> that describes the action
 285:      */
 286:     public void actionPerformed(ActionEvent event)
 287:     {
 288:       SimpleAttributeSet atts = new SimpleAttributeSet();
 289:       StyleConstants.setFontFamily(atts, family);
 290:       setCharacterAttributes(getEditor(event), atts, false);
 291:     }
 292:   }
 293: 
 294:   /**
 295:    * The abstract superclass of all styled TextActions. This class
 296:    * provides some useful methods to manipulate the text attributes.
 297:    */
 298:   public abstract static class StyledTextAction extends TextAction
 299:   {
 300:     /**
 301:      * Creates a new instance of <code>StyledTextAction</code>.
 302:      *
 303:      * @param nm the name of the <code>StyledTextAction</code>
 304:      */
 305:     public StyledTextAction(String nm)
 306:     {
 307:       super(nm);
 308:     }
 309: 
 310:     /**
 311:      * Returns the <code>JEditorPane</code> component from which the
 312:      * <code>ActionEvent</code> originated.
 313:      *
 314:      * @param event the <code>ActionEvent</code>
 315:      * @return the <code>JEditorPane</code> component from which the
 316:      *         <code>ActionEvent</code> originated
 317:      */
 318:     protected final JEditorPane getEditor(ActionEvent event)
 319:     {
 320:       return (JEditorPane) getTextComponent(event);
 321:     }
 322: 
 323:     /**
 324:      * Sets the specified character attributes on the currently selected
 325:      * text of <code>editor</code>. If <code>editor</code> does not have
 326:      * a selection, then the attributes are used as input attributes
 327:      * for newly inserted content.
 328:      *
 329:      * @param editor the <code>JEditorPane</code> component
 330:      * @param atts the text attributes to set
 331:      * @param replace if <code>true</code> the current attributes of the
 332:      *        selection are replaces, otherwise they are merged
 333:      */
 334:     protected final void setCharacterAttributes(JEditorPane editor,
 335:                                                 AttributeSet atts,
 336:                                                 boolean replace)
 337:     {
 338:       Document doc = editor.getDocument();
 339:       if (doc instanceof StyledDocument)
 340:     {
 341:       StyledDocument styleDoc = (StyledDocument) editor.getDocument();
 342:       EditorKit kit = editor.getEditorKit();
 343:       if (!(kit instanceof StyledEditorKit))
 344:         {
 345:           StyledEditorKit styleKit = (StyledEditorKit) kit;
 346:           int start = editor.getSelectionStart();
 347:           int end = editor.getSelectionEnd();
 348:           int dot = editor.getCaret().getDot();
 349:           if (start == dot && end == dot)
 350:         {
 351:           // If there is no selection, then we only update the
 352:           // input attributes.
 353:           MutableAttributeSet inputAttributes =
 354:             styleKit.getInputAttributes();
 355:           inputAttributes.addAttributes(atts);
 356:         }
 357:           else
 358:         styleDoc.setCharacterAttributes(start, end, atts, replace);
 359:         }
 360:       else
 361:         throw new AssertionError("The EditorKit for StyledTextActions "
 362:                      + "is expected to be a StyledEditorKit");
 363:     }
 364:       else
 365:     throw new AssertionError("The Document for StyledTextActions is "
 366:                  + "expected to be a StyledDocument.");
 367:     }
 368: 
 369:     /**
 370:      * Returns the {@link StyledDocument} that is used by <code>editor</code>.
 371:      *
 372:      * @param editor the <code>JEditorPane</code> from which to get the
 373:      *        <code>StyledDocument</code>
 374:      *
 375:      * @return the {@link StyledDocument} that is used by <code>editor</code>
 376:      */
 377:     protected final StyledDocument getStyledDocument(JEditorPane editor)
 378:     {
 379:       Document doc = editor.getDocument();
 380:       if (!(doc instanceof StyledDocument))
 381:     throw new AssertionError("The Document for StyledEditorKits is "
 382:                  + "expected to be a StyledDocument.");
 383: 
 384:       return (StyledDocument) doc;
 385:     }
 386: 
 387:     /**
 388:      * Returns the {@link StyledEditorKit} that is used by <code>editor</code>.
 389:      *
 390:      * @param editor the <code>JEditorPane</code> from which to get the
 391:      *        <code>StyledEditorKit</code>
 392:      *
 393:      * @return the {@link StyledEditorKit} that is used by <code>editor</code>
 394:      */
 395:     protected final StyledEditorKit getStyledEditorKit(JEditorPane editor)
 396:     {
 397:       EditorKit kit = editor.getEditorKit();
 398:       if (!(kit instanceof StyledEditorKit))
 399:     throw new AssertionError("The EditorKit for StyledDocuments is "
 400:                  + "expected to be a StyledEditorKit.");
 401: 
 402:       return (StyledEditorKit) kit;
 403:     }
 404: 
 405:     /**
 406:      * Sets the specified character attributes on the paragraph that
 407:      * contains the currently selected
 408:      * text of <code>editor</code>. If <code>editor</code> does not have
 409:      * a selection, then the attributes are set on the paragraph that
 410:      * contains the current caret position.
 411:      *
 412:      * @param editor the <code>JEditorPane</code> component
 413:      * @param atts the text attributes to set
 414:      * @param replace if <code>true</code> the current attributes of the
 415:      *        selection are replaces, otherwise they are merged
 416:      */
 417:     protected final void setParagraphAttributes(JEditorPane editor,
 418:                                                 AttributeSet atts,
 419:                                                 boolean replace)
 420:     {
 421:       Document doc = editor.getDocument();
 422:       if (doc instanceof StyledDocument)
 423:     {
 424:       StyledDocument styleDoc = (StyledDocument) editor.getDocument();
 425:       EditorKit kit = editor.getEditorKit();
 426:       if (!(kit instanceof StyledEditorKit))
 427:         {
 428:           StyledEditorKit styleKit = (StyledEditorKit) kit;
 429:           int start = editor.getSelectionStart();
 430:           int end = editor.getSelectionEnd();
 431:           int dot = editor.getCaret().getDot();
 432:           if (start == dot && end == dot)
 433:         {
 434:           // If there is no selection, then we only update the
 435:           // input attributes.
 436:           MutableAttributeSet inputAttributes =
 437:             styleKit.getInputAttributes();
 438:           inputAttributes.addAttributes(atts);
 439:         }
 440:           else
 441:         styleDoc.setParagraphAttributes(start, end, atts, replace);
 442:         }
 443:       else
 444:         throw new AssertionError("The EditorKit for StyledTextActions "
 445:                      + "is expected to be a StyledEditorKit");
 446:     }
 447:       else
 448:     throw new AssertionError("The Document for StyledTextActions is "
 449:                  + "expected to be a StyledDocument.");
 450:     }
 451:   }
 452: 
 453:   /**
 454:    * A {@link ViewFactory} that is able to create {@link View}s for
 455:    * the <code>Element</code>s that are supported by
 456:    * <code>StyledEditorKit</code>, namely the following types of Elements:
 457:    *
 458:    * <ul>
 459:    * <li>{@link AbstractDocument#ContentElementName}</li>
 460:    * <li>{@link AbstractDocument#ParagraphElementName}</li>
 461:    * <li>{@link AbstractDocument#SectionElementName}</li>
 462:    * <li>{@link StyleConstants#ComponentElementName}</li>
 463:    * <li>{@link StyleConstants#IconElementName}</li>
 464:    * </ul>
 465:    */
 466:   static class StyledViewFactory
 467:     implements ViewFactory
 468:   {
 469:     /**
 470:      * Creates a {@link View} for the specified <code>Element</code>.
 471:      *
 472:      * @param element the <code>Element</code> to create a <code>View</code>
 473:      *        for
 474:      * @return the <code>View</code> for the specified <code>Element</code>
 475:      *         or <code>null</code> if the type of <code>element</code> is
 476:      *         not supported
 477:      */
 478:     public View create(Element element)
 479:     {
 480:       String name = element.getName();
 481:       View view = null;
 482:       if (name.equals(AbstractDocument.ContentElementName))
 483:     view = new LabelView(element);
 484:       else if (name.equals(AbstractDocument.ParagraphElementName))
 485:     view = new ParagraphView(element);
 486:       else if (name.equals(AbstractDocument.SectionElementName))
 487:     view = new BoxView(element, View.Y_AXIS);
 488:       else if (name.equals(StyleConstants.ComponentElementName))
 489:     view = new ComponentView(element);
 490:       else if (name.equals(StyleConstants.IconElementName))
 491:     view = new IconView(element);
 492:       else
 493:         throw new AssertionError("Unknown Element type: "
 494:                                  + element.getClass().getName() + " : "
 495:                                  + name);
 496:       return view;
 497:     }
 498:   }
 499: 
 500:   /**
 501:    * Keeps track of the caret position and updates the currentRun
 502:    * <code>Element</code> and the <code>inputAttributes</code>.
 503:    */
 504:   class CaretTracker
 505:     implements CaretListener
 506:   {
 507:     /**
 508:      * Notifies an update of the caret position.
 509:      *
 510:      * @param ev the event for the caret update
 511:      */
 512:     public void caretUpdate(CaretEvent ev)
 513:     {
 514:       Object source = ev.getSource();
 515:       if (!(source instanceof JTextComponent))
 516:     throw new AssertionError("CaretEvents are expected to come from a"
 517:                  + "JTextComponent.");
 518: 
 519:       JTextComponent text = (JTextComponent) source;
 520:       Document doc = text.getDocument();
 521:       if (!(doc instanceof StyledDocument))
 522:     throw new AssertionError("The Document used by StyledEditorKits is"
 523:                  + "expected to be a StyledDocument");
 524: 
 525:       StyledDocument styleDoc = (StyledDocument) doc;
 526:       currentRun = styleDoc.getCharacterElement(ev.getDot());
 527:       createInputAttributes(currentRun, inputAttributes);
 528:     }
 529:   }
 530: 
 531:   /**
 532:    * Stores the <code>Element</code> at the current caret position. This
 533:    * is updated by {@link CaretTracker}.
 534:    */
 535:   Element currentRun;
 536: 
 537:   /**
 538:    * The current input attributes. This is updated by {@link CaretTracker}.
 539:    */
 540:   MutableAttributeSet inputAttributes;
 541: 
 542:   /**
 543:    * The CaretTracker that keeps track of the current input attributes, and
 544:    * the current character run Element.
 545:    */
 546:   CaretTracker caretTracker;
 547: 
 548:   /**
 549:    * The ViewFactory for StyledEditorKits.
 550:    */
 551:   StyledViewFactory viewFactory;
 552: 
 553:   /**
 554:    * Creates a new instance of <code>StyledEditorKit</code>.
 555:    */
 556:   public StyledEditorKit()
 557:   {
 558:     inputAttributes = new SimpleAttributeSet();
 559:   }
 560: 
 561:   /**
 562:    * Creates an exact copy of this <code>StyledEditorKit</code>.
 563:    *
 564:    * @return an exact copy of this <code>StyledEditorKit</code>
 565:    */
 566:   public Object clone()
 567:   {
 568:     StyledEditorKit clone = (StyledEditorKit) super.clone();
 569:     // FIXME: Investigate which fields must be copied.
 570:     return clone;
 571:   }
 572: 
 573:   /**
 574:    * Returns the <code>Action</code>s supported by this {@link EditorKit}.
 575:    * This includes the {@link BoldAction}, {@link ItalicAction} and
 576:    * {@link UnderlineAction} as well as the <code>Action</code>s supported
 577:    * by {@link DefaultEditorKit}.
 578:    *
 579:    * The other <code>Action</code>s of <code>StyledEditorKit</code> are not
 580:    * returned here, since they require a parameter and thus custom
 581:    * instantiation.
 582:    *
 583:    * @return the <code>Action</code>s supported by this {@link EditorKit}
 584:    */
 585:   public Action[] getActions()
 586:   {
 587:     Action[] actions1 = super.getActions();
 588:     Action[] myActions = new Action[] { 
 589:       new FontSizeAction("font-size-8", 8),
 590:       new FontSizeAction("font-size-10", 10),
 591:       new FontSizeAction("font-size-12", 12),
 592:       new FontSizeAction("font-size-14", 14),
 593:       new FontSizeAction("font-size-16", 16),
 594:       new FontSizeAction("font-size-18", 18),
 595:       new FontSizeAction("font-size-24", 24),
 596:       new FontSizeAction("font-size-36", 36),
 597:       new FontSizeAction("font-size-48", 48),
 598:       new FontFamilyAction("font-family-Serif", "Serif"),
 599:       new FontFamilyAction("font-family-Monospaced", "Monospaced"),
 600:       new FontFamilyAction("font-family-SansSerif", "SansSerif"),
 601:       new AlignmentAction("left-justify", StyleConstants.ALIGN_LEFT),
 602:       new AlignmentAction("center-justify", StyleConstants.ALIGN_CENTER),
 603:       new AlignmentAction("right-justify", StyleConstants.ALIGN_RIGHT),
 604:       new BoldAction(),
 605:       new ItalicAction(),
 606:       new UnderlineAction()
 607:     };
 608:     return TextAction.augmentList(actions1, myActions);
 609:   }
 610: 
 611:   /**
 612:    * Returns the current input attributes. These are automatically set on
 613:    * any newly inserted content, if not specified otherwise.
 614:    *
 615:    * @return the current input attributes
 616:    */
 617:   public MutableAttributeSet getInputAttributes()
 618:   {
 619:     return inputAttributes;
 620:   }
 621: 
 622:   /**
 623:    * Returns the {@link Element} that represents the character run at the
 624:    * current caret position.
 625:    *
 626:    * @return the {@link Element} that represents the character run at the
 627:    *         current caret position
 628:    */
 629:   public Element getCharacterAttributeRun()
 630:   {
 631:     return currentRun;
 632:   }
 633: 
 634:   /**
 635:    * Creates the default {@link Document} supported by this
 636:    * <code>EditorKit</code>. This is an instance of
 637:    * {@link DefaultStyledDocument} in this case but may be overridden by
 638:    * subclasses.
 639:    *
 640:    * @return an instance of <code>DefaultStyledDocument</code>
 641:    */
 642:   public Document createDefaultDocument()
 643:   {
 644:     return new DefaultStyledDocument();
 645:   }
 646: 
 647:   /**
 648:    * Installs this <code>EditorKit</code> on the specified {@link JEditorPane}.
 649:    * This basically involves setting up required listeners on the
 650:    * <code>JEditorPane</code>.
 651:    *
 652:    * @param component the <code>JEditorPane</code> to install this
 653:    *        <code>EditorKit</code> on
 654:    */
 655:   public void install(JEditorPane component)
 656:   {
 657:     CaretTracker tracker = new CaretTracker();
 658:     component.addCaretListener(tracker);
 659:   }
 660: 
 661:   /**
 662:    * Deinstalls this <code>EditorKit</code> from the specified
 663:    * {@link JEditorPane}. This basically involves removing all listeners from
 664:    * <code>JEditorPane</code> that have been set up by this
 665:    * <code>EditorKit</code>.
 666:    *
 667:    * @param component the <code>JEditorPane</code> from which to deinstall this
 668:    *        <code>EditorKit</code>
 669:    */
 670:   public void deinstall(JEditorPane component)
 671:   {
 672:     CaretTracker t = caretTracker;
 673:     if (t != null)
 674:       component.removeCaretListener(t);
 675:     caretTracker = null;
 676:   }
 677: 
 678:   /**
 679:    * Returns a {@link ViewFactory} that is able to create {@link View}s
 680:    * for {@link Element}s that are supported by this <code>EditorKit</code>,
 681:    * namely the following types of <code>Element</code>s:
 682:    *
 683:    * <ul>
 684:    * <li>{@link AbstractDocument#ContentElementName}</li>
 685:    * <li>{@link AbstractDocument#ParagraphElementName}</li>
 686:    * <li>{@link AbstractDocument#SectionElementName}</li>
 687:    * <li>{@link StyleConstants#ComponentElementName}</li>
 688:    * <li>{@link StyleConstants#IconElementName}</li>
 689:    * </ul>
 690:    *
 691:    * @return a {@link ViewFactory} that is able to create {@link View}s
 692:    *          for {@link Element}s that are supported by this <code>EditorKit</code>
 693:    */
 694:   public ViewFactory getViewFactory()
 695:   {
 696:     if (viewFactory == null)
 697:       viewFactory = new StyledViewFactory();
 698:     return viewFactory;
 699:   }
 700: 
 701:   /**
 702:    * Copies the text attributes from <code>element</code> to <code>set</code>.
 703:    * This is called everytime when the caret position changes to keep
 704:    * track of the current input attributes. The attributes in <code>set</code>
 705:    * are cleaned before adding the attributes of <code>element</code>.
 706:    *
 707:    * This method filters out attributes for element names, <code>Icon</code>s
 708:    * and <code>Component</code>s.
 709:    *
 710:    * @param element the <code>Element</code> from which to copy the text
 711:    *         attributes
 712:    * @param set the inputAttributes to copy the attributes to
 713:    */
 714:   protected void createInputAttributes(Element element,
 715:                        MutableAttributeSet set)
 716:   {
 717:     // FIXME: Filter out component, icon and element name attributes.
 718:     set.removeAttributes(set);
 719:     set.addAttributes(element.getAttributes());
 720:   }
 721: }