src/share/classes/javax/swing/text/GapContent.java

Print this page


   1 /*
   2  * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  41  * implemented using a gapped buffer similar to that used by emacs.
  42  * The underlying storage is a array of unicode characters with
  43  * a gap somewhere.  The gap is moved to the location of changes
  44  * to take advantage of common behavior where most changes are
  45  * in the same location.  Changes that occur at a gap boundary are
  46  * generally cheap and moving the gap is generally cheaper than
  47  * moving the array contents directly to accommodate the change.
  48  * <p>
  49  * The positions tracking change are also generally cheap to
  50  * maintain.  The Position implementations (marks) store the array
  51  * index and can easily calculate the sequential position from
  52  * the current gap location.  Changes only require update to the
  53  * the marks between the old and new gap boundaries when the gap
  54  * is moved, so generally updating the marks is pretty cheap.
  55  * The marks are stored sorted so they can be located quickly
  56  * with a binary search.  This increases the cost of adding a
  57  * mark, and decreases the cost of keeping the mark updated.
  58  *
  59  * @author  Timothy Prinzing
  60  */

  61 public class GapContent extends GapVector implements AbstractDocument.Content, Serializable {
  62 
  63     /**
  64      * Creates a new GapContent object.  Initial size defaults to 10.
  65      */
  66     public GapContent() {
  67         this(10);
  68     }
  69 
  70     /**
  71      * Creates a new GapContent object, with the initial
  72      * size specified.  The initial size will not be allowed
  73      * to go below 2, to give room for the implied break and
  74      * the gap.
  75      *
  76      * @param initialLength the initial size
  77      */
  78     public GapContent(int initialLength) {
  79         super(Math.max(initialLength,2));
  80         char[] implied = new char[1];


 560         return (cmp < 0) ? mid : mid + 1;
 561     }
 562 
 563     /**
 564      * Remove all unused marks out of the sorted collection
 565      * of marks.
 566      */
 567     final void removeUnusedMarks() {
 568         int n = marks.size();
 569         MarkVector cleaned = new MarkVector(n);
 570         for (int i = 0; i < n; i++) {
 571             MarkData mark = marks.elementAt(i);
 572             if (mark.get() != null) {
 573                 cleaned.addElement(mark);
 574             }
 575         }
 576         marks = cleaned;
 577         unusedMarks = 0;
 578     }
 579 
 580 
 581     static class MarkVector extends GapVector {
 582 
 583         MarkVector() {
 584             super();
 585         }
 586 
 587         MarkVector(int size) {
 588             super(size);
 589         }
 590 
 591         /**
 592          * Allocate an array to store items of the type
 593          * appropriate (which is determined by the subclass).
 594          */
 595         protected Object allocateArray(int len) {
 596             return new MarkData[len];
 597         }
 598 
 599         /**
 600          * Get the length of the allocated array


 838          */
 839         protected void resetLocation(int endOffset, int g1) {
 840             if (undoLocation != endOffset) {
 841                 this.rec.index = undoLocation;
 842             }
 843             else {
 844                 this.rec.index = g1;
 845             }
 846         }
 847 
 848         /** Previous Offset of rec. */
 849         protected int undoLocation;
 850         /** Mark to reset offset. */
 851         protected MarkData rec;
 852     } // End of GapContent.UndoPosRef
 853 
 854 
 855     /**
 856      * UnoableEdit created for inserts.
 857      */

 858     class InsertUndo extends AbstractUndoableEdit {
 859         protected InsertUndo(int offset, int length) {
 860             super();
 861             this.offset = offset;
 862             this.length = length;
 863         }
 864 
 865         public void undo() throws CannotUndoException {
 866             super.undo();
 867             try {
 868                 // Get the Positions in the range being removed.
 869                 posRefs = getPositionsInRange(null, offset, length);
 870                 string = getString(offset, length);
 871                 remove(offset, length);
 872             } catch (BadLocationException bl) {
 873               throw new CannotUndoException();
 874             }
 875         }
 876 
 877         public void redo() throws CannotRedoException {


 888                 throw new CannotRedoException();
 889             }
 890         }
 891 
 892         /** Where string was inserted. */
 893         protected int offset;
 894         /** Length of string inserted. */
 895         protected int length;
 896         /** The string that was inserted. This will only be valid after an
 897          * undo. */
 898         protected String string;
 899         /** An array of instances of UndoPosRef for the Positions in the
 900          * range that was removed, valid after undo. */
 901         protected Vector posRefs;
 902     } // GapContent.InsertUndo
 903 
 904 
 905     /**
 906      * UndoableEdit created for removes.
 907      */

 908     class RemoveUndo extends AbstractUndoableEdit {
 909         protected RemoveUndo(int offset, String string) {
 910             super();
 911             this.offset = offset;
 912             this.string = string;
 913             this.length = string.length();
 914             posRefs = getPositionsInRange(null, offset, length);
 915         }
 916 
 917         public void undo() throws CannotUndoException {
 918             super.undo();
 919             try {
 920                 insertString(offset, string);
 921                 // Update the Positions that were in the range removed.
 922                 if(posRefs != null) {
 923                     updateUndoPositions(posRefs, offset, length);
 924                     posRefs = null;
 925                 }
 926                 string = null;
 927             } catch (BadLocationException bl) {


   1 /*
   2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  41  * implemented using a gapped buffer similar to that used by emacs.
  42  * The underlying storage is a array of unicode characters with
  43  * a gap somewhere.  The gap is moved to the location of changes
  44  * to take advantage of common behavior where most changes are
  45  * in the same location.  Changes that occur at a gap boundary are
  46  * generally cheap and moving the gap is generally cheaper than
  47  * moving the array contents directly to accommodate the change.
  48  * <p>
  49  * The positions tracking change are also generally cheap to
  50  * maintain.  The Position implementations (marks) store the array
  51  * index and can easily calculate the sequential position from
  52  * the current gap location.  Changes only require update to the
  53  * the marks between the old and new gap boundaries when the gap
  54  * is moved, so generally updating the marks is pretty cheap.
  55  * The marks are stored sorted so they can be located quickly
  56  * with a binary search.  This increases the cost of adding a
  57  * mark, and decreases the cost of keeping the mark updated.
  58  *
  59  * @author  Timothy Prinzing
  60  */
  61 @SuppressWarnings("serial") // Superclass is not serializable across versions
  62 public class GapContent extends GapVector implements AbstractDocument.Content, Serializable {
  63 
  64     /**
  65      * Creates a new GapContent object.  Initial size defaults to 10.
  66      */
  67     public GapContent() {
  68         this(10);
  69     }
  70 
  71     /**
  72      * Creates a new GapContent object, with the initial
  73      * size specified.  The initial size will not be allowed
  74      * to go below 2, to give room for the implied break and
  75      * the gap.
  76      *
  77      * @param initialLength the initial size
  78      */
  79     public GapContent(int initialLength) {
  80         super(Math.max(initialLength,2));
  81         char[] implied = new char[1];


 561         return (cmp < 0) ? mid : mid + 1;
 562     }
 563 
 564     /**
 565      * Remove all unused marks out of the sorted collection
 566      * of marks.
 567      */
 568     final void removeUnusedMarks() {
 569         int n = marks.size();
 570         MarkVector cleaned = new MarkVector(n);
 571         for (int i = 0; i < n; i++) {
 572             MarkData mark = marks.elementAt(i);
 573             if (mark.get() != null) {
 574                 cleaned.addElement(mark);
 575             }
 576         }
 577         marks = cleaned;
 578         unusedMarks = 0;
 579     }
 580 
 581     @SuppressWarnings("serial") // Superclass is not serializable across versions
 582     static class MarkVector extends GapVector {
 583 
 584         MarkVector() {
 585             super();
 586         }
 587 
 588         MarkVector(int size) {
 589             super(size);
 590         }
 591 
 592         /**
 593          * Allocate an array to store items of the type
 594          * appropriate (which is determined by the subclass).
 595          */
 596         protected Object allocateArray(int len) {
 597             return new MarkData[len];
 598         }
 599 
 600         /**
 601          * Get the length of the allocated array


 839          */
 840         protected void resetLocation(int endOffset, int g1) {
 841             if (undoLocation != endOffset) {
 842                 this.rec.index = undoLocation;
 843             }
 844             else {
 845                 this.rec.index = g1;
 846             }
 847         }
 848 
 849         /** Previous Offset of rec. */
 850         protected int undoLocation;
 851         /** Mark to reset offset. */
 852         protected MarkData rec;
 853     } // End of GapContent.UndoPosRef
 854 
 855 
 856     /**
 857      * UnoableEdit created for inserts.
 858      */
 859     @SuppressWarnings("serial") // Superclass is a JDK-implementation class
 860     class InsertUndo extends AbstractUndoableEdit {
 861         protected InsertUndo(int offset, int length) {
 862             super();
 863             this.offset = offset;
 864             this.length = length;
 865         }
 866 
 867         public void undo() throws CannotUndoException {
 868             super.undo();
 869             try {
 870                 // Get the Positions in the range being removed.
 871                 posRefs = getPositionsInRange(null, offset, length);
 872                 string = getString(offset, length);
 873                 remove(offset, length);
 874             } catch (BadLocationException bl) {
 875               throw new CannotUndoException();
 876             }
 877         }
 878 
 879         public void redo() throws CannotRedoException {


 890                 throw new CannotRedoException();
 891             }
 892         }
 893 
 894         /** Where string was inserted. */
 895         protected int offset;
 896         /** Length of string inserted. */
 897         protected int length;
 898         /** The string that was inserted. This will only be valid after an
 899          * undo. */
 900         protected String string;
 901         /** An array of instances of UndoPosRef for the Positions in the
 902          * range that was removed, valid after undo. */
 903         protected Vector posRefs;
 904     } // GapContent.InsertUndo
 905 
 906 
 907     /**
 908      * UndoableEdit created for removes.
 909      */
 910     @SuppressWarnings("serial") // JDK-implementation class
 911     class RemoveUndo extends AbstractUndoableEdit {
 912         protected RemoveUndo(int offset, String string) {
 913             super();
 914             this.offset = offset;
 915             this.string = string;
 916             this.length = string.length();
 917             posRefs = getPositionsInRange(null, offset, length);
 918         }
 919 
 920         public void undo() throws CannotUndoException {
 921             super.undo();
 922             try {
 923                 insertString(offset, string);
 924                 // Update the Positions that were in the range removed.
 925                 if(posRefs != null) {
 926                     updateUndoPositions(posRefs, offset, length);
 927                     posRefs = null;
 928                 }
 929                 string = null;
 930             } catch (BadLocationException bl) {