/** Update the child views in response to a document event. */
  void updateChildren(DocumentEvent e, Shape a) {

    Element elem = getElement();
    DocumentEvent.ElementChange ec = e.getChange(elem);

    // This occurs when syntax highlighting only changes on lines
    // (i.e. beginning a multiline comment).
    if (e.getType() == DocumentEvent.EventType.CHANGE) {
      // System.err.println("Updating the damage due to a CHANGE event...");
      // FIXME:  Make me repaint more intelligently.
      getContainer().repaint();
      // damageLineRange(startLine,endLine, a, host);
    } else if (ec != null) {

      // the structure of this element changed.
      Element[] removedElems = ec.getChildrenRemoved();
      Element[] addedElems = ec.getChildrenAdded();
      View[] added = new View[addedElems.length];

      for (int i = 0; i < addedElems.length; i++) added[i] = new WrappedLine(addedElems[i]);
      // System.err.println("Replacing " + removedElems.length +
      // " children with " + addedElems.length);
      replace(ec.getIndex(), removedElems.length, added);

      // should damge a little more intelligently.
      if (a != null) {
        preferenceChanged(null, true, true);
        getContainer().repaint();
      }
    }

    // update font metrics which may be used by the child views
    updateMetrics();
  }
  /**
   * Repaint the region of change covered by the given document event. Damages the line that begins
   * the range to cover the case when the insert/remove is only on one line. If lines are added or
   * removed, damages the whole view. The longest line is checked to see if it has changed.
   */
  protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f) {
    Component host = getContainer();
    updateMetrics();
    Element elem = getElement();
    DocumentEvent.ElementChange ec = changes.getChange(elem);
    Element[] added = (ec != null) ? ec.getChildrenAdded() : null;
    Element[] removed = (ec != null) ? ec.getChildrenRemoved() : null;
    if (((added != null) && (added.length > 0)) || ((removed != null) && (removed.length > 0))) {
      // lines were added or removed...
      if (added != null) {
        int addedAt = ec.getIndex(); // FIXME: Is this correct?????
        for (int i = 0; i < added.length; i++) possiblyUpdateLongLine(added[i], addedAt + i);
      }
      if (removed != null) {
        for (int i = 0; i < removed.length; i++) {
          if (removed[i] == longLine) {
            longLineWidth = -1; // Must do this!!
            calculateLongestLine();
            break;
          }
        }
      }
      preferenceChanged(null, true, true);
      host.repaint();
    }

    // This occurs when syntax highlighting only changes on lines
    // (i.e. beginning a multiline comment).
    else if (changes.getType() == DocumentEvent.EventType.CHANGE) {
      // System.err.println("Updating the damage due to a CHANGE event...");
      int startLine = changes.getOffset();
      int endLine = changes.getLength();
      damageLineRange(startLine, endLine, a, host);
    } else {
      Element map = getElement();
      int line = map.getElementIndex(changes.getOffset());
      damageLineRange(line, line, a, host);
      if (changes.getType() == DocumentEvent.EventType.INSERT) {
        // check to see if the line is longer than current
        // longest line.
        Element e = map.getElement(line);
        if (e == longLine) {
          // We must recalculate longest line's width here
          // because it has gotten longer.
          longLineWidth = getLineWidth(line);
          preferenceChanged(null, true, false);
        } else {
          // If long line gets updated, update the status bars too.
          if (possiblyUpdateLongLine(e, line)) preferenceChanged(null, true, false);
        }
      } else if (changes.getType() == DocumentEvent.EventType.REMOVE) {
        if (map.getElement(line) == longLine) {
          // removed from longest line... recalc
          longLineWidth = -1; // Must do this!
          calculateLongestLine();
          preferenceChanged(null, true, false);
        }
      }
    }
  }
Exemple #3
0
 /**
  * Gives notification from the document that attributes were changed in a location that this view
  * is responsible for. To reduce the burden to subclasses, this functionality is spread out into
  * the following calls that subclasses can reimplement:
  *
  * <ol>
  *   <li><a href="#updateChildren">updateChildren</a> is called if there were any changes to the
  *       element this view is responsible for. If this view has child views that are represent the
  *       child elements, then this method should do whatever is necessary to make sure the child
  *       views correctly represent the model.
  *   <li><a href="#forwardUpdate">forwardUpdate</a> is called to forward the DocumentEvent to the
  *       appropriate child views.
  *   <li><a href="#updateLayout">updateLayout</a> is called to give the view a chance to either
  *       repair its layout, to reschedule layout, or do nothing.
  * </ol>
  *
  * @param e the change information from the associated document
  * @param a the current allocation of the view
  * @param f the factory to use to rebuild if the view has children
  * @see View#changedUpdate
  */
 public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
   if (getViewCount() > 0) {
     Element elem = getElement();
     DocumentEvent.ElementChange ec = e.getChange(elem);
     if (ec != null) {
       if (!updateChildren(ec, e, f)) {
         // don't consider the element changes they
         // are for a view further down.
         ec = null;
       }
     }
     forwardUpdate(ec, e, a, f);
     updateLayout(ec, e, a);
   }
 }
Exemple #4
0
  protected void documentChanged(DocumentEvent evt) {
    DocumentEvent.ElementChange ch = evt.getChange(document.getDefaultRootElement());

    int count;
    if (ch == null) count = 0;
    else count = ch.getChildrenAdded().length - ch.getChildrenRemoved().length;

    int line = getLineOfOffset(evt.getOffset());
    if (count == 0) {
      painter.invalidateLine(line);
    }
    // do magic stuff
    else if (line < firstLine) {
      setFirstLine(firstLine + count);
    }
    // end of magic stuff
    else {
      painter.invalidateLineRange(line, firstLine + visibleLines);
      updateScrollBars();
    }
  }