public LeafElement(Element parent, AttributeSet a, int offs0, int offs1) { super(parent, a); try { p0 = createPosition(offs0); p1 = createPosition(offs1); } catch (BadLocationException e) { p0 = null; p1 = null; throw new StateInvariantError("Can't create Position references"); } } /** * Converts the element to a string. * * @return the string */ public String toString() { return "LeafElement(" + getName() + ") " + p0 + "," + p1 + "\n"; } // --- Element methods --------------------------------------------- /** * Gets the starting offset in the model for the element. * * @return the offset >= 0 */ public int getStartOffset() { return p0.getOffset(); } /** * Gets the ending offset in the model for the element. * * @return the offset >= 0 */ public int getEndOffset() { return p1.getOffset(); } /** * Gets the element name. * * @return the name */ public String getName() { String nm = super.getName(); if (nm == null) { nm = ContentElementName; } return nm; } /** * Gets the child element index closest to the given model offset. * * @param pos the offset >= 0 * @return the element index >= 0 */ public int getElementIndex(int pos) { return -1; } /** * Gets a child element. * * @param index the child index, >= 0 && < getElementCount() * @return the child element */ public Element getElement(int index) { return null; } /** * Returns the number of child elements. * * @return the number of children >= 0 */ public int getElementCount() { return 0; } /** * Checks whether the element is a leaf. * * @return true if a leaf */ public boolean isLeaf() { return true; } // ------ TreeNode ---------------------------------------------- /** * Returns true if the receiver allows children. * @return true if the receiver allows children, otherwise false */ public boolean getAllowsChildren() { return false; } /** * Returns the children of the receiver as an * <code>Enumeration</code>. * @return the children of the receiver */ public Enumeration children() { return null; } // --- serialization --------------------------------------------- private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeInt(p0.getOffset()); s.writeInt(p1.getOffset()); } private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { s.defaultReadObject(); // set the range with positions that track change int off0 = s.readInt(); int off1 = s.readInt(); try { p0 = createPosition(off0); p1 = createPosition(off1); } catch (BadLocationException e) { p0 = null; p1 = null; throw new IOException("Can't restore Position references"); } } // ---- members ----------------------------------------------------- private transient Position p0; private transient Position p1; } /** * Represents the root element of the bidirectional element structure. * The root element is the only element in the bidi element structure * which contains children. */ class BidiRootElement extends BranchElement { BidiRootElement() { super( null, null ); } /** * Gets the name of the element. * @return the name */ public String getName() { return "bidi root"; } } /** * Represents an element of the bidirectional element structure. */ class BidiElement extends LeafElement { /** * Creates a new BidiElement. */ BidiElement(Element parent, int start, int end, int level) { super(parent, new SimpleAttributeSet(), start, end); addAttribute(StyleConstants.BidiLevel, Integer.valueOf(level)); //System.out.println("BidiElement: start = " + start // + " end = " + end + " level = " + level ); } /** * Gets the name of the element. * @return the name */ public String getName() { return BidiElementName; } int getLevel() { Integer o = (Integer) getAttribute(StyleConstants.BidiLevel); if (o != null) { return o.intValue(); } return 0; // Level 0 is base level (non-embedded) left-to-right } boolean isLeftToRight() { return ((getLevel() % 2) == 0); } } /** * Stores document changes as the document is being * modified. Can subsequently be used for change notification * when done with the document modification transaction. * This is used by the AbstractDocument class and its extensions * for broadcasting change information to the document listeners. */ public class DefaultDocumentEvent extends CompoundEdit implements DocumentEvent { /** * Constructs a change record. * * @param offs the offset into the document of the change >= 0 * @param len the length of the change >= 0 * @param type the type of event (DocumentEvent.EventType) * @since 1.4 */ public DefaultDocumentEvent(int offs, int len, DocumentEvent.EventType type) { super(); offset = offs; length = len; this.type = type; } /** * Returns a string description of the change event. * * @return a string */ public String toString() { return edits.toString(); } // --- CompoundEdit methods -------------------------- /** * Adds a document edit. If the number of edits crosses * a threshold, this switches on a hashtable lookup for * ElementChange implementations since access of these * needs to be relatively quick. * * @param anEdit a document edit record * @return true if the edit was added */ public boolean addEdit(UndoableEdit anEdit) { // if the number of changes gets too great, start using // a hashtable for to locate the change for a given element. if ((changeLookup == null) && (edits.size() > 10)) { changeLookup = new Hashtable<Element, ElementChange>(); int n = edits.size(); for (int i = 0; i < n; i++) { Object o = edits.elementAt(i); if (o instanceof DocumentEvent.ElementChange) { DocumentEvent.ElementChange ec = (DocumentEvent.ElementChange) o; changeLookup.put(ec.getElement(), ec); } } } // if we have a hashtable... add the entry if it's // an ElementChange. if ((changeLookup != null) && (anEdit instanceof DocumentEvent.ElementChange)) { DocumentEvent.ElementChange ec = (DocumentEvent.ElementChange) anEdit; changeLookup.put(ec.getElement(), ec); } return super.addEdit(anEdit); } /** * Redoes a change. * * @exception CannotRedoException if the change cannot be redone */ public void redo() throws CannotRedoException { writeLock(); try { // change the state super.redo(); // fire a DocumentEvent to notify the view(s) UndoRedoDocumentEvent ev = new UndoRedoDocumentEvent(this, false); if (type == DocumentEvent.EventType.INSERT) { fireInsertUpdate(ev); } else if (type == DocumentEvent.EventType.REMOVE) { fireRemoveUpdate(ev); } else { fireChangedUpdate(ev); } } finally { writeUnlock(); } } /** * Undoes a change. * * @exception CannotUndoException if the change cannot be undone */ public void undo() throws CannotUndoException { writeLock(); try { // change the state super.undo(); // fire a DocumentEvent to notify the view(s) UndoRedoDocumentEvent ev = new UndoRedoDocumentEvent(this, true); if (type == DocumentEvent.EventType.REMOVE) { fireInsertUpdate(ev); } else if (type == DocumentEvent.EventType.INSERT) { fireRemoveUpdate(ev); } else { fireChangedUpdate(ev); } } finally { writeUnlock(); } } /** * DefaultDocument events are significant. If you wish to aggregate * DefaultDocumentEvents to present them as a single edit to the user * place them into a CompoundEdit. * * @return whether the event is significant for edit undo purposes */ public boolean isSignificant() { return true; } /** * Provides a localized, human readable description of this edit * suitable for use in, say, a change log. * * @return the description */ public String getPresentationName() { DocumentEvent.EventType type = getType(); if(type == DocumentEvent.EventType.INSERT) return UIManager.getString("AbstractDocument.additionText"); if(type == DocumentEvent.EventType.REMOVE) return UIManager.getString("AbstractDocument.deletionText"); return UIManager.getString("AbstractDocument.styleChangeText"); } /** * Provides a localized, human readable description of the undoable * form of this edit, e.g. for use as an Undo menu item. Typically * derived from getDescription(); * * @return the description */ public String getUndoPresentationName() { return UIManager.getString("AbstractDocument.undoText") + " " + getPresentationName(); } /** * Provides a localized, human readable description of the redoable * form of this edit, e.g. for use as a Redo menu item. Typically * derived from getPresentationName(); * * @return the description */ public String getRedoPresentationName() { return UIManager.getString("AbstractDocument.redoText") + " " + getPresentationName(); } // --- DocumentEvent methods -------------------------- /** * Returns the type of event. * * @return the event type as a DocumentEvent.EventType * @see DocumentEvent#getType */ public DocumentEvent.EventType getType() { return type; } /** * Returns the offset within the document of the start of the change. * * @return the offset >= 0 * @see DocumentEvent#getOffset */ public int getOffset() { return offset; } /** * Returns the length of the change. * * @return the length >= 0 * @see DocumentEvent#getLength */ public int getLength() { return length; } /** * Gets the document that sourced the change event. * * @return the document * @see DocumentEvent#getDocument */ public Document getDocument() { return AbstractDocument.this; } /** * Gets the changes for an element. * * @param elem the element * @return the changes */ public DocumentEvent.ElementChange getChange(Element elem) { if (changeLookup != null) { return changeLookup.get(elem); } int n = edits.size(); for (int i = 0; i < n; i++) { Object o = edits.elementAt(i); if (o instanceof DocumentEvent.ElementChange) { DocumentEvent.ElementChange c = (DocumentEvent.ElementChange) o; if (elem.equals(c.getElement())) { return c; } } } return null; } // --- member variables ------------------------------------ private int offset; private int length; private Hashtable<Element, ElementChange> changeLookup; private DocumentEvent.EventType type; } /** * This event used when firing document changes while Undo/Redo * operations. It just wraps DefaultDocumentEvent and delegates * all calls to it except getType() which depends on operation * (Undo or Redo). */ class UndoRedoDocumentEvent implements DocumentEvent { private DefaultDocumentEvent src = null; private boolean isUndo; private EventType type = null; public UndoRedoDocumentEvent(DefaultDocumentEvent src, boolean isUndo) { this.src = src; this.isUndo = isUndo; if(isUndo) { if(src.getType().equals(EventType.INSERT)) { type = EventType.REMOVE; } else if(src.getType().equals(EventType.REMOVE)) { type = EventType.INSERT; } else { type = src.getType(); } } else { type = src.getType(); } } public DefaultDocumentEvent getSource() { return src; } // DocumentEvent methods delegated to DefaultDocumentEvent source // except getType() which depends on operation (Undo or Redo). public int getOffset() { return src.getOffset(); } public int getLength() { return src.getLength(); } public Document getDocument() { return src.getDocument(); } public DocumentEvent.EventType getType() { return type; } public DocumentEvent.ElementChange getChange(Element elem) { return src.getChange(elem); } } /** * An implementation of ElementChange that can be added to the document * event. */ public static class ElementEdit extends AbstractUndoableEdit implements DocumentEvent.ElementChange {Lines 2501–3000 of 3118. Previous lines Load more
public LeafElement(Element parent, AttributeSet a, int offs0, int offs1) { super(parent, a); try { p0 = createPosition(offs0); p1 = createPosition(offs1); } catch (BadLocationException e) { p0 = null; p1 = null; throw new StateInvariantError("Can't create Position references"); } } /** * Converts the element to a string. * * @return the string */ public String toString() { return "LeafElement(" + getName() + ") " + p0 + "," + p1 + "\n"; } // --- Element methods --------------------------------------------- /** * Gets the starting offset in the model for the element. * * @return the offset >= 0 */ public int getStartOffset() { return p0.getOffset(); } /** * Gets the ending offset in the model for the element. * * @return the offset >= 0 */ public int getEndOffset() { return p1.getOffset(); } /** * Gets the element name. * * @return the name */ public String getName() { String nm = super.getName(); if (nm == null) { nm = ContentElementName; } return nm; } /** * Gets the child element index closest to the given model offset. * * @param pos the offset >= 0 * @return the element index >= 0 */ public int getElementIndex(int pos) { return -1; } /** * Gets a child element. * * @param index the child index, >= 0 && < getElementCount() * @return the child element */ public Element getElement(int index) { return null; } /** * Returns the number of child elements. * * @return the number of children >= 0 */ public int getElementCount() { return 0; } /** * Checks whether the element is a leaf. * * @return true if a leaf */ public boolean isLeaf() { return true; } // ------ TreeNode ---------------------------------------------- /** * Returns true if the receiver allows children. * @return true if the receiver allows children, otherwise false */ public boolean getAllowsChildren() { return false; } /** * Returns the children of the receiver as an * <code>Enumeration</code>. * @return the children of the receiver */ public Enumeration children() { return null; } // --- serialization --------------------------------------------- private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeInt(p0.getOffset()); s.writeInt(p1.getOffset()); } private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { s.defaultReadObject(); // set the range with positions that track change int off0 = s.readInt(); int off1 = s.readInt(); try { p0 = createPosition(off0); p1 = createPosition(off1); } catch (BadLocationException e) { p0 = null; p1 = null; throw new IOException("Can't restore Position references"); } } // ---- members ----------------------------------------------------- private transient Position p0; private transient Position p1; } /** * Represents the root element of the bidirectional element structure. * The root element is the only element in the bidi element structure * which contains children. */ class BidiRootElement extends BranchElement { BidiRootElement() { super( null, null ); } /** * Gets the name of the element. * @return the name */ public String getName() { return "bidi root"; } } /** * Represents an element of the bidirectional element structure. */ class BidiElement extends LeafElement { /** * Creates a new BidiElement. */ BidiElement(Element parent, int start, int end, int level) { super(parent, new SimpleAttributeSet(), start, end); addAttribute(StyleConstants.BidiLevel, Integer.valueOf(level)); //System.out.println("BidiElement: start = " + start // + " end = " + end + " level = " + level ); } /** * Gets the name of the element. * @return the name */ public String getName() { return BidiElementName; } int getLevel() { Integer o = (Integer) getAttribute(StyleConstants.BidiLevel); if (o != null) { return o.intValue(); } return 0; // Level 0 is base level (non-embedded) left-to-right } boolean isLeftToRight() { return ((getLevel() % 2) == 0); } } /** * Stores document changes as the document is being * modified. Can subsequently be used for change notification * when done with the document modification transaction. * This is used by the AbstractDocument class and its extensions * for broadcasting change information to the document listeners. */ public class DefaultDocumentEvent extends CompoundEdit implements DocumentEvent { /** * Constructs a change record. * * @param offs the offset into the document of the change >= 0 * @param len the length of the change >= 0 * @param type the type of event (DocumentEvent.EventType) * @since 1.4 */ public DefaultDocumentEvent(int offs, int len, DocumentEvent.EventType type) { super(); offset = offs; length = len; this.type = type; } /** * Returns a string description of the change event. * * @return a string */ public String toString() { return edits.toString(); } // --- CompoundEdit methods -------------------------- /** * Adds a document edit. If the number of edits crosses * a threshold, this switches on a hashtable lookup for * ElementChange implementations since access of these * needs to be relatively quick. * * @param anEdit a document edit record * @return true if the edit was added */ public boolean addEdit(UndoableEdit anEdit) { // if the number of changes gets too great, start using // a hashtable for to locate the change for a given element. if ((changeLookup == null) && (edits.size() > 10)) { changeLookup = new Hashtable<Element, ElementChange>(); int n = edits.size(); for (int i = 0; i < n; i++) { Object o = edits.elementAt(i); if (o instanceof DocumentEvent.ElementChange) { DocumentEvent.ElementChange ec = (DocumentEvent.ElementChange) o; changeLookup.put(ec.getElement(), ec); } } } // if we have a hashtable... add the entry if it's // an ElementChange. if ((changeLookup != null) && (anEdit instanceof DocumentEvent.ElementChange)) { DocumentEvent.ElementChange ec = (DocumentEvent.ElementChange) anEdit; changeLookup.put(ec.getElement(), ec); } return super.addEdit(anEdit); } /** * Redoes a change. * * @exception CannotRedoException if the change cannot be redone */ public void redo() throws CannotRedoException { writeLock(); try { // change the state super.redo(); // fire a DocumentEvent to notify the view(s) UndoRedoDocumentEvent ev = new UndoRedoDocumentEvent(this, false); if (type == DocumentEvent.EventType.INSERT) { fireInsertUpdate(ev); } else if (type == DocumentEvent.EventType.REMOVE) { fireRemoveUpdate(ev); } else { fireChangedUpdate(ev); } } finally { writeUnlock(); } } /** * Undoes a change. * * @exception CannotUndoException if the change cannot be undone */ public void undo() throws CannotUndoException { writeLock(); try { // change the state super.undo(); // fire a DocumentEvent to notify the view(s) UndoRedoDocumentEvent ev = new UndoRedoDocumentEvent(this, true); if (type == DocumentEvent.EventType.REMOVE) { fireInsertUpdate(ev); } else if (type == DocumentEvent.EventType.INSERT) { fireRemoveUpdate(ev); } else { fireChangedUpdate(ev); } } finally { writeUnlock(); } } /** * DefaultDocument events are significant. If you wish to aggregate * DefaultDocumentEvents to present them as a single edit to the user * place them into a CompoundEdit. * * @return whether the event is significant for edit undo purposes */ public boolean isSignificant() { return true; } /** * Provides a localized, human readable description of this edit * suitable for use in, say, a change log. * * @return the description */ public String getPresentationName() { DocumentEvent.EventType type = getType(); if(type == DocumentEvent.EventType.INSERT) return UIManager.getString("AbstractDocument.additionText"); if(type == DocumentEvent.EventType.REMOVE) return UIManager.getString("AbstractDocument.deletionText"); return UIManager.getString("AbstractDocument.styleChangeText"); } /** * Provides a localized, human readable description of the undoable * form of this edit, e.g. for use as an Undo menu item. Typically * derived from getDescription(); * * @return the description */ public String getUndoPresentationName() { return UIManager.getString("AbstractDocument.undoText") + " " + getPresentationName(); } /** * Provides a localized, human readable description of the redoable * form of this edit, e.g. for use as a Redo menu item. Typically * derived from getPresentationName(); * * @return the description */ public String getRedoPresentationName() { return UIManager.getString("AbstractDocument.redoText") + " " + getPresentationName(); } // --- DocumentEvent methods -------------------------- /** * Returns the type of event. * * @return the event type as a DocumentEvent.EventType * @see DocumentEvent#getType */ public DocumentEvent.EventType getType() { return type; } /** * Returns the offset within the document of the start of the change. * * @return the offset >= 0 * @see DocumentEvent#getOffset */ public int getOffset() { return offset; } /** * Returns the length of the change. * * @return the length >= 0 * @see DocumentEvent#getLength */ public int getLength() { return length; } /** * Gets the document that sourced the change event. * * @return the document * @see DocumentEvent#getDocument */ public Document getDocument() { return AbstractDocument.this; } /** * Gets the changes for an element. * * @param elem the element * @return the changes */ public DocumentEvent.ElementChange getChange(Element elem) { if (changeLookup != null) { return changeLookup.get(elem); } int n = edits.size(); for (int i = 0; i < n; i++) { Object o = edits.elementAt(i); if (o instanceof DocumentEvent.ElementChange) { DocumentEvent.ElementChange c = (DocumentEvent.ElementChange) o; if (elem.equals(c.getElement())) { return c; } } } return null; } // --- member variables ------------------------------------ private int offset; private int length; private Hashtable<Element, ElementChange> changeLookup; private DocumentEvent.EventType type; } /** * This event used when firing document changes while Undo/Redo * operations. It just wraps DefaultDocumentEvent and delegates * all calls to it except getType() which depends on operation * (Undo or Redo). */ class UndoRedoDocumentEvent implements DocumentEvent { private DefaultDocumentEvent src = null; private boolean isUndo; private EventType type = null; public UndoRedoDocumentEvent(DefaultDocumentEvent src, boolean isUndo) { this.src = src; this.isUndo = isUndo; if(isUndo) { if(src.getType().equals(EventType.INSERT)) { type = EventType.REMOVE; } else if(src.getType().equals(EventType.REMOVE)) { type = EventType.INSERT; } else { type = src.getType(); } } else { type = src.getType(); } } public DefaultDocumentEvent getSource() { return src; } // DocumentEvent methods delegated to DefaultDocumentEvent source // except getType() which depends on operation (Undo or Redo). public int getOffset() { return src.getOffset(); } public int getLength() { return src.getLength(); } public Document getDocument() { return src.getDocument(); } public DocumentEvent.EventType getType() { return type; } public DocumentEvent.ElementChange getChange(Element elem) { return src.getChange(elem); } } /** * An implementation of ElementChange that can be added to the document * event. */ public static class ElementEdit extends AbstractUndoableEdit implements DocumentEvent.ElementChange {