StyledEditorKit.java 22.1 KB
Newer Older
Tom Tromey committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/* StyledEditorKit.java --
   Copyright (C) 2002, 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text;

import java.awt.Color;
import java.awt.event.ActionEvent;

import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

/**
Tom Tromey committed
50
 * An {@link EditorKit} that supports editing styled text.
Tom Tromey committed
51 52
 *
 * @author Andrew Selkirk
Tom Tromey committed
53
 * @author Roman Kennke (roman@kennke.org)
Tom Tromey committed
54 55 56
 */
public class StyledEditorKit extends DefaultEditorKit
{
Tom Tromey committed
57
  /** The serialVersionUID. */
Tom Tromey committed
58 59 60
  private static final long serialVersionUID = 7002391892985555948L;

  /**
Tom Tromey committed
61
   * Toggles the underline attribute for the selected text.
Tom Tromey committed
62 63 64 65
   */
  public static class UnderlineAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
66
     * Creates an instance of <code>UnderlineAction</code>.
Tom Tromey committed
67 68 69
     */
    public UnderlineAction()
    {
70
      super("font-underline");
Tom Tromey committed
71 72 73
    }

    /**
Tom Tromey committed
74 75 76
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
77 78 79
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
80 81 82 83 84 85 86
      JEditorPane editor = getEditor(event);
      StyledDocument doc = getStyledDocument(editor);
      Element el = doc.getCharacterElement(editor.getSelectionStart());
      boolean isUnderline = StyleConstants.isUnderline(el.getAttributes());
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setUnderline(atts, ! isUnderline);
      setCharacterAttributes(editor, atts, false);
Tom Tromey committed
87 88 89 90
    }
  }

  /**
Tom Tromey committed
91
   * Toggles the italic attribute for the selected text.
Tom Tromey committed
92 93 94 95
   */
  public static class ItalicAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
96
     * Creates an instance of <code>ItalicAction</code>.
Tom Tromey committed
97 98 99
     */
    public ItalicAction()
    {
100
      super("font-italic");
Tom Tromey committed
101 102 103
    }

    /**
Tom Tromey committed
104 105 106
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
107 108 109
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
110 111 112 113 114 115 116
      JEditorPane editor = getEditor(event);
      StyledDocument doc = getStyledDocument(editor);
      Element el = doc.getCharacterElement(editor.getSelectionStart());
      boolean isItalic = StyleConstants.isItalic(el.getAttributes());
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setItalic(atts, ! isItalic);
      setCharacterAttributes(editor, atts, false);
Tom Tromey committed
117 118 119 120
    }
  }

  /**
Tom Tromey committed
121
   * Toggles the bold attribute for the selected text.
Tom Tromey committed
122 123 124 125
   */
  public static class BoldAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
126
     * Creates an instance of <code>BoldAction</code>.
Tom Tromey committed
127 128 129
     */
    public BoldAction()
    {
130
      super("font-bold");
Tom Tromey committed
131 132 133
    }

    /**
Tom Tromey committed
134 135 136
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
137 138 139
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
140 141 142 143 144
      JEditorPane editor = getEditor(event);
      StyledDocument doc = getStyledDocument(editor);
      Element el = doc.getCharacterElement(editor.getSelectionStart());
      boolean isBold = StyleConstants.isBold(el.getAttributes());
      SimpleAttributeSet atts = new SimpleAttributeSet();
145
      StyleConstants.setBold(atts, ! isBold);
Tom Tromey committed
146
      setCharacterAttributes(editor, atts, false);
Tom Tromey committed
147 148 149 150
    }
  }

  /**
Tom Tromey committed
151
   * Sets the alignment attribute on the selected text.
Tom Tromey committed
152 153 154 155
   */
  public static class AlignmentAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
156
     * The aligment to set.
Tom Tromey committed
157 158 159 160
     */
    private int a;

    /**
Tom Tromey committed
161 162 163 164 165
     * Creates a new instance of <code>AlignmentAction</code> to set the
     * alignment to <code>a</code>.
     *
     * @param nm the name of the Action
     * @param a the alignment to set
Tom Tromey committed
166 167 168
     */
    public AlignmentAction(String nm, int a)
    {
Tom Tromey committed
169 170
      super(nm);
      this.a = a;
Tom Tromey committed
171 172 173
    }

    /**
Tom Tromey committed
174 175 176
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
177 178 179
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
180 181 182
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setAlignment(atts, a);
      setParagraphAttributes(getEditor(event), atts, false);
Tom Tromey committed
183 184 185 186
    }
  }

  /**
Tom Tromey committed
187
   * Sets the foreground color attribute on the selected text.
Tom Tromey committed
188 189 190 191
   */
  public static class ForegroundAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
192
     * The foreground color to set.
Tom Tromey committed
193 194 195 196
     */
    private Color fg;

    /**
Tom Tromey committed
197 198 199 200 201
     * Creates a new instance of <code>ForegroundAction</code> to set the
     * foreground color to <code>fg</code>.
     *
     * @param nm the name of the Action
     * @param fg the foreground color to set
Tom Tromey committed
202 203 204
     */
    public ForegroundAction(String nm, Color fg)
    {
Tom Tromey committed
205 206
      super(nm);
      this.fg = fg;
Tom Tromey committed
207 208 209
    }

    /**
Tom Tromey committed
210 211 212
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
213 214 215
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
216 217 218
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setForeground(atts, fg);
      setCharacterAttributes(getEditor(event), atts, false);
Tom Tromey committed
219 220 221 222
    }
  }

  /**
Tom Tromey committed
223
   * Sets the font size attribute on the selected text.
Tom Tromey committed
224 225 226 227
   */
  public static class FontSizeAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
228
     * The font size to set.
Tom Tromey committed
229 230 231 232
     */
    private int size;

    /**
Tom Tromey committed
233 234 235 236 237
     * Creates a new instance of <code>FontSizeAction</code> to set the
     * font size to <code>size</code>.
     *
     * @param nm the name of the Action
     * @param size the font size to set
Tom Tromey committed
238 239 240
     */
    public FontSizeAction(String nm, int size)
    {
Tom Tromey committed
241 242
      super(nm);
      this.size = size;
Tom Tromey committed
243 244 245
    }

    /**
Tom Tromey committed
246 247 248
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
249 250 251
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
252 253 254
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setFontSize(atts, size);
      setCharacterAttributes(getEditor(event), atts, false);
Tom Tromey committed
255 256 257 258
    }
  }

  /**
Tom Tromey committed
259
   * Sets the font family attribute on the selected text.
Tom Tromey committed
260 261 262 263
   */
  public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
  {
    /**
Tom Tromey committed
264
     * The font family to set.
Tom Tromey committed
265 266 267 268
     */
    private String family;

    /**
Tom Tromey committed
269 270 271 272 273
     * Creates a new instance of <code>FontFamilyAction</code> to set the
     * font family to <code>family</code>.
     *
     * @param nm the name of the Action
     * @param family the font family to set
Tom Tromey committed
274 275 276
     */
    public FontFamilyAction(String nm, String family)
    {
Tom Tromey committed
277 278
      super(nm);
      this.family = family;
Tom Tromey committed
279 280 281
    }

    /**
Tom Tromey committed
282 283 284
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
Tom Tromey committed
285 286 287
     */
    public void actionPerformed(ActionEvent event)
    {
Tom Tromey committed
288 289 290
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setFontFamily(atts, family);
      setCharacterAttributes(getEditor(event), atts, false);
Tom Tromey committed
291 292 293 294
    }
  }

  /**
Tom Tromey committed
295 296
   * The abstract superclass of all styled TextActions. This class
   * provides some useful methods to manipulate the text attributes.
Tom Tromey committed
297 298 299 300
   */
  public abstract static class StyledTextAction extends TextAction
  {
    /**
Tom Tromey committed
301 302 303
     * Creates a new instance of <code>StyledTextAction</code>.
     *
     * @param nm the name of the <code>StyledTextAction</code>
Tom Tromey committed
304 305 306 307 308 309 310
     */
    public StyledTextAction(String nm)
    {
      super(nm);
    }

    /**
Tom Tromey committed
311 312 313 314 315 316
     * Returns the <code>JEditorPane</code> component from which the
     * <code>ActionEvent</code> originated.
     *
     * @param event the <code>ActionEvent</code>
     * @return the <code>JEditorPane</code> component from which the
     *         <code>ActionEvent</code> originated
Tom Tromey committed
317 318 319
     */
    protected final JEditorPane getEditor(ActionEvent event)
    {
Tom Tromey committed
320
      return (JEditorPane) getTextComponent(event);
Tom Tromey committed
321 322 323
    }

    /**
Tom Tromey committed
324 325 326 327 328 329 330 331 332
     * Sets the specified character attributes on the currently selected
     * text of <code>editor</code>. If <code>editor</code> does not have
     * a selection, then the attributes are used as input attributes
     * for newly inserted content.
     *
     * @param editor the <code>JEditorPane</code> component
     * @param atts the text attributes to set
     * @param replace if <code>true</code> the current attributes of the
     *        selection are replaces, otherwise they are merged
Tom Tromey committed
333
     */
Tom Tromey committed
334 335 336
    protected final void setCharacterAttributes(JEditorPane editor,
                                                AttributeSet atts,
                                                boolean replace)
Tom Tromey committed
337
    {
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
      int p0 = editor.getSelectionStart();
      int p1 = editor.getSelectionEnd();
      if (p0 != p1)
        {
          StyledDocument doc = getStyledDocument(editor);
          doc.setCharacterAttributes(p0, p1 - p0, atts, replace);
        }
      // Update input attributes.
      StyledEditorKit kit = getStyledEditorKit(editor);
      MutableAttributeSet inputAtts = kit.getInputAttributes();
      if (replace)
        {
          inputAtts.removeAttributes(inputAtts);
        }
      inputAtts.addAttributes(atts);
Tom Tromey committed
353 354 355
    }

    /**
Tom Tromey committed
356 357 358 359 360 361
     * Returns the {@link StyledDocument} that is used by <code>editor</code>.
     *
     * @param editor the <code>JEditorPane</code> from which to get the
     *        <code>StyledDocument</code>
     *
     * @return the {@link StyledDocument} that is used by <code>editor</code>
Tom Tromey committed
362
     */
Tom Tromey committed
363
    protected final StyledDocument getStyledDocument(JEditorPane editor)
Tom Tromey committed
364
    {
Tom Tromey committed
365 366 367 368 369 370
      Document doc = editor.getDocument();
      if (!(doc instanceof StyledDocument))
	throw new AssertionError("The Document for StyledEditorKits is "
				 + "expected to be a StyledDocument.");

      return (StyledDocument) doc;
Tom Tromey committed
371 372 373
    }

    /**
Tom Tromey committed
374 375 376 377 378 379
     * Returns the {@link StyledEditorKit} that is used by <code>editor</code>.
     *
     * @param editor the <code>JEditorPane</code> from which to get the
     *        <code>StyledEditorKit</code>
     *
     * @return the {@link StyledEditorKit} that is used by <code>editor</code>
Tom Tromey committed
380
     */
Tom Tromey committed
381
    protected final StyledEditorKit getStyledEditorKit(JEditorPane editor)
Tom Tromey committed
382
    {
Tom Tromey committed
383 384 385 386 387 388
      EditorKit kit = editor.getEditorKit();
      if (!(kit instanceof StyledEditorKit))
	throw new AssertionError("The EditorKit for StyledDocuments is "
				 + "expected to be a StyledEditorKit.");

      return (StyledEditorKit) kit;
Tom Tromey committed
389 390 391
    }

    /**
Tom Tromey committed
392 393 394 395 396 397 398 399 400 401
     * Sets the specified character attributes on the paragraph that
     * contains the currently selected
     * text of <code>editor</code>. If <code>editor</code> does not have
     * a selection, then the attributes are set on the paragraph that
     * contains the current caret position.
     *
     * @param editor the <code>JEditorPane</code> component
     * @param atts the text attributes to set
     * @param replace if <code>true</code> the current attributes of the
     *        selection are replaces, otherwise they are merged
Tom Tromey committed
402
     */
Tom Tromey committed
403 404 405
    protected final void setParagraphAttributes(JEditorPane editor,
                                                AttributeSet atts,
                                                boolean replace)
Tom Tromey committed
406
    {
Tom Tromey committed
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
      Document doc = editor.getDocument();
      if (doc instanceof StyledDocument)
	{
	  StyledDocument styleDoc = (StyledDocument) editor.getDocument();
	  EditorKit kit = editor.getEditorKit();
	  if (!(kit instanceof StyledEditorKit))
	    {
	      StyledEditorKit styleKit = (StyledEditorKit) kit;
	      int start = editor.getSelectionStart();
	      int end = editor.getSelectionEnd();
	      int dot = editor.getCaret().getDot();
	      if (start == dot && end == dot)
		{
		  // If there is no selection, then we only update the
		  // input attributes.
		  MutableAttributeSet inputAttributes =
		    styleKit.getInputAttributes();
		  inputAttributes.addAttributes(atts);
		}
	      else
		styleDoc.setParagraphAttributes(start, end, atts, replace);
	    }
	  else
	    throw new AssertionError("The EditorKit for StyledTextActions "
				     + "is expected to be a StyledEditorKit");
	}
      else
	throw new AssertionError("The Document for StyledTextActions is "
				 + "expected to be a StyledDocument.");
Tom Tromey committed
436 437 438 439
    }
  }

  /**
Tom Tromey committed
440 441 442 443 444
   * A {@link ViewFactory} that is able to create {@link View}s for
   * the <code>Element</code>s that are supported by
   * <code>StyledEditorKit</code>, namely the following types of Elements:
   *
   * <ul>
445 446 447 448 449
   * <li>{@link AbstractDocument#ContentElementName}</li>
   * <li>{@link AbstractDocument#ParagraphElementName}</li>
   * <li>{@link AbstractDocument#SectionElementName}</li>
   * <li>{@link StyleConstants#ComponentElementName}</li>
   * <li>{@link StyleConstants#IconElementName}</li>
Tom Tromey committed
450
   * </ul>
Tom Tromey committed
451 452 453 454 455
   */
  static class StyledViewFactory
    implements ViewFactory
  {
    /**
Tom Tromey committed
456 457 458 459 460 461 462
     * Creates a {@link View} for the specified <code>Element</code>.
     *
     * @param element the <code>Element</code> to create a <code>View</code>
     *        for
     * @return the <code>View</code> for the specified <code>Element</code>
     *         or <code>null</code> if the type of <code>element</code> is
     *         not supported
Tom Tromey committed
463
     */
Tom Tromey committed
464
    public View create(Element element)
Tom Tromey committed
465
    {
Tom Tromey committed
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
      String name = element.getName();
      View view = null;
      if (name.equals(AbstractDocument.ContentElementName))
	view = new LabelView(element);
      else if (name.equals(AbstractDocument.ParagraphElementName))
	view = new ParagraphView(element);
      else if (name.equals(AbstractDocument.SectionElementName))
	view = new BoxView(element, View.Y_AXIS);
      else if (name.equals(StyleConstants.ComponentElementName))
	view = new ComponentView(element);
      else if (name.equals(StyleConstants.IconElementName))
	view = new IconView(element);
      else
        throw new AssertionError("Unknown Element type: "
                                 + element.getClass().getName() + " : "
                                 + name);
      return view;
Tom Tromey committed
483 484 485 486
    }
  }

  /**
Tom Tromey committed
487 488
   * Keeps track of the caret position and updates the currentRun
   * <code>Element</code> and the <code>inputAttributes</code>.
Tom Tromey committed
489
   */
Tom Tromey committed
490 491
  class CaretTracker
    implements CaretListener
Tom Tromey committed
492 493
  {
    /**
Tom Tromey committed
494 495 496
     * Notifies an update of the caret position.
     *
     * @param ev the event for the caret update
Tom Tromey committed
497
     */
Tom Tromey committed
498
    public void caretUpdate(CaretEvent ev)
Tom Tromey committed
499
    {
Tom Tromey committed
500 501 502 503 504 505 506 507 508 509 510 511 512 513
      Object source = ev.getSource();
      if (!(source instanceof JTextComponent))
	throw new AssertionError("CaretEvents are expected to come from a"
				 + "JTextComponent.");

      JTextComponent text = (JTextComponent) source;
      Document doc = text.getDocument();
      if (!(doc instanceof StyledDocument))
	throw new AssertionError("The Document used by StyledEditorKits is"
				 + "expected to be a StyledDocument");

      StyledDocument styleDoc = (StyledDocument) doc;
      currentRun = styleDoc.getCharacterElement(ev.getDot());
      createInputAttributes(currentRun, inputAttributes);
Tom Tromey committed
514 515 516 517
    }
  }

  /**
Tom Tromey committed
518 519
   * Stores the <code>Element</code> at the current caret position. This
   * is updated by {@link CaretTracker}.
Tom Tromey committed
520 521 522 523
   */
  Element currentRun;

  /**
Tom Tromey committed
524
   * The current input attributes. This is updated by {@link CaretTracker}.
Tom Tromey committed
525
   */
Tom Tromey committed
526
  MutableAttributeSet inputAttributes;
Tom Tromey committed
527 528

  /**
Tom Tromey committed
529 530
   * The CaretTracker that keeps track of the current input attributes, and
   * the current character run Element.
Tom Tromey committed
531
   */
Tom Tromey committed
532 533 534 535 536 537
  CaretTracker caretTracker;

  /**
   * The ViewFactory for StyledEditorKits.
   */
  StyledViewFactory viewFactory;
Tom Tromey committed
538 539

  /**
Tom Tromey committed
540
   * Creates a new instance of <code>StyledEditorKit</code>.
Tom Tromey committed
541 542 543
   */
  public StyledEditorKit()
  {
Tom Tromey committed
544
    inputAttributes = new SimpleAttributeSet();
Tom Tromey committed
545 546 547
  }

  /**
Tom Tromey committed
548 549 550
   * Creates an exact copy of this <code>StyledEditorKit</code>.
   *
   * @return an exact copy of this <code>StyledEditorKit</code>
Tom Tromey committed
551 552 553
   */
  public Object clone()
  {
Tom Tromey committed
554 555 556
    StyledEditorKit clone = (StyledEditorKit) super.clone();
    // FIXME: Investigate which fields must be copied.
    return clone;
Tom Tromey committed
557 558 559
  }

  /**
Tom Tromey committed
560 561 562 563 564 565 566 567 568 569
   * Returns the <code>Action</code>s supported by this {@link EditorKit}.
   * This includes the {@link BoldAction}, {@link ItalicAction} and
   * {@link UnderlineAction} as well as the <code>Action</code>s supported
   * by {@link DefaultEditorKit}.
   *
   * The other <code>Action</code>s of <code>StyledEditorKit</code> are not
   * returned here, since they require a parameter and thus custom
   * instantiation.
   *
   * @return the <code>Action</code>s supported by this {@link EditorKit}
Tom Tromey committed
570 571 572
   */
  public Action[] getActions()
  {
Tom Tromey committed
573
    Action[] actions1 = super.getActions();
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
    Action[] myActions = new Action[] { 
      new FontSizeAction("font-size-8", 8),
      new FontSizeAction("font-size-10", 10),
      new FontSizeAction("font-size-12", 12),
      new FontSizeAction("font-size-14", 14),
      new FontSizeAction("font-size-16", 16),
      new FontSizeAction("font-size-18", 18),
      new FontSizeAction("font-size-24", 24),
      new FontSizeAction("font-size-36", 36),
      new FontSizeAction("font-size-48", 48),
      new FontFamilyAction("font-family-Serif", "Serif"),
      new FontFamilyAction("font-family-Monospaced", "Monospaced"),
      new FontFamilyAction("font-family-SansSerif", "SansSerif"),
      new AlignmentAction("left-justify", StyleConstants.ALIGN_LEFT),
      new AlignmentAction("center-justify", StyleConstants.ALIGN_CENTER),
      new AlignmentAction("right-justify", StyleConstants.ALIGN_RIGHT),
      new BoldAction(),
      new ItalicAction(),
      new UnderlineAction()
    };
Tom Tromey committed
594
    return TextAction.augmentList(actions1, myActions);
Tom Tromey committed
595 596 597
  }

  /**
Tom Tromey committed
598 599 600 601
   * Returns the current input attributes. These are automatically set on
   * any newly inserted content, if not specified otherwise.
   *
   * @return the current input attributes
Tom Tromey committed
602 603 604
   */
  public MutableAttributeSet getInputAttributes()
  {
Tom Tromey committed
605
    return inputAttributes;
Tom Tromey committed
606 607 608
  }

  /**
Tom Tromey committed
609 610 611 612 613
   * Returns the {@link Element} that represents the character run at the
   * current caret position.
   *
   * @return the {@link Element} that represents the character run at the
   *         current caret position
Tom Tromey committed
614 615 616
   */
  public Element getCharacterAttributeRun()
  {
Tom Tromey committed
617
    return currentRun;
Tom Tromey committed
618 619 620
  }

  /**
Tom Tromey committed
621 622 623 624 625 626
   * Creates the default {@link Document} supported by this
   * <code>EditorKit</code>. This is an instance of
   * {@link DefaultStyledDocument} in this case but may be overridden by
   * subclasses.
   *
   * @return an instance of <code>DefaultStyledDocument</code>
Tom Tromey committed
627 628 629
   */
  public Document createDefaultDocument()
  {
Tom Tromey committed
630
    return new DefaultStyledDocument();
Tom Tromey committed
631 632 633
  }

  /**
Tom Tromey committed
634 635 636 637 638 639
   * Installs this <code>EditorKit</code> on the specified {@link JEditorPane}.
   * This basically involves setting up required listeners on the
   * <code>JEditorPane</code>.
   *
   * @param component the <code>JEditorPane</code> to install this
   *        <code>EditorKit</code> on
Tom Tromey committed
640 641 642
   */
  public void install(JEditorPane component)
  {
Tom Tromey committed
643 644
    CaretTracker tracker = new CaretTracker();
    component.addCaretListener(tracker);
Tom Tromey committed
645 646 647
  }

  /**
Tom Tromey committed
648 649 650 651 652 653 654
   * Deinstalls this <code>EditorKit</code> from the specified
   * {@link JEditorPane}. This basically involves removing all listeners from
   * <code>JEditorPane</code> that have been set up by this
   * <code>EditorKit</code>.
   *
   * @param component the <code>JEditorPane</code> from which to deinstall this
   *        <code>EditorKit</code>
Tom Tromey committed
655 656 657
   */
  public void deinstall(JEditorPane component)
  {
Tom Tromey committed
658 659 660 661
    CaretTracker t = caretTracker;
    if (t != null)
      component.removeCaretListener(t);
    caretTracker = null;
Tom Tromey committed
662 663 664
  }

  /**
Tom Tromey committed
665 666 667 668 669
   * Returns a {@link ViewFactory} that is able to create {@link View}s
   * for {@link Element}s that are supported by this <code>EditorKit</code>,
   * namely the following types of <code>Element</code>s:
   *
   * <ul>
670 671 672 673 674
   * <li>{@link AbstractDocument#ContentElementName}</li>
   * <li>{@link AbstractDocument#ParagraphElementName}</li>
   * <li>{@link AbstractDocument#SectionElementName}</li>
   * <li>{@link StyleConstants#ComponentElementName}</li>
   * <li>{@link StyleConstants#IconElementName}</li>
Tom Tromey committed
675 676 677 678
   * </ul>
   *
   * @return a {@link ViewFactory} that is able to create {@link View}s
   *          for {@link Element}s that are supported by this <code>EditorKit</code>
Tom Tromey committed
679 680 681
   */
  public ViewFactory getViewFactory()
  {
Tom Tromey committed
682 683 684
    if (viewFactory == null)
      viewFactory = new StyledViewFactory();
    return viewFactory;
Tom Tromey committed
685 686 687
  }

  /**
Tom Tromey committed
688 689 690 691 692 693 694 695 696 697 698
   * Copies the text attributes from <code>element</code> to <code>set</code>.
   * This is called everytime when the caret position changes to keep
   * track of the current input attributes. The attributes in <code>set</code>
   * are cleaned before adding the attributes of <code>element</code>.
   *
   * This method filters out attributes for element names, <code>Icon</code>s
   * and <code>Component</code>s.
   *
   * @param element the <code>Element</code> from which to copy the text
   *         attributes
   * @param set the inputAttributes to copy the attributes to
Tom Tromey committed
699
   */
Tom Tromey committed
700 701
  protected void createInputAttributes(Element element,
				       MutableAttributeSet set)
Tom Tromey committed
702
  {
Tom Tromey committed
703
    // FIXME: Filter out component, icon and element name attributes.
704 705
    set.removeAttributes(set);
    set.addAttributes(element.getAttributes());
Tom Tromey committed
706 707
  }
}