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