Ejemplo n.º 1
0
  /** Execute when new member join or leave Group */
  public void viewAccepted(View v) {
    memberSize = v.size();
    if (mainFrame != null) setTitle();
    members.clear();
    members.addAll(v.getMembers());

    if (v instanceof MergeView) {
      System.out.println("** " + v);

      // This is a simple merge function, which fetches the state from the coordinator
      // on a merge and overwrites all of its own state
      if (useState && !members.isEmpty()) {
        Address coord = members.get(0);
        Address local_addr = channel.getAddress();
        if (local_addr != null && !local_addr.equals(coord)) {
          try {

            // make a copy of our state first
            Map<Point, Color> copy = null;
            if (send_own_state_on_merge) {
              synchronized (drawPanel.state) {
                copy = new LinkedHashMap<Point, Color>(drawPanel.state);
              }
            }
            System.out.println("fetching state from " + coord);
            channel.getState(coord, 5000);
            if (copy != null)
              sendOwnState(copy); // multicast my own state so everybody else has it too
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    } else System.out.println("** View=" + v);
  }
Ejemplo n.º 2
0
  protected void movePolygon(Point previousMousePoint, Point mousePoint) {
    // Intersect a ray through each mouse point, with a geoid passing through the reference
    // elevation.
    // If either ray fails to intersect the geoid, then ignore this event. Use the difference
    // between the two
    // intersected positions to move the control point's location.

    View view = this.wwd.getView();
    Globe globe = this.wwd.getModel().getGlobe();

    Position refPos = this.polygon.getReferencePosition();
    if (refPos == null) return;

    Line ray = view.computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
    Line previousRay =
        view.computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY());

    Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), ray);
    Vec4 previousVec =
        AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), previousRay);

    if (vec == null || previousVec == null) {
      return;
    }

    Position pos = globe.computePositionFromPoint(vec);
    Position previousPos = globe.computePositionFromPoint(previousVec);
    LatLon change = pos.subtract(previousPos);

    this.polygon.move(new Position(change.getLatitude(), change.getLongitude(), 0.0));
  }
Ejemplo n.º 3
0
  /**
   * Notifies all views of a context change.
   *
   * @param nodes new context set (may be {@code null} if root nodes are addressed)
   * @param quick quick switch
   * @param vw the calling view
   */
  public void context(final Nodes nodes, final boolean quick, final View vw) {
    final Context ctx = gui.context;

    // add new entry if current node set has not been cached yet
    final Nodes newn = nodes.checkRoot();
    final Nodes empty = new Nodes(new int[0], ctx.data(), ctx.marked.ftpos);
    final Nodes curr = quick ? ctx.current() : null;
    final Nodes cmp = quick ? curr : ctx.marked;
    if (cont[hist] == null ? cmp != null : cmp == null || !cont[hist].sameAs(cmp)) {
      checkHist();
      if (quick) {
        // store history entry
        queries[hist] = "";
        marked[hist] = new Nodes(ctx.data());
        // add current entry
        cont[++hist] = curr;
      } else {
        // store history entry
        final String in = gui.input.getText();
        queries[hist] = in;
        marked[hist] = ctx.marked;
        // add current entry
        cont[++hist] = newn;
        queries[hist] = in;
        marked[hist] = empty;
      }
      histsize = hist;
    }
    ctx.set(newn, empty);

    for (final View v : view) if (v != vw && v.visible()) v.refreshContext(true, quick);
    gui.refreshControls();
  }
Ejemplo n.º 4
0
  protected void dragWholeShape(DragSelectEvent dragEvent, Movable dragObject) {
    View view = getWwd().getView();
    EllipsoidalGlobe globe = (EllipsoidalGlobe) getWwd().getModel().getGlobe();

    // Compute ref-point position in screen coordinates.
    Position refPos = dragObject.getReferencePosition();
    if (refPos == null) return;

    Vec4 refPoint = globe.computePointFromPosition(refPos);
    Vec4 screenRefPoint = view.project(refPoint);

    // Compute screen-coord delta since last event.
    int dx = dragEvent.getPickPoint().x - dragEvent.getPreviousPickPoint().x;
    int dy = dragEvent.getPickPoint().y - dragEvent.getPreviousPickPoint().y;

    // Find intersection of screen coord ref-point with globe.
    double x = screenRefPoint.x + dx;
    double y =
        dragEvent.getMouseEvent().getComponent().getSize().height - screenRefPoint.y + dy - 1;
    Line ray = view.computeRayFromScreenPoint(x, y);
    Intersection inters[] = globe.intersect(ray, refPos.getElevation());

    if (inters != null) {
      // Intersection with globe. Move reference point to the intersection point.
      Position p = globe.computePositionFromPoint(inters[0].getIntersectionPoint());
      dragObject.moveTo(p);
    }
  }
Ejemplo n.º 5
0
  private void goToSelectedNode(int mode) {
    TreePath path = resultTree.getSelectionPath();
    if (path == null) return;

    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
    Object value = node.getUserObject();

    // do nothing if clicked "foo (showing n occurrences in m files)"
    if (node.getParent() != resultTreeRoot && value instanceof HyperSearchNode) {
      HyperSearchNode n = (HyperSearchNode) value;
      Buffer buffer = n.getBuffer(view);
      if (buffer == null) return;

      EditPane pane;

      switch (mode) {
        case M_OPEN:
          pane = view.goToBuffer(buffer);
          break;
        case M_OPEN_NEW_VIEW:
          pane = jEdit.newView(view, buffer, false).getEditPane();
          break;
        case M_OPEN_NEW_PLAIN_VIEW:
          pane = jEdit.newView(view, buffer, true).getEditPane();
          break;
        case M_OPEN_NEW_SPLIT:
          pane = view.splitHorizontally();
          break;
        default:
          throw new IllegalArgumentException("Bad mode: " + mode);
      }

      n.goTo(pane);
    }
  } // }}}
Ejemplo n.º 6
0
 /** Notifies all views of updates in the data structure. */
 public void update() {
   final Data data = initHistory(gui.context);
   if (data == null) return;
   gui.context.marked = new Nodes(data);
   for (final View v : view) if (v.visible()) v.refreshUpdate();
   gui.refreshControls();
 }
Ejemplo n.º 7
0
  /**
   * Performs layout for the minor axis of the box (i.e. the axis orthogonal to the axis that it
   * represents). The results of the layout (the offset and span for each children) are placed in
   * the given arrays which represent the allocations to the children along the minor axis.
   *
   * @param targetSpan the total span given to the view, which would be used to layout the children.
   * @param axis the axis being layed out
   * @param offsets the offsets from the origin of the view for each of the child views; this is a
   *     return value and is filled in by the implementation of this method
   * @param spans the span of each child view; this is a return value and is filled in by the
   *     implementation of this method
   */
  protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
    int n = getViewCount();
    Object key = (axis == X_AXIS) ? CSS.Attribute.WIDTH : CSS.Attribute.HEIGHT;
    for (int i = 0; i < n; i++) {
      View v = getView(i);
      int min = (int) v.getMinimumSpan(axis);
      int max;

      // check for percentage span
      AttributeSet a = v.getAttributes();
      CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(key);
      if ((lv != null) && lv.isPercentage()) {
        // bound the span to the percentage specified
        min = Math.max((int) lv.getValue(targetSpan), min);
        max = min;
      } else {
        max = (int) v.getMaximumSpan(axis);
      }

      // assign the offset and span for the child
      if (max < targetSpan) {
        // can't make the child this wide, align it
        float align = v.getAlignment(axis);
        offsets[i] = (int) ((targetSpan - max) * align);
        spans[i] = max;
      } else {
        // make it the target width, or as small as it can get.
        offsets[i] = 0;
        spans[i] = Math.max(min, targetSpan);
      }
    }
  }
Ejemplo n.º 8
0
 public void dispose() {
   // Dispose of the views
   logger.debug("Disposing of views");
   for (View view : getViews()) {
     view.dispose();
   }
 }
  /** Move forward one item in the window history, if possible, and open the view. */
  private void onForward() {

    View view = history.goForward();
    if (view != null) oParent.addViewToDesktop(view, view.getLabel());

    enableHistoryButtons();
  }
Ejemplo n.º 10
0
 /**
  * Notifies all views of a selection change.
  *
  * @param mark marked nodes
  * @param vw the calling view
  */
 public void mark(final Nodes mark, final View vw) {
   final Context ctx = gui.context;
   ctx.marked = mark;
   for (final View v : view) if (v != vw && v.visible()) v.refreshMark();
   gui.filter.setEnabled(mark.size() != 0);
   gui.refreshControls();
 }
Ejemplo n.º 11
0
  @Override
  public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {

    int offs = -1;

    if (!isAllocationValid()) {
      Rectangle alloc = a.getBounds();
      setSize(alloc.width, alloc.height);
    }

    // Get the child view for the line at (x,y), and ask it for the
    // specific offset.
    Rectangle alloc = getInsideAllocation(a);
    View v = getViewAtPoint((int) x, (int) y, alloc);
    if (v != null) {
      offs = v.viewToModel(x, y, alloc, bias);
    }

    // Code folding may have hidden the last line.  If so, return the last
    // visible offset instead of the last offset.
    if (host.isCodeFoldingEnabled()
        && v == getView(getViewCount() - 1)
        && offs == v.getEndOffset() - 1) {
      offs = host.getLastVisibleOffset();
    }

    return offs;
  }
 /**
  * Gives notification that something was inserted into the document in a location that this view
  * is responsible for. This is implemented to simply update the children.
  *
  * @param changes 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#insertUpdate
  */
 public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
   updateChildren(changes, a);
   Rectangle alloc = ((a != null) && isAllocationValid()) ? getInsideAllocation(a) : null;
   int pos = changes.getOffset();
   View v = getViewAtPosition(pos, alloc);
   if (v != null) v.insertUpdate(changes, alloc, f);
 }
Ejemplo n.º 13
0
 public boolean containsView(String id) {
   for (View view : getViews()) {
     if (id.equals(view.getId())) {
       return true;
     }
   }
   return false;
 }
Ejemplo n.º 14
0
 /**
  * Notifies all views of a focus change.
  *
  * @param pre focused pre value
  * @param vw the calling view
  */
 public void focus(final int pre, final View vw) {
   if (gui.context.focused == pre) return;
   gui.context.focused = pre;
   for (final View v : view) if (v != vw && v.visible()) v.refreshFocus();
   if (pre != -1) {
     gui.status.setText(Token.string(ViewData.path(gui.context.data(), pre)));
   }
 }
Ejemplo n.º 15
0
 /** Notifies all views of layout changes. */
 public void layout() {
   for (final View v : view) {
     v.refreshLayout();
     final ViewPanel vp = (ViewPanel) v.getParent();
     final ViewMover vm = (ViewMover) vp.getComponent(0);
     vm.refreshLayout();
   }
 }
  /** Display the forwards window history in a menu. */
  private void onShowForwardHistory() {

    UIScrollableMenu hist =
        new UIScrollableMenu(
            LanguageProperties.getString(
                LanguageProperties.TOOLBARS_BUNDLE, "UIToolBarMain.forwardHistory"),
            0); //$NON-NLS-1$

    Vector views = history.getForwardHistory();
    int currentIndex = history.getCurrentPosition();

    int count = views.size();
    if (count == 0) return;

    JMenuItem item = null;
    for (int i = 0; i < count; i++) {
      View view = (View) views.elementAt(i);
      item = new JMenuItem(view.getLabel());

      final View fview = view;
      final int fi = (currentIndex + 1) + i;
      item.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent event) {
              if (history.goToHistoryItem(fi)) oParent.addViewToDesktop(fview, fview.getLabel());
            }
          });

      hist.add(item);
    }

    JPopupMenu pop = hist.getPopupMenu();
    pop.pack();

    Point loc = pbShowForwardHistory.getLocation();
    Dimension size = pbShowForwardHistory.getSize();
    Dimension popsize = hist.getPreferredSize();
    Point finalP = SwingUtilities.convertPoint(tbrToolBar.getParent(), loc, oParent.getDesktop());

    int x = 0;
    int y = 0;
    if (oManager.getLeftToolBarController().containsBar(tbrToolBar)) {
      x = finalP.x + size.width;
      y = finalP.y;
    } else if (oManager.getRightToolBarController().containsBar(tbrToolBar)) {
      x = finalP.x - popsize.width;
      y = finalP.y;
    } else if (oManager.getTopToolBarController().containsBar(tbrToolBar)) {
      x = finalP.x;
      y = finalP.y + size.width;
    } else if (oManager.getBottomToolBarController().containsBar(tbrToolBar)) {
      x = finalP.x;
      y = finalP.y - popsize.height;
    }

    hist.setPopupMenuVisible(true);
    pop.show(oParent.getDesktop(), x, y);
  }
Ejemplo n.º 17
0
 public void bringViewToFront(String id) {
   for (View view : getViews()) {
     if (view.getId() != null && view.getId().equals(id)) {
       Util.bringToFront(view);
       // Carry on until all views with the specified
       // view id are in front
     }
   }
 }
Ejemplo n.º 18
0
 private View getView(String id, Component c) {
   Collection<View> views = UIUtil.getComponentsExtending(c, View.class);
   for (View view : views) {
     if (view.getId().equals(id)) {
       return view;
     }
   }
   return null;
 }
Ejemplo n.º 19
0
 private boolean contains(View logicalView, View v) {
   int n = logicalView.getViewCount();
   for (int i = 0; i < n; i++) {
     if (logicalView.getView(i) == v) {
       return true;
     }
   }
   return false;
 }
Ejemplo n.º 20
0
 /**
  * Forwards the <code>DocumentEvent</code> to the give child view. This simply messages the view
  * with a call to <code>insertUpdate</code>, <code>removeUpdate</code>, or <code>changedUpdate
  * </code> depending upon the type of the event. This is called by <a
  * href="#forwardUpdate">forwardUpdate</a> to forward the event to children that need it.
  *
  * @param v the child view to forward the event to
  * @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 #forwardUpdate
  * @since 1.3
  */
 protected void forwardUpdateToView(View v, DocumentEvent e, Shape a, ViewFactory f) {
   DocumentEvent.EventType type = e.getType();
   if (type == DocumentEvent.EventType.INSERT) {
     v.insertUpdate(e, a, f);
   } else if (type == DocumentEvent.EventType.REMOVE) {
     v.removeUpdate(e, a, f);
   } else {
     v.changedUpdate(e, a, f);
   }
 }
Ejemplo n.º 21
0
    /**
     * Update the flow on the given FlowView. By default, this causes all of the rows (child views)
     * to be rebuilt to match the given constraints for each row. This is called by a
     * FlowView.layout to update the child views in the flow.
     *
     * @param fv the view to reflow
     */
    public void layout(FlowView fv) {
      int p0 = fv.getStartOffset();
      int p1 = fv.getEndOffset();

      // we want to preserve all views from the logicalView from being
      // removed
      View lv = getLogicalView(fv);
      int n = lv.getViewCount();
      for (int i = 0; i < n; i++) {
        View v = lv.getView(i);
        v.setParent(lv);
      }
      fv.removeAll();
      for (int rowIndex = 0; p0 < p1; rowIndex++) {
        View row = fv.createRow();
        fv.append(row);

        // layout the row to the current span.  If nothing fits,
        // force something.
        int next = layoutRow(fv, rowIndex, p0);
        if (row.getViewCount() == 0) {
          row.append(createView(fv, p0, Integer.MAX_VALUE, rowIndex));
          next = row.getEndOffset();
        }
        if (next <= p0) {
          throw new StateInvariantError("infinite loop in formatting");
        } else {
          p0 = next;
        }
      }
    }
Ejemplo n.º 22
0
  /** Notifies all views of a data reference change. */
  public void init() {
    final Data data = initHistory(gui.context);
    if (data != null) {
      // if a large database is opened, the user is asked if complex
      /// visualizations should be closed first
      final long size = data.meta.dbsize();
      boolean open = false;
      for (final View v : view) open |= v.visible() && v.db();
      if (open
          && size > LARGEDB
          && BaseXDialog.confirm(gui, Util.info(H_LARGE_DB, Performance.format(size)))) {
        for (final View v : view) if (v.visible() && v.db()) v.visible(false);
      }
    } else {
      // database closed: close open dialogs
      for (final Window w : gui.getOwnedWindows()) {
        if (w.isVisible() && w instanceof BaseXDialog) ((BaseXDialog) w).cancel();
      }
    }

    gui.context.focused = -1;
    for (final View v : view) v.refreshInit();
    gui.layoutViews();
    gui.setTitle(data != null ? data.meta.name : null);
  }
Ejemplo n.º 23
0
 /**
  * Fetches the child view index representing the given position in the model.
  *
  * @param pos the position >= 0
  * @return index of the view representing the given position, or -1 if no view represents that
  *     position
  */
 protected int getViewIndexAtPosition(int pos) {
   if (pos >= getStartOffset() && (pos < getEndOffset())) {
     for (int counter = getViewCount() - 1; counter >= 0; counter--) {
       View v = getView(counter);
       if (pos >= v.getStartOffset() && pos < v.getEndOffset()) {
         return counter;
       }
     }
   }
   return -1;
 }
Ejemplo n.º 24
0
 private void recursiveReparent(View v, View logicalView) {
   int n = v.getViewCount();
   for (int i = 0; i < n; i++) {
     View tmpView = v.getView(i);
     if (contains(logicalView, tmpView)) {
       tmpView.setParent(logicalView);
     } else {
       recursiveReparent(tmpView, logicalView);
     }
   }
 }
Ejemplo n.º 25
0
 @Override
 public GridCellImpl getCellFor(final Content content) {
   // check if the content is already in some cell
   GridCellImpl current = myContent2Cell.get(content);
   if (current != null) return current;
   // view may be shared between several contents with the same ID in different cells
   // (temporary contents like "Dump Stack" or "Console Result")
   View view = getStateFor(content);
   final GridCellImpl cell = myPlaceInGrid2Cell.get(view.getPlaceInGrid());
   assert cell != null : "Unknown place in grid: " + view.getPlaceInGrid().name();
   return cell;
 }
Ejemplo n.º 26
0
  protected void doMoveAirspaceLaterally(
      WorldWindow wwd, Airspace airspace, Point mousePoint, Point previousMousePoint) {
    // Intersect a ray throuh each mouse point, with a geoid passing through the reference
    // elevation. Since
    // most airspace control points follow a fixed altitude, this will track close to the intended
    // mouse position.
    // If either ray fails to intersect the geoid, then ignore this event. Use the difference
    // between the two
    // intersected positions to move the control point's location.

    if (!(airspace instanceof Movable)) {
      return;
    }

    Movable movable = (Movable) airspace;
    View view = wwd.getView();
    Globe globe = wwd.getModel().getGlobe();

    Position refPos = movable.getReferencePosition();
    if (refPos == null) return;

    // Convert the reference position into a cartesian point. This assumes that the reference
    // elevation is defined
    // by the airspace's lower altitude.
    Vec4 refPoint = null;
    if (airspace.isTerrainConforming()[LOWER_ALTITUDE])
      refPoint = wwd.getSceneController().getTerrain().getSurfacePoint(refPos);
    if (refPoint == null) refPoint = globe.computePointFromPosition(refPos);

    // Convert back to a position.
    refPos = globe.computePositionFromPoint(refPoint);

    Line ray = view.computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
    Line previousRay =
        view.computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY());

    Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(wwd, refPos.getElevation(), ray);
    Vec4 previousVec = AirspaceEditorUtil.intersectGlobeAt(wwd, refPos.getElevation(), previousRay);

    if (vec == null || previousVec == null) {
      return;
    }

    Position pos = globe.computePositionFromPoint(vec);
    Position previousPos = globe.computePositionFromPoint(previousVec);
    LatLon change = pos.subtract(previousPos);

    movable.move(new Position(change.getLatitude(), change.getLongitude(), 0.0));

    this.fireAirspaceMoved(new AirspaceEditEvent(wwd, airspace, this));
  }
Ejemplo n.º 27
0
  public void play(int lv) {
    jl.setText("Level " + level);
    Game game = new Game(lv); // An object representing the game
    View view = new View(game); // An object representing the view of the game
    game.newGame();
    view.print();
    gameBoardPanel = view.mainPanel;
    ButtonPanel buttonPanel = new ButtonPanel(game);
    container.add(buttonPanel, BorderLayout.EAST);
    container.add(gameBoardPanel, BorderLayout.WEST);
    mainFrame.pack();

    // Main game loop
    while (true) {

      view.print();
      gameBoardPanel = view.mainPanel;

      // Win/lose conditions
      if (game.isWin()) {
        view.print();
        gameBoardPanel = view.mainPanel;
        int choice;
        choice = JOptionPane.showConfirmDialog(null, "You win!", "", JOptionPane.OK_OPTION);
        if (choice == JOptionPane.OK_OPTION) {
          level++;
          mainFrame.remove(buttonPanel);
          mainFrame.remove(gameBoardPanel);
          play(level);
        }
      }
      if (game.isLose()) {
        view.print();
        gameBoardPanel = view.mainPanel;
        int choice;
        choice =
            JOptionPane.showConfirmDialog(
                null, "You lose!", "Would you like to play again?", JOptionPane.YES_NO_OPTION);
        if (choice == JOptionPane.YES_OPTION) {
          level = 1;
          mainFrame.remove(buttonPanel);
          mainFrame.remove(gameBoardPanel);
          play(level);
        } else {
          System.exit(0);
        }
      }
    }
  }
Ejemplo n.º 28
0
 /**
  * Determines the preferred span for this view along an axis.
  *
  * @param axis may be either View.X_AXIS or View.Y_AXIS
  * @return the span the view would like to be rendered into. Typically the view is told to
  *     render into the span that is returned, although there is no guarantee. The parent may
  *     choose to resize or break the view.
  * @see View#getPreferredSpan
  */
 public float getPreferredSpan(int axis) {
   float maxpref = 0;
   float pref = 0;
   int n = getViewCount();
   for (int i = 0; i < n; i++) {
     View v = getView(i);
     pref += v.getPreferredSpan(axis);
     if (v.getBreakWeight(axis, 0, Short.MAX_VALUE) >= ForcedBreakWeight) {
       maxpref = Math.max(maxpref, pref);
       pref = 0;
     }
   }
   maxpref = Math.max(maxpref, pref);
   return maxpref;
 }
Ejemplo n.º 29
0
  /**
   * Compute the lat/lon position of the view center
   *
   * @param dc the current DrawContext
   * @param view the current View
   * @return the ground position of the view center or null
   */
  protected Position computeGroundPosition(DrawContext dc, View view) {
    if (view == null) return null;

    Position groundPos =
        view.computePositionFromScreenPoint(
            view.getViewport().getWidth() / 2, view.getViewport().getHeight() / 2);
    if (groundPos == null) return null;

    double elevation =
        dc.getGlobe().getElevation(groundPos.getLatitude(), groundPos.getLongitude());
    return new Position(
        groundPos.getLatitude(),
        groundPos.getLongitude(),
        elevation * dc.getVerticalExaggeration());
  }
Ejemplo n.º 30
0
  /**
   * Forwards the given <code>DocumentEvent</code> to the child views that need to be notified of
   * the change to the model. If there were changes to the element this view is responsible for,
   * that should be considered when forwarding (i.e. new child views should not get notified).
   *
   * @param ec changes to the element this view is responsible for (may be <code>null</code> if
   *     there were no changes).
   * @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 #insertUpdate
   * @see #removeUpdate
   * @see #changedUpdate
   * @since 1.3
   */
  protected void forwardUpdate(
      DocumentEvent.ElementChange ec, DocumentEvent e, Shape a, ViewFactory f) {
    Element elem = getElement();
    int pos = e.getOffset();
    int index0 = getViewIndex(pos, Position.Bias.Forward);
    if (index0 == -1 && e.getType() == DocumentEvent.EventType.REMOVE && pos >= getEndOffset()) {
      // Event beyond our offsets. We may have represented this, that is
      // the remove may have removed one of our child Elements that
      // represented this, so, we should foward to last element.
      index0 = getViewCount() - 1;
    }
    int index1 = index0;
    View v = (index0 >= 0) ? getView(index0) : null;
    if (v != null) {
      if ((v.getStartOffset() == pos) && (pos > 0)) {
        // If v is at a boundary, forward the event to the previous
        // view too.
        index0 = Math.max(index0 - 1, 0);
      }
    }
    if (e.getType() != DocumentEvent.EventType.REMOVE) {
      index1 = getViewIndex(pos + e.getLength(), Position.Bias.Forward);
      if (index1 < 0) {
        index1 = getViewCount() - 1;
      }
    }
    int hole0 = index1 + 1;
    int hole1 = hole0;
    Element[] addedElems = (ec != null) ? ec.getChildrenAdded() : null;
    if ((addedElems != null) && (addedElems.length > 0)) {
      hole0 = ec.getIndex();
      hole1 = hole0 + addedElems.length - 1;
    }

    // forward to any view not in the forwarding hole
    // formed by added elements (i.e. they will be updated
    // by initialization.
    index0 = Math.max(index0, 0);
    for (int i = index0; i <= index1; i++) {
      if (!((i >= hole0) && (i <= hole1))) {
        v = getView(i);
        if (v != null) {
          Shape childAlloc = getChildAllocation(i, a);
          forwardUpdateToView(v, e, childAlloc, f);
        }
      }
    }
  }