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