Source for javax.swing.text.DefaultEditorKit

   1: /* DefaultEditorKit.java --
   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.text;
  40: 
  41: import gnu.java.lang.CPStringBuilder;
  42: 
  43: import java.awt.Toolkit;
  44: import java.awt.event.ActionEvent;
  45: 
  46: import java.io.BufferedReader;
  47: import java.io.IOException;
  48: import java.io.InputStream;
  49: import java.io.InputStreamReader;
  50: import java.io.OutputStream;
  51: import java.io.OutputStreamWriter;
  52: import java.io.Reader;
  53: import java.io.Writer;
  54: 
  55: import javax.swing.Action;
  56: import javax.swing.SwingConstants;
  57: 
  58: /**
  59:  * The default implementation of {@link EditorKit}. This <code>EditorKit</code>
  60:  * a plain text <code>Document</code> and several commands that together
  61:  * make up a basic editor, like cut / copy + paste.
  62:  *
  63:  * @author original author unknown
  64:  * @author Roman Kennke (roman@kennke.org)
  65:  * @author Robert Schuster (robertschuster@fsfe.org)
  66:  */
  67: public class DefaultEditorKit extends EditorKit
  68: {
  69:   static class SelectionPreviousWordAction
  70:       extends TextAction
  71:   {
  72:     SelectionPreviousWordAction()
  73:     {
  74:       super(selectionPreviousWordAction);
  75:     }
  76: 
  77:     public void actionPerformed(ActionEvent event)
  78:     {
  79:       try
  80:         {
  81:           JTextComponent t = getTextComponent(event);
  82: 
  83:           if (t != null)
  84:             {
  85:               int offs = Utilities.getPreviousWord(t, t.getCaretPosition());
  86: 
  87:               Caret c = t.getCaret();
  88:               c.moveDot(offs);
  89:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
  90:             }
  91:         }
  92:       catch(BadLocationException ble)
  93:         {
  94:           // Can't happen.
  95:         }
  96:     }
  97:   }
  98: 
  99:   static class SelectionNextWordAction
 100:       extends TextAction
 101:   {
 102:     SelectionNextWordAction()
 103:     {
 104:       super(selectionNextWordAction);
 105:     }
 106: 
 107:     public void actionPerformed(ActionEvent event)
 108:     {
 109:       try
 110:         {
 111:           JTextComponent t = getTextComponent(event);
 112: 
 113:           if (t != null)
 114:             {
 115:               int offs = Utilities.getNextWord(t, t.getCaretPosition());
 116: 
 117:               Caret c = t.getCaret();
 118:               c.moveDot(offs);
 119:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 120:             }
 121:         }
 122:       catch(BadLocationException ble)
 123:         {
 124:           // Can't happen.
 125:         }
 126:     }
 127:   }
 128: 
 129:   static class SelectionBeginWordAction extends TextAction
 130:   {
 131:     SelectionBeginWordAction()
 132:     {
 133:       super(selectionBeginWordAction);
 134:     }
 135: 
 136:     public void actionPerformed(ActionEvent event)
 137:     {
 138:       try
 139:         {
 140:           JTextComponent t = getTextComponent(event);
 141: 
 142:           if (t != null)
 143:             {
 144:               int offs = Utilities.getWordStart(t, t.getCaretPosition());
 145: 
 146:               Caret c = t.getCaret();
 147:               c.moveDot(offs);
 148:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 149:             }
 150:         }
 151:       catch(BadLocationException ble)
 152:         {
 153:           // Can't happen.
 154:         }
 155:     }
 156:   }
 157: 
 158:   static class SelectionEndWordAction extends TextAction
 159:   {
 160:     SelectionEndWordAction()
 161:     {
 162:       super(selectionEndWordAction);
 163:     }
 164: 
 165:     public void actionPerformed(ActionEvent event)
 166:     {
 167:       try
 168:         {
 169:           JTextComponent t = getTextComponent(event);
 170: 
 171:           if (t != null)
 172:             {
 173:               int offs = Utilities.getWordEnd(t, t.getCaretPosition());
 174: 
 175:               Caret c = t.getCaret();
 176:               c.moveDot(offs);
 177:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 178:             }
 179:         }
 180:       catch(BadLocationException ble)
 181:         {
 182:           // Can't happen.
 183:         }
 184:     }
 185:   }
 186: 
 187:   static class BeginWordAction extends TextAction
 188:   {
 189:     BeginWordAction()
 190:     {
 191:       super(beginWordAction);
 192:     }
 193: 
 194:     public void actionPerformed(ActionEvent event)
 195:     {
 196:       try
 197:         {
 198:           JTextComponent t = getTextComponent(event);
 199: 
 200:           if (t != null)
 201:             {
 202:               int offs = Utilities.getWordStart(t, t.getCaretPosition());
 203: 
 204:               Caret c = t.getCaret();
 205:               c.setDot(offs);
 206:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 207:             }
 208:         }
 209:       catch(BadLocationException ble)
 210:         {
 211:           // Can't happen.
 212:         }
 213:     }
 214:   }
 215: 
 216:   static class EndWordAction extends TextAction
 217:   {
 218:     EndWordAction()
 219:     {
 220:       super(endWordAction);
 221:     }
 222: 
 223:     public void actionPerformed(ActionEvent event)
 224:     {
 225:       try
 226:         {
 227:           JTextComponent t = getTextComponent(event);
 228: 
 229:           if (t != null)
 230:             {
 231:               int offs = Utilities.getWordEnd(t, t.getCaretPosition());
 232: 
 233:               Caret c = t.getCaret();
 234:               c.setDot(offs);
 235:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 236:             }
 237:         }
 238:       catch(BadLocationException ble)
 239:         {
 240:           // Can't happen.
 241:         }
 242:     }
 243:   }
 244: 
 245:   static class PreviousWordAction
 246:       extends TextAction
 247:   {
 248:     PreviousWordAction()
 249:     {
 250:       super(previousWordAction);
 251:     }
 252: 
 253:     public void actionPerformed(ActionEvent event)
 254:     {
 255:       try
 256:         {
 257:           JTextComponent t = getTextComponent(event);
 258: 
 259:           if (t != null)
 260:             {
 261:               int offs = Utilities.getPreviousWord(t, t.getCaretPosition());
 262: 
 263:               Caret c = t.getCaret();
 264:               c.setDot(offs);
 265:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 266:             }
 267:         }
 268:       catch(BadLocationException ble)
 269:         {
 270:           // Can't happen.
 271:         }
 272:     }
 273:   }
 274: 
 275:   static class NextWordAction
 276:       extends TextAction
 277:   {
 278:     NextWordAction()
 279:     {
 280:       super(nextWordAction);
 281:     }
 282: 
 283:     public void actionPerformed(ActionEvent event)
 284:     {
 285:       try
 286:         {
 287:           JTextComponent t = getTextComponent(event);
 288: 
 289:           if (t != null)
 290:             {
 291:               int offs = Utilities.getNextWord(t, t.getCaretPosition());
 292: 
 293:               Caret c = t.getCaret();
 294:               c.setDot(offs);
 295:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 296:             }
 297:         }
 298:       catch(BadLocationException ble)
 299:         {
 300:           // Can't happen.
 301:         }
 302:     }
 303:   }
 304: 
 305:   static class SelectAllAction
 306:       extends TextAction
 307:   {
 308:     SelectAllAction()
 309:     {
 310:       super(selectAllAction);
 311:     }
 312: 
 313:     public void actionPerformed(ActionEvent event)
 314:     {
 315:       JTextComponent t = getTextComponent(event);
 316:       if (t != null)
 317:         {
 318:           int offs = t.getDocument().getLength();
 319:           Caret c = t.getCaret();
 320:           c.setDot(0);
 321:           c.moveDot(offs);
 322:           try
 323:             {
 324:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 325:             }
 326:           catch(BadLocationException ble)
 327:             {
 328:               // Can't happen.
 329:             }
 330:         }
 331:     }
 332:   }
 333: 
 334:   static class SelectionBeginAction
 335:       extends TextAction
 336:   {
 337:     SelectionBeginAction()
 338:     {
 339:       super(selectionBeginAction);
 340:     }
 341: 
 342:     public void actionPerformed(ActionEvent event)
 343:     {
 344:       JTextComponent t = getTextComponent(event);
 345:       if (t != null)
 346:         {
 347:           Caret c = t.getCaret();
 348:           c.moveDot(0);
 349:           try
 350:             {
 351:               c.setMagicCaretPosition(t.modelToView(0).getLocation());
 352:             }
 353:           catch(BadLocationException ble)
 354:             {
 355:               // Can't happen.
 356:             }
 357:         }
 358:     }
 359:   }
 360: 
 361:   static class SelectionEndAction
 362:       extends TextAction
 363:   {
 364:     SelectionEndAction()
 365:     {
 366:       super(selectionEndAction);
 367:     }
 368: 
 369:     public void actionPerformed(ActionEvent event)
 370:     {
 371:       JTextComponent t = getTextComponent(event);
 372:       if (t != null)
 373:         {
 374:           int offs = t.getDocument().getLength();
 375:           Caret c = t.getCaret();
 376:           c.moveDot(offs);
 377:           try
 378:             {
 379:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 380:             }
 381:           catch(BadLocationException ble)
 382:             {
 383:               // Can't happen.
 384:             }
 385:         }
 386:     }
 387:   }
 388: 
 389:   static class SelectionBeginLineAction
 390:     extends TextAction
 391:   {
 392: 
 393:     SelectionBeginLineAction()
 394:     {
 395:       super(selectionBeginLineAction);
 396:     }
 397: 
 398:     public void actionPerformed(ActionEvent event)
 399:     {
 400:       JTextComponent t = getTextComponent(event);
 401:       if (t != null)
 402:         {
 403:           Caret c = t.getCaret();
 404:           try
 405:             {
 406:               int offs = Utilities.getRowStart(t, c.getDot());
 407:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 408:             }
 409:           catch(BadLocationException ble)
 410:             {
 411:               // Can't happen.
 412:             }
 413:         }
 414:     }
 415:   }
 416: 
 417:   static class SelectionEndLineAction
 418:       extends TextAction
 419:   {
 420:     SelectionEndLineAction()
 421:     {
 422:       super(selectionEndLineAction);
 423:     }
 424: 
 425:     public void actionPerformed(ActionEvent event)
 426:     {
 427:       JTextComponent t = getTextComponent(event);
 428:       if (t != null)
 429:         {
 430:           Caret c = t.getCaret();
 431:           try
 432:             {
 433:               int offs = Utilities.getRowEnd(t, c.getDot());
 434:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 435:             }
 436:           catch(BadLocationException ble)
 437:             {
 438:               // Can't happen.
 439:             }
 440:         }
 441:     }
 442:   }
 443: 
 444:   static class SelectLineAction extends TextAction
 445:   {
 446:     SelectLineAction()
 447:     {
 448:       super(selectLineAction);
 449:     }
 450: 
 451:     public void actionPerformed(ActionEvent event)
 452:     {
 453:       JTextComponent t = getTextComponent(event);
 454:       if (t != null)
 455:         {
 456:           Caret c = t.getCaret();
 457:           try
 458:             {
 459:               int offs1 = Utilities.getRowStart(t, c.getDot());
 460:               int offs2 = Utilities.getRowEnd(t, c.getDot());
 461:               c.setDot(offs2);
 462:               c.moveDot(offs1);
 463:               c.setMagicCaretPosition(t.modelToView(offs2).getLocation());
 464:             }
 465:           catch(BadLocationException ble)
 466:             {
 467:               // Can't happen.
 468:             }
 469:         }
 470:     }
 471:   }
 472: 
 473:   static class SelectWordAction extends TextAction
 474:   {
 475:     SelectWordAction()
 476:     {
 477:       super(selectWordAction);
 478:     }
 479: 
 480:     public void actionPerformed(ActionEvent event)
 481:     {
 482:       JTextComponent t = getTextComponent(event);
 483:       if (t != null)
 484:         {
 485:           Caret c = t.getCaret();
 486:           int dot = c.getDot();
 487:           try
 488:             {
 489:               int wordStart = Utilities.getWordStart(t, dot);
 490: 
 491:               if (dot == wordStart)
 492:                 {
 493:                   // Current cursor position is on the first character in a word.
 494:                   c.setDot(wordStart);
 495:                   c.moveDot(Utilities.getWordEnd(t, wordStart));
 496:                 }
 497:               else
 498:                 {
 499:                   // Current cursor position is not on the first character
 500:                   // in a word.
 501:                   int nextWord = Utilities.getNextWord(t, dot);
 502:                   int previousWord = Utilities.getPreviousWord(t, dot);
 503:                   int previousWordEnd = Utilities.getWordEnd(t, previousWord);
 504: 
 505:                   // Cursor position is in the space between two words. In such a
 506:                   // situation just select the space.
 507:                   if (dot >= previousWordEnd && dot <= nextWord)
 508:                     {
 509:                       c.setDot(previousWordEnd);
 510:                       c.moveDot(nextWord);
 511:                     }
 512:                   else
 513:                     {
 514:                       // Cursor position is inside a word. Just select it then.
 515:                       c.setDot(previousWord);
 516:                       c.moveDot(previousWordEnd);
 517:                     }
 518:                 }
 519: 
 520:               // If the position was updated change the magic caret position
 521:               // as well.
 522:               if (c.getDot() != dot)
 523:                 c.setMagicCaretPosition(t.modelToView(c.getDot()).getLocation());
 524:             }
 525:           catch(BadLocationException ble)
 526:             {
 527:               // Can't happen.
 528:             }
 529:         }
 530:     }
 531:   }
 532: 
 533:   static class SelectionDownAction
 534:       extends TextAction.VerticalMovementAction
 535:   {
 536:     SelectionDownAction()
 537:     {
 538:       super(selectionDownAction, SwingConstants.SOUTH);
 539:     }
 540: 
 541:     protected void actionPerformedImpl(Caret c, int offs)
 542:     {
 543:       c.moveDot(offs);
 544:     }
 545: 
 546:   }
 547: 
 548:   static class SelectionUpAction
 549:   extends TextAction.VerticalMovementAction
 550:   {
 551:     SelectionUpAction()
 552:     {
 553:       super(selectionUpAction, SwingConstants.NORTH);
 554:     }
 555: 
 556:     protected void actionPerformedImpl(Caret c, int offs)
 557:     {
 558:       c.moveDot(offs);
 559:     }
 560: 
 561:   }
 562: 
 563:   static class SelectionForwardAction
 564:       extends TextAction.HorizontalMovementAction
 565:   {
 566:     SelectionForwardAction()
 567:     {
 568:       super(selectionForwardAction, SwingConstants.EAST);
 569:     }
 570: 
 571:     protected void actionPerformedImpl(Caret c, int offs)
 572:     {
 573:       c.moveDot(offs);
 574:     }
 575:   }
 576: 
 577:   static class SelectionBackwardAction
 578:       extends TextAction.HorizontalMovementAction
 579:   {
 580:     SelectionBackwardAction()
 581:     {
 582:       super(selectionBackwardAction, SwingConstants.WEST);
 583:     }
 584: 
 585:     protected void actionPerformedImpl(Caret c, int offs)
 586:     {
 587:       c.moveDot(offs);
 588:     }
 589:   }
 590: 
 591:   static class DownAction
 592:       extends TextAction.VerticalMovementAction
 593:   {
 594:     DownAction()
 595:     {
 596:       super(downAction, SwingConstants.SOUTH);
 597:     }
 598: 
 599:     protected void actionPerformedImpl(Caret c, int offs)
 600:     {
 601:       c.setDot(offs);
 602:     }
 603:   }
 604: 
 605:   static class UpAction
 606:       extends TextAction.VerticalMovementAction
 607:   {
 608:     UpAction()
 609:     {
 610:       super(upAction, SwingConstants.NORTH);
 611:     }
 612: 
 613:     protected void actionPerformedImpl(Caret c, int offs)
 614:     {
 615:       c.setDot(offs);
 616:     }
 617: 
 618:   }
 619: 
 620:   static class ForwardAction
 621:       extends TextAction.HorizontalMovementAction
 622:   {
 623:     ForwardAction()
 624:     {
 625:       super(forwardAction, SwingConstants.EAST);
 626:     }
 627: 
 628:     protected void actionPerformedImpl(Caret c, int offs)
 629:     {
 630:       c.setDot(offs);
 631:     }
 632: 
 633:   }
 634: 
 635:   static class BackwardAction
 636:       extends TextAction.HorizontalMovementAction
 637:   {
 638:     BackwardAction()
 639:     {
 640:       super(backwardAction, SwingConstants.WEST);
 641:     }
 642: 
 643:     protected void actionPerformedImpl(Caret c, int offs)
 644:     {
 645:       c.setDot(offs);
 646:     }
 647: 
 648:   }
 649: 
 650:   static class DeletePrevCharAction
 651:       extends TextAction
 652:   {
 653:     DeletePrevCharAction()
 654:     {
 655:       super(deletePrevCharAction);
 656:     }
 657: 
 658:     public void actionPerformed(ActionEvent event)
 659:     {
 660:       JTextComponent t = getTextComponent(event);
 661:       if (t != null)
 662:         {
 663:           try
 664:             {
 665:               int pos = t.getSelectionStart();
 666:               int len = t.getSelectionEnd() - pos;
 667: 
 668:               if (len > 0)
 669:                   t.getDocument().remove(pos, len);
 670:               else if (pos > 0)
 671:                 {
 672:                   pos--;
 673:                   t.getDocument().remove(pos, 1);
 674:                   Caret c = t.getCaret();
 675:                   c.setDot(pos);
 676:                   c.setMagicCaretPosition(t.modelToView(pos).getLocation());
 677:                 }
 678:             }
 679:           catch (BadLocationException e)
 680:             {
 681:               // FIXME: we're not authorized to throw this.. swallow it?
 682:             }
 683:         }
 684:     }
 685:   }
 686: 
 687:   static class DeleteNextCharAction
 688:       extends TextAction
 689:   {
 690:     DeleteNextCharAction()
 691:     {
 692:       super(deleteNextCharAction);
 693:     }
 694: 
 695:     public void actionPerformed(ActionEvent event)
 696:     {
 697:       JTextComponent t = getTextComponent(event);
 698:       if (t != null)
 699:         {
 700:           try
 701:             {
 702:               int pos = t.getSelectionStart();
 703:               int len = t.getSelectionEnd() - pos;
 704: 
 705:               if (len > 0)
 706:                   t.getDocument().remove(pos, len);
 707:               else if (pos < t.getDocument().getLength())
 708:                   t.getDocument().remove(pos, 1);
 709: 
 710:               Caret c = t.getCaret();
 711:               c.setDot(pos);
 712:               c.setMagicCaretPosition(t.modelToView(pos).getLocation());
 713:             }
 714:           catch (BadLocationException e)
 715:             {
 716:               // FIXME: we're not authorized to throw this.. swallow it?
 717:             }
 718:         }
 719:     }
 720:   }
 721: 
 722:   static class EndLineAction
 723:       extends TextAction
 724:   {
 725:     EndLineAction()
 726:     {
 727:       super(endLineAction);
 728:     }
 729: 
 730:     public void actionPerformed(ActionEvent event)
 731:     {
 732:       JTextComponent t = getTextComponent(event);
 733:       if (t != null)
 734:         {
 735:           try
 736:             {
 737:               int offs = Utilities.getRowEnd(t, t.getCaretPosition());
 738:               if (offs > -1)
 739:                 {
 740:                   Caret c = t.getCaret();
 741:                   c.setDot(offs);
 742:                   c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 743:                 }
 744:             }
 745:           catch (BadLocationException ble)
 746:             {
 747:               // Nothing to do here
 748:             }
 749:         }
 750:     }
 751:   }
 752: 
 753:   static class BeginLineAction
 754:       extends TextAction
 755:   {
 756:     BeginLineAction()
 757:     {
 758:       super(beginLineAction);
 759:     }
 760: 
 761:     public void actionPerformed(ActionEvent event)
 762:     {
 763:       JTextComponent t = getTextComponent(event);
 764:       if (t != null)
 765:         {
 766:           try
 767:             {
 768:               int offs = Utilities.getRowStart(t, t.getCaretPosition());
 769:               if (offs > -1)
 770:                 {
 771:                   Caret c = t.getCaret();
 772:                   c.setDot(offs);
 773:                   c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 774:                 }
 775:             }
 776:           catch (BadLocationException ble)
 777:             {
 778:               // Do nothing here.
 779:             }
 780:         }
 781:     }
 782:   }
 783: 
 784:   static class BeginAction extends TextAction
 785:   {
 786: 
 787:     BeginAction()
 788:     {
 789:       super(beginAction);
 790:     }
 791: 
 792:     public void actionPerformed(ActionEvent event)
 793:     {
 794:       JTextComponent t = getTextComponent(event);
 795:       if (t != null)
 796:         {
 797:           Caret c = t.getCaret();
 798:           c.setDot(0);
 799:           try
 800:             {
 801:               c.setMagicCaretPosition(t.modelToView(0).getLocation());
 802:             }
 803:           catch(BadLocationException ble)
 804:             {
 805:               // Can't happen.
 806:             }
 807:         }
 808:     }
 809:   }
 810: 
 811:   static class EndAction extends TextAction
 812:   {
 813: 
 814:     EndAction()
 815:     {
 816:       super(endAction);
 817:     }
 818: 
 819:     public void actionPerformed(ActionEvent event)
 820:     {
 821:       JTextComponent t = getTextComponent(event);
 822:       if (t != null)
 823:         {
 824:           int offs = t.getDocument().getLength();
 825:           Caret c = t.getCaret();
 826:           c.setDot(offs);
 827:           try
 828:             {
 829:               c.setMagicCaretPosition(t.modelToView(offs).getLocation());
 830:             }
 831:           catch(BadLocationException ble)
 832:             {
 833:               // Can't happen.
 834:             }
 835:         }
 836:     }
 837:   }
 838: 
 839:   /**
 840:    * Creates a beep on the PC speaker.
 841:    *
 842:    * @see Toolkit#beep()
 843:    */
 844:   public static class BeepAction extends TextAction
 845:   {
 846:     /**
 847:      * Creates a new <code>BeepAction</code>.
 848:      */
 849:     public BeepAction()
 850:     {
 851:       super(beepAction);
 852:     }
 853: 
 854:     /**
 855:      * Performs the <code>Action</code>.
 856:      *
 857:      * @param event the action event describing the user action
 858:      */
 859:     public void actionPerformed(ActionEvent event)
 860:     {
 861:       Toolkit.getDefaultToolkit().beep();
 862:     }
 863:   }
 864: 
 865:   /**
 866:    * Copies the selected content into the system clipboard.
 867:    *
 868:    * @see Toolkit#getSystemClipboard()
 869:    * @see CutAction
 870:    * @see PasteAction
 871:    */
 872:   public static class CopyAction extends TextAction
 873:   {
 874: 
 875:     /**
 876:      * Create a new <code>CopyAction</code>.
 877:      */
 878:     public CopyAction()
 879:     {
 880:       super(copyAction);
 881:     }
 882: 
 883:     /**
 884:      * Performs the <code>Action</code>.
 885:      *
 886:      * @param event the action event describing the user action
 887:      */
 888:     public void actionPerformed(ActionEvent event)
 889:     {
 890:       JTextComponent target = getTextComponent(event);
 891:       if (target != null)
 892:         target.copy();
 893:     }
 894:   }
 895: 
 896: 
 897:   /**
 898:    * Copies the selected content into the system clipboard and deletes the
 899:    * selection.
 900:    *
 901:    * @see Toolkit#getSystemClipboard()
 902:    * @see CopyAction
 903:    * @see PasteAction
 904:    */
 905:   public static class CutAction extends TextAction
 906:   {
 907: 
 908:     /**
 909:      * Create a new <code>CutAction</code>.
 910:      */
 911:     public CutAction()
 912:     {
 913:       super(cutAction);
 914:     }
 915: 
 916:     /**
 917:      * Performs the <code>Action</code>.
 918:      *
 919:      * @param event the action event describing the user action
 920:      */
 921:     public void actionPerformed(ActionEvent event)
 922:     {
 923:       JTextComponent target = getTextComponent(event);
 924:       if (target != null)
 925:         target.cut();
 926:     }
 927:   }
 928: 
 929:   /**
 930:    * Copies content from the system clipboard into the editor.
 931:    *
 932:    * @see Toolkit#getSystemClipboard()
 933:    * @see CopyAction
 934:    * @see CutAction
 935:    */
 936:   public static class PasteAction extends TextAction
 937:   {
 938: 
 939:     /**
 940:      * Create a new <code>PasteAction</code>.
 941:      */
 942:     public PasteAction()
 943:     {
 944:       super(pasteAction);
 945:     }
 946: 
 947:     /**
 948:      * Performs the <code>Action</code>.
 949:      *
 950:      * @param event the action event describing the user action
 951:      */
 952:     public void actionPerformed(ActionEvent event)
 953:     {
 954:       JTextComponent target = getTextComponent(event);
 955:       if (target != null)
 956:         target.paste();
 957:     }
 958:   }
 959: 
 960:   /**
 961:    * This action is executed as default action when a KEY_TYPED
 962:    * event is received and no keymap entry exists for that. The purpose
 963:    * of this action is to filter out a couple of characters. This includes
 964:    * the control characters and characters with the ALT-modifier.
 965:    *
 966:    * If an event does not get filtered, it is inserted into the document
 967:    * of the text component. If there is some text selected in the text
 968:    * component, this text will be replaced.
 969:    */
 970:   public static class DefaultKeyTypedAction
 971:     extends TextAction
 972:   {
 973: 
 974:     /**
 975:      * Creates a new <code>DefaultKeyTypedAction</code>.
 976:      */
 977:     public DefaultKeyTypedAction()
 978:     {
 979:       super(defaultKeyTypedAction);
 980:     }
 981: 
 982:     /**
 983:      * Performs the <code>Action</code>.
 984:      *
 985:      * @param event the action event describing the user action
 986:      */
 987:     public void actionPerformed(ActionEvent event)
 988:     {
 989:       // first we filter the following events:
 990:       // - control characters
 991:       // - key events with the ALT modifier
 992:       JTextComponent target = getTextComponent(event);
 993:       if ((target != null) && (event != null))
 994:         {
 995:           if ((target.isEditable()) && (target.isEnabled()))
 996:             {
 997:               String content = event.getActionCommand();
 998:               int mod = event.getModifiers();
 999:               if ((content != null) && (content.length() > 0)
1000:                   && (mod & ActionEvent.ALT_MASK) == 0
1001:                   && (mod & ActionEvent.CTRL_MASK) == 0)
1002:                 {
1003:                   char c = content.charAt(0);
1004:                   if ((c >= 0x20) && (c != 0x7F))
1005:                     {
1006:                       target.replaceSelection(content);
1007:                     }
1008:                 }
1009:             }
1010:         }
1011:     }
1012:   }
1013: 
1014:   /**
1015:    * This action inserts a newline character into the document
1016:    * of the text component. This is typically triggered by hitting
1017:    * ENTER on the keyboard.
1018:    */
1019:   public static class InsertBreakAction extends TextAction
1020:   {
1021: 
1022:     /**
1023:      * Creates a new <code>InsertBreakAction</code>.
1024:      */
1025:     public InsertBreakAction()
1026:     {
1027:       super(insertBreakAction);
1028:     }
1029: 
1030:     /**
1031:      * Performs the <code>Action</code>.
1032:      *
1033:      * @param event the action event describing the user action
1034:      */
1035:     public void actionPerformed(ActionEvent event)
1036:     {
1037:       JTextComponent t = getTextComponent(event);
1038:       if (t != null)
1039:         t.replaceSelection("\n");
1040:     }
1041:   }
1042: 
1043:   /**
1044:    * Places content into the associated editor. If there currently is a
1045:    * selection, this selection is replaced.
1046:    */
1047:   // FIXME: Figure out what this Action is supposed to do. Obviously text
1048:   // that is entered by the user is inserted through DefaultKeyTypedAction.
1049:   public static class InsertContentAction extends TextAction
1050:   {
1051: 
1052:     /**
1053:      * Creates a new <code>InsertContentAction</code>.
1054:      */
1055:     public InsertContentAction()
1056:     {
1057:       super(insertContentAction);
1058:     }
1059: 
1060:     /**
1061:      * Performs the <code>Action</code>.
1062:      *
1063:      * @param event the action event describing the user action
1064:      */
1065:     public void actionPerformed(ActionEvent event)
1066:     {
1067:       // FIXME: Figure out what this Action is supposed to do. Obviously text
1068:       // that is entered by the user is inserted through DefaultKeyTypedAction.
1069:     }
1070:   }
1071: 
1072:   /**
1073:    * Inserts a TAB character into the text editor.
1074:    */
1075:   public static class InsertTabAction extends TextAction
1076:   {
1077: 
1078:     /**
1079:      * Creates a new <code>TabAction</code>.
1080:      */
1081:     public InsertTabAction()
1082:     {
1083:       super(insertTabAction);
1084:     }
1085: 
1086:     /**
1087:      * Performs the <code>Action</code>.
1088:      *
1089:      * @param event the action event describing the user action
1090:      */
1091:     public void actionPerformed(ActionEvent event)
1092:     {
1093:       JTextComponent t = getTextComponent(event);
1094:       if (t != null)
1095:         t.replaceSelection("\t");
1096:     }
1097:   }
1098: 
1099:   /**
1100:    * The serial version of DefaultEditorKit.
1101:    */
1102:   private static final long serialVersionUID = 9017245433028523428L;
1103: 
1104:   /**
1105:    * The name of the <code>Action</code> that moves the caret one character
1106:    * backwards.
1107:    *
1108:    * @see #getActions()
1109:    */
1110:   public static final String backwardAction = "caret-backward";
1111: 
1112:   /**
1113:    * The name of the <code>Action</code> that creates a beep in the speaker.
1114:    *
1115:    * @see #getActions()
1116:    */
1117:   public static final String beepAction = "beep";
1118: 
1119:   /**
1120:    * The name of the <code>Action</code> that moves the caret to the beginning
1121:    * of the <code>Document</code>.
1122:    *
1123:    * @see #getActions()
1124:    */
1125:   public static final String beginAction = "caret-begin";
1126: 
1127:   /**
1128:    * The name of the <code>Action</code> that moves the caret to the beginning
1129:    * of the current line.
1130:    *
1131:    * @see #getActions()
1132:    */
1133:   public static final String beginLineAction = "caret-begin-line";
1134: 
1135:   /**
1136:    * The name of the <code>Action</code> that moves the caret to the beginning
1137:    * of the current paragraph.
1138:    *
1139:    * @see #getActions()
1140:    */
1141:   public static final String beginParagraphAction = "caret-begin-paragraph";
1142: 
1143:   /**
1144:    * The name of the <code>Action</code> that moves the caret to the beginning
1145:    * of the current word.
1146:    *
1147:    * @see #getActions()
1148:    */
1149:   public static final String beginWordAction = "caret-begin-word";
1150: 
1151:   /**
1152:    * The name of the <code>Action</code> that copies the selected content
1153:    * into the system clipboard.
1154:    *
1155:    * @see #getActions()
1156:    */
1157:   public static final String copyAction = "copy-to-clipboard";
1158: 
1159:   /**
1160:    * The name of the <code>Action</code> that copies the selected content
1161:    * into the system clipboard and removes the selection.
1162:    *
1163:    * @see #getActions()
1164:    */
1165:   public static final String cutAction = "cut-to-clipboard";
1166: 
1167:   /**
1168:    * The name of the <code>Action</code> that is performed by default if
1169:    * a key is typed and there is no keymap entry.
1170:    *
1171:    * @see #getActions()
1172:    */
1173:   public static final String defaultKeyTypedAction = "default-typed";
1174: 
1175:   /**
1176:    * The name of the <code>Action</code> that deletes the character that
1177:    * follows the current caret position.
1178:    *
1179:    * @see #getActions()
1180:    */
1181:   public static final String deleteNextCharAction = "delete-next";
1182: 
1183:   /**
1184:    * The name of the <code>Action</code> that deletes the character that
1185:    * precedes the current caret position.
1186:    *
1187:    * @see #getActions()
1188:    */
1189:   public static final String deletePrevCharAction = "delete-previous";
1190: 
1191:   /**
1192:    * The name of the <code>Action</code> that moves the caret one line down.
1193:    *
1194:    * @see #getActions()
1195:    */
1196:   public static final String downAction = "caret-down";
1197: 
1198:   /**
1199:    * The name of the <code>Action</code> that moves the caret to the end
1200:    * of the <code>Document</code>.
1201:    *
1202:    * @see #getActions()
1203:    */
1204:   public static final String endAction = "caret-end";
1205: 
1206:   /**
1207:    * The name of the <code>Action</code> that moves the caret to the end
1208:    * of the current line.
1209:    *
1210:    * @see #getActions()
1211:    */
1212:   public static final String endLineAction = "caret-end-line";
1213: 
1214:   /**
1215:    * When a document is read and an CRLF is encountered, then we add a property
1216:    * with this name and a value of &quot;\r\n&quot;.
1217:    */
1218:   public static final String EndOfLineStringProperty = "__EndOfLine__";
1219: 
1220:   /**
1221:    * The name of the <code>Action</code> that moves the caret to the end
1222:    * of the current paragraph.
1223:    *
1224:    * @see #getActions()
1225:    */
1226:   public static final String endParagraphAction = "caret-end-paragraph";
1227: 
1228:   /**
1229:    * The name of the <code>Action</code> that moves the caret to the end
1230:    * of the current word.
1231:    *
1232:    * @see #getActions()
1233:    */
1234:   public static final String endWordAction = "caret-end-word";
1235: 
1236:   /**
1237:    * The name of the <code>Action</code> that moves the caret one character
1238:    * forward.
1239:    *
1240:    * @see #getActions()
1241:    */
1242:   public static final String forwardAction = "caret-forward";
1243: 
1244:   /**
1245:    * The name of the <code>Action</code> that inserts a line break.
1246:    *
1247:    * @see #getActions()
1248:    */
1249:   public static final String insertBreakAction = "insert-break";
1250: 
1251:   /**
1252:    * The name of the <code>Action</code> that inserts some content.
1253:    *
1254:    * @see #getActions()
1255:    */
1256:   public static final String insertContentAction = "insert-content";
1257: 
1258:   /**
1259:    * The name of the <code>Action</code> that inserts a TAB.
1260:    *
1261:    * @see #getActions()
1262:    */
1263:   public static final String insertTabAction = "insert-tab";
1264: 
1265:   /**
1266:    * The name of the <code>Action</code> that moves the caret to the beginning
1267:    * of the next word.
1268:    *
1269:    * @see #getActions()
1270:    */
1271:   public static final String nextWordAction = "caret-next-word";
1272: 
1273:   /**
1274:    * The name of the <code>Action</code> that moves the caret one page down.
1275:    *
1276:    * @see #getActions()
1277:    */
1278:   public static final String pageDownAction = "page-down";
1279: 
1280:   /**
1281:    * The name of the <code>Action</code> that moves the caret one page up.
1282:    *
1283:    * @see #getActions()
1284:    */
1285:   public static final String pageUpAction = "page-up";
1286: 
1287:   /**
1288:    * The name of the <code>Action</code> that copies content from the system
1289:    * clipboard into the document.
1290:    *
1291:    * @see #getActions()
1292:    */
1293:   public static final String pasteAction = "paste-from-clipboard";
1294: 
1295:   /**
1296:    * The name of the <code>Action</code> that moves the caret to the beginning
1297:    * of the previous word.
1298:    *
1299:    * @see #getActions()
1300:    */
1301:   public static final String previousWordAction = "caret-previous-word";
1302: 
1303:   /**
1304:    * The name of the <code>Action</code> that sets the editor in read only
1305:    * mode.
1306:    *
1307:    * @see #getActions()
1308:    */
1309:   public static final String readOnlyAction = "set-read-only";
1310: 
1311:   /**
1312:    * The name of the <code>Action</code> that selects the whole document.
1313:    *
1314:    * @see #getActions()
1315:    */
1316:   public static final String selectAllAction = "select-all";
1317: 
1318:   /**
1319:    * The name of the <code>Action</code> that moves the caret one character
1320:    * backwards, possibly extending the current selection.
1321:    *
1322:    * @see #getActions()
1323:    */
1324:   public static final String selectionBackwardAction = "selection-backward";
1325: 
1326:   /**
1327:    * The name of the <code>Action</code> that moves the caret to the beginning
1328:    * of the document, possibly extending the current selection.
1329:    *
1330:    * @see #getActions()
1331:    */
1332:   public static final String selectionBeginAction = "selection-begin";
1333: 
1334:   /**
1335:    * The name of the <code>Action</code> that moves the caret to the beginning
1336:    * of the current line, possibly extending the current selection.
1337:    *
1338:    * @see #getActions()
1339:    */
1340:   public static final String selectionBeginLineAction = "selection-begin-line";
1341: 
1342:   /**
1343:    * The name of the <code>Action</code> that moves the caret to the beginning
1344:    * of the current paragraph, possibly extending the current selection.
1345:    *
1346:    * @see #getActions()
1347:    */
1348:   public static final String selectionBeginParagraphAction =
1349:     "selection-begin-paragraph";
1350: 
1351:   /**
1352:    * The name of the <code>Action</code> that moves the caret to the beginning
1353:    * of the current word, possibly extending the current selection.
1354:    *
1355:    * @see #getActions()
1356:    */
1357:   public static final String selectionBeginWordAction = "selection-begin-word";
1358: 
1359:   /**
1360:    * The name of the <code>Action</code> that moves the caret one line down,
1361:    * possibly extending the current selection.
1362:    *
1363:    * @see #getActions()
1364:    */
1365:   public static final String selectionDownAction = "selection-down";
1366: 
1367:   /**
1368:    * The name of the <code>Action</code> that moves the caret to the end
1369:    * of the document, possibly extending the current selection.
1370:    *
1371:    * @see #getActions()
1372:    */
1373:   public static final String selectionEndAction = "selection-end";
1374: 
1375:   /**
1376:    * The name of the <code>Action</code> that moves the caret to the end
1377:    * of the current line, possibly extending the current selection.
1378:    *
1379:    * @see #getActions()
1380:    */
1381:   public static final String selectionEndLineAction = "selection-end-line";
1382: 
1383:   /**
1384:    * The name of the <code>Action</code> that moves the caret to the end
1385:    * of the current paragraph, possibly extending the current selection.
1386:    *
1387:    * @see #getActions()
1388:    */
1389:   public static final String selectionEndParagraphAction =
1390:     "selection-end-paragraph";
1391: 
1392:   /**
1393:    * The name of the <code>Action</code> that moves the caret to the end
1394:    * of the current word, possibly extending the current selection.
1395:    *
1396:    * @see #getActions()
1397:    */
1398:   public static final String selectionEndWordAction = "selection-end-word";
1399: 
1400:   /**
1401:    * The name of the <code>Action</code> that moves the caret one character
1402:    * forwards, possibly extending the current selection.
1403:    *
1404:    * @see #getActions()
1405:    */
1406:   public static final String selectionForwardAction = "selection-forward";
1407: 
1408:   /**
1409:    * The name of the <code>Action</code> that moves the caret to the beginning
1410:    * of the next word, possibly extending the current selection.
1411:    *
1412:    * @see #getActions()
1413:    */
1414:   public static final String selectionNextWordAction = "selection-next-word";
1415: 
1416:   /**
1417:    * The name of the <code>Action</code> that moves the caret to the beginning
1418:    * of the previous word, possibly extending the current selection.
1419:    *
1420:    * @see #getActions()
1421:    */
1422:   public static final String selectionPreviousWordAction =
1423:     "selection-previous-word";
1424: 
1425:   /**
1426:    * The name of the <code>Action</code> that moves the caret one line up,
1427:    * possibly extending the current selection.
1428:    *
1429:    * @see #getActions()
1430:    */
1431:   public static final String selectionUpAction = "selection-up";
1432: 
1433:   /**
1434:    * The name of the <code>Action</code> that selects the line around the
1435:    * caret.
1436:    *
1437:    * @see #getActions()
1438:    */
1439:   public static final String selectLineAction = "select-line";
1440: 
1441:   /**
1442:    * The name of the <code>Action</code> that selects the paragraph around the
1443:    * caret.
1444:    *
1445:    * @see #getActions()
1446:    */
1447:   public static final String selectParagraphAction = "select-paragraph";
1448: 
1449:   /**
1450:    * The name of the <code>Action</code> that selects the word around the
1451:    * caret.
1452:    *
1453:    * @see #getActions()
1454:    */
1455:   public static final String selectWordAction = "select-word";
1456: 
1457:   /**
1458:    * The name of the <code>Action</code> that moves the caret one line up.
1459:    *
1460:    * @see #getActions()
1461:    */
1462:   public static final String upAction = "caret-up";
1463: 
1464:   /**
1465:    * The name of the <code>Action</code> that sets the editor in read-write
1466:    * mode.
1467:    *
1468:    * @see #getActions()
1469:    */
1470:   public static final String writableAction = "set-writable";
1471: 
1472:   /**
1473:    * Creates a new <code>DefaultEditorKit</code>.
1474:    */
1475:   public DefaultEditorKit()
1476:   {
1477:     // Nothing to do here.
1478:   }
1479: 
1480:   /**
1481:    * The <code>Action</code>s that are supported by the
1482:    * <code>DefaultEditorKit</code>.
1483:    */
1484:   private static Action[] defaultActions =
1485:   new Action[] {
1486:     // These classes are public because they are so in the RI.
1487:     new BeepAction(),
1488:     new CopyAction(),
1489:     new CutAction(),
1490:     new DefaultKeyTypedAction(),
1491:     new InsertBreakAction(),
1492:     new InsertContentAction(),
1493:     new InsertTabAction(),
1494:     new PasteAction(),
1495: 
1496:     // These are (package-)private inner classes.
1497:     new DeleteNextCharAction(),
1498:     new DeletePrevCharAction(),
1499: 
1500:     new BeginLineAction(),
1501:     new SelectionBeginLineAction(),
1502: 
1503:     new EndLineAction(),
1504:     new SelectionEndLineAction(),
1505: 
1506:     new BackwardAction(),
1507:     new SelectionBackwardAction(),
1508: 
1509:     new ForwardAction(),
1510:     new SelectionForwardAction(),
1511: 
1512:     new UpAction(),
1513:     new SelectionUpAction(),
1514: 
1515:     new DownAction(),
1516:     new SelectionDownAction(),
1517: 
1518:     new NextWordAction(),
1519:     new SelectionNextWordAction(),
1520: 
1521:     new PreviousWordAction(),
1522:     new SelectionPreviousWordAction(),
1523: 
1524:     new BeginAction(),
1525:     new SelectionBeginAction(),
1526: 
1527:     new EndAction(),
1528:     new SelectionEndAction(),
1529: 
1530:     new BeginWordAction(),
1531:     new SelectionBeginWordAction(),
1532: 
1533:     new EndWordAction(),
1534:     new SelectionEndWordAction(),
1535: 
1536:     new SelectAllAction(),
1537:     new SelectLineAction(),
1538:     new SelectWordAction()
1539:   };
1540: 
1541:   /**
1542:    * Creates the <code>Caret</code> for this <code>EditorKit</code>. This
1543:    * returns a {@link DefaultCaret} in this case.
1544:    *
1545:    * @return the <code>Caret</code> for this <code>EditorKit</code>
1546:    */
1547:   public Caret createCaret()
1548:   {
1549:     return new DefaultCaret();
1550:   }
1551: 
1552:   /**
1553:    * Creates the default {@link Document} that this <code>EditorKit</code>
1554:    * supports. This is a {@link PlainDocument} in this case.
1555:    *
1556:    * @return the default {@link Document} that this <code>EditorKit</code>
1557:    *         supports
1558:    */
1559:   public Document createDefaultDocument()
1560:   {
1561:     return new PlainDocument();
1562:   }
1563: 
1564:   /**
1565:    * Returns the <code>Action</code>s supported by this <code>EditorKit</code>.
1566:    *
1567:    * @return the <code>Action</code>s supported by this <code>EditorKit</code>
1568:    */
1569:   public Action[] getActions()
1570:   {
1571:     return defaultActions;
1572:   }
1573: 
1574:   /**
1575:    * Returns the content type that this <code>EditorKit</code> supports.
1576:    * The <code>DefaultEditorKit</code> supports the content type
1577:    * <code>text/plain</code>.
1578:    *
1579:    * @return the content type that this <code>EditorKit</code> supports
1580:    */
1581:   public String getContentType()
1582:   {
1583:     return "text/plain";
1584:   }
1585: 
1586:   /**
1587:    * Returns a {@link ViewFactory} that is able to create {@link View}s for
1588:    * the <code>Element</code>s that are used in this <code>EditorKit</code>'s
1589:    * model. This returns null which lets the UI of the text component supply
1590:    * <code>View</code>s.
1591:    *
1592:    * @return a {@link ViewFactory} that is able to create {@link View}s for
1593:    *         the <code>Element</code>s that are used in this
1594:    *         <code>EditorKit</code>'s model
1595:    */
1596:   public ViewFactory getViewFactory()
1597:   {
1598:     return null;
1599:   }
1600: 
1601:   /**
1602:    * Reads a document of the supported content type from an {@link InputStream}
1603:    * into the actual {@link Document} object.
1604:    *
1605:    * @param in the stream from which to read the document
1606:    * @param document the document model into which the content is read
1607:    * @param offset the offset inside to document where the content is inserted
1608:    *
1609:    * @throws BadLocationException if <code>offset</code> is an invalid location
1610:    *         inside <code>document</code>
1611:    * @throws IOException if something goes wrong while reading from
1612:    *        <code>in</code>
1613:    */
1614:   public void read(InputStream in, Document document, int offset)
1615:     throws BadLocationException, IOException
1616:   {
1617:     read(new InputStreamReader(in), document, offset);
1618:   }
1619: 
1620:   /**
1621:    * Reads a document of the supported content type from a {@link Reader}
1622:    * into the actual {@link Document} object.
1623:    *
1624:    * @param in the reader from which to read the document
1625:    * @param document the document model into which the content is read
1626:    * @param offset the offset inside to document where the content is inserted
1627:    *
1628:    * @throws BadLocationException if <code>offset</code> is an invalid location
1629:    *         inside <code>document</code>
1630:    * @throws IOException if something goes wrong while reading from
1631:    *        <code>in</code>
1632:    */
1633:   public void read(Reader in, Document document, int offset)
1634:     throws BadLocationException, IOException
1635:   {
1636:     BufferedReader reader = new BufferedReader(in);
1637: 
1638:     String line;
1639:     CPStringBuilder content = new CPStringBuilder();
1640: 
1641:     while ((line = reader.readLine()) != null)
1642:       {
1643:         content.append(line);
1644:         content.append("\n");
1645:       }
1646: 
1647:     document.insertString(offset, content.substring(0, content.length() - 1),
1648:                           SimpleAttributeSet.EMPTY);
1649:   }
1650: 
1651:   /**
1652:    * Writes the <code>Document</code> (or a fragment of the
1653:    * <code>Document</code>) to an {@link OutputStream} in the
1654:    * supported content type format.
1655:    *
1656:    * @param out the stream to write to
1657:    * @param document the document that should be written out
1658:    * @param offset the beginning offset from where to write
1659:    * @param len the length of the fragment to write
1660:    *
1661:    * @throws BadLocationException if <code>offset</code> or
1662:    *         <code>offset + len</code>is an invalid location inside
1663:    *         <code>document</code>
1664:    * @throws IOException if something goes wrong while writing to
1665:    *        <code>out</code>
1666:    */
1667:   public void write(OutputStream out, Document document, int offset, int len)
1668:     throws BadLocationException, IOException
1669:   {
1670:     write(new OutputStreamWriter(out), document, offset, len);
1671:   }
1672: 
1673:   /**
1674:    * Writes the <code>Document</code> (or a fragment of the
1675:    * <code>Document</code>) to a {@link Writer} in the
1676:    * supported content type format.
1677:    *
1678:    * @param out the writer to write to
1679:    * @param document the document that should be written out
1680:    * @param offset the beginning offset from where to write
1681:    * @param len the length of the fragment to write
1682:    *
1683:    * @throws BadLocationException if <code>offset</code> is an
1684:    * invalid location inside <code>document</code>.
1685:    * @throws IOException if something goes wrong while writing to
1686:    *        <code>out</code>
1687:    */
1688:   public void write(Writer out, Document document, int offset, int len)
1689:       throws BadLocationException, IOException
1690:   {
1691:     // Throw a BLE if offset is invalid
1692:     if (offset < 0 || offset > document.getLength())
1693:       throw new BadLocationException("Tried to write to invalid location",
1694:                                      offset);
1695: 
1696:     // If they gave an overly large len, just adjust it
1697:     if (offset + len > document.getLength())
1698:       len = document.getLength() - offset;
1699: 
1700:     out.write(document.getText(offset, len));
1701:   }
1702: }