KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > text > CompositeView


1 /*
2  * @(#)CompositeView.java 1.67 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.text;
8
9 import java.util.Vector JavaDoc;
10 import java.awt.*;
11 import javax.swing.event.*;
12 import javax.swing.SwingConstants JavaDoc;
13
14 /**
15  * <code>CompositeView</code> is an abstract <code>View</code>
16  * implementation which manages one or more child views.
17  * (Note that <code>CompositeView</code> is intended
18  * for managing relatively small numbers of child views.)
19  * <code>CompositeView</code> is intended to be used as
20  * a starting point for <code>View</code> implementations,
21  * such as <code>BoxView</code>, that will contain child
22  * <code>View</code>s. Subclasses that wish to manage the
23  * collection of child <code>View</code>s should use the
24  * {@link #replace} method. As <code>View</code> invokes
25  * <code>replace</code> during <code>DocumentListener</code>
26  * notification, you normally won't need to directly
27  * invoke <code>replace</code>.
28  *
29  * <p>While <code>CompositeView</code>
30  * does not impose a layout policy on its child <code>View</code>s,
31  * it does allow for inseting the child <code>View</code>s
32  * it will contain. The insets can be set by either
33  * {@link #setInsets} or {@link #setParagraphInsets}.
34  *
35  * <p>In addition to the abstract methods of
36  * {@link javax.swing.text.View},
37  * subclasses of <code>CompositeView</code> will need to
38  * override:
39  * <ul>
40  * <li>{@link #isBefore} - Used to test if a given
41  * <code>View</code> location is before the visual space
42  * of the <code>CompositeView</code>.
43  * <li>{@link #isAfter} - Used to test if a given
44  * <code>View</code> location is after the visual space
45  * of the <code>CompositeView</code>.
46  * <li>{@link #getViewAtPoint} - Returns the view at
47  * a given visual location.
48  * <li>{@link #childAllocation} - Returns the bounds of
49  * a particular child <code>View</code>.
50  * <code>getChildAllocation</code> will invoke
51  * <code>childAllocation</code> after offseting
52  * the bounds by the <code>Inset</code>s of the
53  * <code>CompositeView</code>.
54  * </ul>
55  *
56  * @author Timothy Prinzing
57  * @version 1.67 12/19/03
58  */

59 public abstract class CompositeView extends View JavaDoc {
60
61     /**
62      * Constructs a <code>CompositeView</code> for the given element.
63      *
64      * @param elem the element this view is responsible for
65      */

66     public CompositeView(Element JavaDoc elem) {
67     super(elem);
68     children = new View JavaDoc[1];
69     nchildren = 0;
70     childAlloc = new Rectangle();
71     }
72
73     /**
74      * Loads all of the children to initialize the view.
75      * This is called by the {@link #setParent}
76      * method. Subclasses can reimplement this to initialize
77      * their child views in a different manner. The default
78      * implementation creates a child view for each
79      * child element.
80      *
81      * @param f the view factory
82      * @see #setParent
83      */

84     protected void loadChildren(ViewFactory JavaDoc f) {
85     if (f == null) {
86         // No factory. This most likely indicates the parent view
87
// has changed out from under us, bail!
88
return;
89     }
90     Element JavaDoc e = getElement();
91     int n = e.getElementCount();
92     if (n > 0) {
93         View JavaDoc[] added = new View JavaDoc[n];
94         for (int i = 0; i < n; i++) {
95         added[i] = f.create(e.getElement(i));
96         }
97         replace(0, 0, added);
98     }
99     }
100
101     // --- View methods ---------------------------------------------
102

103     /**
104      * Sets the parent of the view.
105      * This is reimplemented to provide the superclass
106      * behavior as well as calling the <code>loadChildren</code>
107      * method if this view does not already have children.
108      * The children should not be loaded in the
109      * constructor because the act of setting the parent
110      * may cause them to try to search up the hierarchy
111      * (to get the hosting <code>Container</code> for example).
112      * If this view has children (the view is being moved
113      * from one place in the view hierarchy to another),
114      * the <code>loadChildren</code> method will not be called.
115      *
116      * @param parent the parent of the view, <code>null</code> if none
117      */

118     public void setParent(View JavaDoc parent) {
119     super.setParent(parent);
120     if ((parent != null) && (nchildren == 0)) {
121         ViewFactory JavaDoc f = getViewFactory();
122         loadChildren(f);
123     }
124     }
125
126     /**
127      * Returns the number of child views of this view.
128      *
129      * @return the number of views >= 0
130      * @see #getView
131      */

132     public int getViewCount() {
133     return nchildren;
134     }
135
136     /**
137      * Returns the n-th view in this container.
138      *
139      * @param n the number of the desired view, >= 0 && < getViewCount()
140      * @return the view at index <code>n</code>
141      */

142     public View JavaDoc getView(int n) {
143     return children[n];
144     }
145
146     /**
147      * Replaces child views. If there are no views to remove
148      * this acts as an insert. If there are no views to
149      * add this acts as a remove. Views being removed will
150      * have the parent set to <code>null</code>,
151      * and the internal reference to them removed so that they
152      * may be garbage collected.
153      *
154      * @param offset the starting index into the child views to insert
155      * the new views; >= 0 and <= getViewCount
156      * @param length the number of existing child views to remove;
157      * this should be a value >= 0 and <= (getViewCount() - offset)
158      * @param views the child views to add; this value can be
159      * <code>null</code>
160      * to indicate no children are being added (useful to remove)
161      */

162     public void replace(int offset, int length, View JavaDoc[] views) {
163     // make sure an array exists
164
if (views == null) {
165         views = ZERO;
166     }
167
168     // update parent reference on removed views
169
for (int i = offset; i < offset + length; i++) {
170         if (children[i].getParent() == this) {
171         // in FlowView.java view might be referenced
172
// from two super-views as a child. see logicalView
173
children[i].setParent(null);
174         }
175         children[i] = null;
176     }
177     
178     // update the array
179
int delta = views.length - length;
180     int src = offset + length;
181     int nmove = nchildren - src;
182     int dest = src + delta;
183     if ((nchildren + delta) >= children.length) {
184         // need to grow the array
185
int newLength = Math.max(2*children.length, nchildren + delta);
186         View JavaDoc[] newChildren = new View JavaDoc[newLength];
187         System.arraycopy(children, 0, newChildren, 0, offset);
188         System.arraycopy(views, 0, newChildren, offset, views.length);
189         System.arraycopy(children, src, newChildren, dest, nmove);
190         children = newChildren;
191     } else {
192         // patch the existing array
193
System.arraycopy(children, src, children, dest, nmove);
194         System.arraycopy(views, 0, children, offset, views.length);
195     }
196     nchildren = nchildren + delta;
197
198     // update parent reference on added views
199
for (int i = 0; i < views.length; i++) {
200         views[i].setParent(this);
201     }
202     }
203
204     /**
205      * Fetches the allocation for the given child view to
206      * render into. This enables finding out where various views
207      * are located.
208      *
209      * @param index the index of the child, >= 0 && < getViewCount()
210      * @param a the allocation to this view
211      * @return the allocation to the child
212      */

213     public Shape getChildAllocation(int index, Shape a) {
214     Rectangle alloc = getInsideAllocation(a);
215     childAllocation(index, alloc);
216     return alloc;
217     }
218
219     /**
220      * Provides a mapping from the document model coordinate space
221      * to the coordinate space of the view mapped to it.
222      *
223      * @param pos the position to convert >= 0
224      * @param a the allocated region to render into
225      * @param b a bias value of either <code>Position.Bias.Forward</code>
226      * or <code>Position.Bias.Backward</code>
227      * @return the bounding box of the given position
228      * @exception BadLocationException if the given position does
229      * not represent a valid location in the associated document
230      * @see View#modelToView
231      */

232     public Shape modelToView(int pos, Shape a, Position.Bias JavaDoc b) throws BadLocationException JavaDoc {
233     boolean isBackward = (b == Position.Bias.Backward);
234     int testPos = (isBackward) ? Math.max(0, pos - 1) : pos;
235     if(isBackward && testPos < getStartOffset()) {
236         return null;
237     }
238     int vIndex = getViewIndexAtPosition(testPos);
239     if ((vIndex != -1) && (vIndex < getViewCount())) {
240         View JavaDoc v = getView(vIndex);
241         if(v != null && testPos >= v.getStartOffset() &&
242            testPos < v.getEndOffset()) {
243                 Shape childShape = getChildAllocation(vIndex, a);
244                 if (childShape == null) {
245                     // We are likely invalid, fail.
246
return null;
247                 }
248         Shape retShape = v.modelToView(pos, childShape, b);
249         if(retShape == null && v.getEndOffset() == pos) {
250             if(++vIndex < getViewCount()) {
251             v = getView(vIndex);
252             retShape = v.modelToView(pos, getChildAllocation(vIndex, a), b);
253             }
254         }
255         return retShape;
256         }
257     }
258     throw new BadLocationException JavaDoc("Position not represented by view",
259                        pos);
260     }
261
262     /**
263      * Provides a mapping from the document model coordinate space
264      * to the coordinate space of the view mapped to it.
265      *
266      * @param p0 the position to convert >= 0
267      * @param b0 the bias toward the previous character or the
268      * next character represented by p0, in case the
269      * position is a boundary of two views; either
270      * <code>Position.Bias.Forward</code> or
271      * <code>Position.Bias.Backward</code>
272      * @param p1 the position to convert >= 0
273      * @param b1 the bias toward the previous character or the
274      * next character represented by p1, in case the
275      * position is a boundary of two views
276      * @param a the allocated region to render into
277      * @return the bounding box of the given position is returned
278      * @exception BadLocationException if the given position does
279      * not represent a valid location in the associated document
280      * @exception IllegalArgumentException for an invalid bias argument
281      * @see View#viewToModel
282      */

283     public Shape modelToView(int p0, Position.Bias JavaDoc b0, int p1, Position.Bias JavaDoc b1, Shape a) throws BadLocationException JavaDoc {
284     if (p0 == getStartOffset() && p1 == getEndOffset()) {
285         return a;
286     }
287     Rectangle alloc = getInsideAllocation(a);
288     Rectangle r0 = new Rectangle(alloc);
289     View JavaDoc v0 = getViewAtPosition((b0 == Position.Bias.Backward) ?
290                     Math.max(0, p0 - 1) : p0, r0);
291     Rectangle r1 = new Rectangle(alloc);
292     View JavaDoc v1 = getViewAtPosition((b1 == Position.Bias.Backward) ?
293                     Math.max(0, p1 - 1) : p1, r1);
294     if (v0 == v1) {
295         if (v0 == null) {
296         return a;
297         }
298         // Range contained in one view
299
return v0.modelToView(p0, b0, p1, b1, r0);
300     }
301     // Straddles some views.
302
int viewCount = getViewCount();
303     int counter = 0;
304     while (counter < viewCount) {
305         View JavaDoc v;
306         // Views may not be in same order as model.
307
// v0 or v1 may be null if there is a gap in the range this
308
// view contains.
309
if ((v = getView(counter)) == v0 || v == v1) {
310         View JavaDoc endView;
311         Rectangle retRect;
312         Rectangle tempRect = new Rectangle();
313         if (v == v0) {
314             retRect = v0.modelToView(p0, b0, v0.getEndOffset(),
315                          Position.Bias.Backward, r0).
316                               getBounds();
317             endView = v1;
318         }
319         else {
320             retRect = v1.modelToView(v1.getStartOffset(),
321                          Position.Bias.Forward,
322                          p1, b1, r1).getBounds();
323             endView = v0;
324         }
325
326         // Views entirely covered by range.
327
while (++counter < viewCount &&
328                (v = getView(counter)) != endView) {
329             tempRect.setBounds(alloc);
330             childAllocation(counter, tempRect);
331             retRect.add(tempRect);
332         }
333
334         // End view.
335
if (endView != null) {
336             Shape endShape;
337             if (endView == v1) {
338             endShape = v1.modelToView(v1.getStartOffset(),
339                           Position.Bias.Forward,
340                           p1, b1, r1);
341             }
342             else {
343             endShape = v0.modelToView(p0, b0, v0.getEndOffset(),
344                           Position.Bias.Backward, r0);
345             }
346             if (endShape instanceof Rectangle) {
347             retRect.add((Rectangle)endShape);
348             }
349             else {
350             retRect.add(endShape.getBounds());
351             }
352         }
353         return retRect;
354         }
355         counter++;
356     }
357     throw new BadLocationException JavaDoc("Position not represented by view", p0);
358     }
359
360     /**
361      * Provides a mapping from the view coordinate space to the logical
362      * coordinate space of the model.
363      *
364      * @param x x coordinate of the view location to convert >= 0
365      * @param y y coordinate of the view location to convert >= 0
366      * @param a the allocated region to render into
367      * @param bias either <code>Position.Bias.Forward</code> or
368      * <code>Position.Bias.Backward</code>
369      * @return the location within the model that best represents the
370      * given point in the view >= 0
371      * @see View#viewToModel
372      */

373     public int viewToModel(float x, float y, Shape a, Position.Bias JavaDoc[] bias) {
374     Rectangle alloc = getInsideAllocation(a);
375     if (isBefore((int) x, (int) y, alloc)) {
376         // point is before the range represented
377
int retValue = -1;
378
379         try {
380         retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward,
381                              a, EAST, bias);
382         } catch (BadLocationException JavaDoc ble) { }
383         catch (IllegalArgumentException JavaDoc iae) { }
384         if(retValue == -1) {
385         retValue = getStartOffset();
386         bias[0] = Position.Bias.Forward;
387         }
388         return retValue;
389     } else if (isAfter((int) x, (int) y, alloc)) {
390         // point is after the range represented.
391
int retValue = -1;
392         try {
393         retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward,
394                              a, WEST, bias);
395         } catch (BadLocationException JavaDoc ble) { }
396         catch (IllegalArgumentException JavaDoc iae) { }
397
398         if(retValue == -1) {
399         // NOTE: this could actually use end offset with backward.
400
retValue = getEndOffset() - 1;
401         bias[0] = Position.Bias.Forward;
402         }
403         return retValue;
404     } else {
405         // locate the child and pass along the request
406
View JavaDoc v = getViewAtPoint((int) x, (int) y, alloc);
407         if (v != null) {
408           return v.viewToModel(x, y, alloc, bias);
409         }
410     }
411     return -1;
412     }
413
414     /**
415      * Provides a way to determine the next visually represented model
416      * location that one might place a caret. Some views may not be visible,
417      * they might not be in the same order found in the model, or they just
418      * might not allow access to some of the locations in the model.
419      * This is a convenience method for {@link #getNextNorthSouthVisualPositionFrom}
420      * and {@link #getNextEastWestVisualPositionFrom}.
421      *
422      * @param pos the position to convert >= 0
423      * @param b a bias value of either <code>Position.Bias.Forward</code>
424      * or <code>Position.Bias.Backward</code>
425      * @param a the allocated region to render into
426      * @param direction the direction from the current position that can
427      * be thought of as the arrow keys typically found on a keyboard;
428      * this may be one of the following:
429      * <ul>
430      * <li><code>SwingConstants.WEST</code>
431      * <li><code>SwingConstants.EAST</code>
432      * <li><code>SwingConstants.NORTH</code>
433      * <li><code>SwingConstants.SOUTH</code>
434      * </ul>
435      * @param biasRet an array containing the bias that was checked
436      * @return the location within the model that best represents the next
437      * location visual position
438      * @exception BadLocationException
439      * @exception IllegalArgumentException if <code>direction</code> is invalid
440      */

441     public int getNextVisualPositionFrom(int pos, Position.Bias JavaDoc b, Shape a,
442                      int direction, Position.Bias JavaDoc[] biasRet)
443       throws BadLocationException JavaDoc {
444         Rectangle alloc = getInsideAllocation(a);
445
446     switch (direction) {
447     case NORTH:
448         return getNextNorthSouthVisualPositionFrom(pos, b, a, direction,
449                                biasRet);
450     case SOUTH:
451         return getNextNorthSouthVisualPositionFrom(pos, b, a, direction,
452                                biasRet);
453     case EAST:
454         return getNextEastWestVisualPositionFrom(pos, b, a, direction,
455                              biasRet);
456     case WEST:
457         return getNextEastWestVisualPositionFrom(pos, b, a, direction,
458                              biasRet);
459     default:
460         throw new IllegalArgumentException JavaDoc("Bad direction: " + direction);
461     }
462     }
463
464     /**
465      * Returns the child view index representing the given
466      * position in the model. This is implemented to call the
467      * <code>getViewIndexByPosition</code>
468      * method for backward compatibility.
469      *
470      * @param pos the position >= 0
471      * @return index of the view representing the given position, or
472      * -1 if no view represents that position
473      */

474     public int getViewIndex(int pos, Position.Bias JavaDoc b) {
475     if(b == Position.Bias.Backward) {
476         pos -= 1;
477     }
478     if ((pos >= getStartOffset()) && (pos < getEndOffset())) {
479         return getViewIndexAtPosition(pos);
480     }
481     return -1;
482     }
483
484     // --- local methods ----------------------------------------------------
485

486
487     /**
488      * Tests whether a point lies before the rectangle range.
489      *
490      * @param x the X coordinate >= 0
491      * @param y the Y coordinate >= 0
492      * @param alloc the rectangle
493      * @return true if the point is before the specified range
494      */

495     protected abstract boolean isBefore(int x, int y, Rectangle alloc);
496
497     /**
498      * Tests whether a point lies after the rectangle range.
499      *
500      * @param x the X coordinate >= 0
501      * @param y the Y coordinate >= 0
502      * @param alloc the rectangle
503      * @return true if the point is after the specified range
504      */

505     protected abstract boolean isAfter(int x, int y, Rectangle alloc);
506
507     /**
508      * Fetches the child view at the given coordinates.
509      *
510      * @param x the X coordinate >= 0
511      * @param y the Y coordinate >= 0
512      * @param alloc the parent's allocation on entry, which should
513      * be changed to the child's allocation on exit
514      * @return the child view
515      */

516     protected abstract View JavaDoc getViewAtPoint(int x, int y, Rectangle alloc);
517
518     /**
519      * Returns the allocation for a given child.
520      *
521      * @param index the index of the child, >= 0 && < getViewCount()
522      * @param a the allocation to the interior of the box on entry,
523      * and the allocation of the child view at the index on exit.
524      */

525     protected abstract void childAllocation(int index, Rectangle a);
526
527     /**
528      * Fetches the child view that represents the given position in
529      * the model. This is implemented to fetch the view in the case
530      * where there is a child view for each child element.
531      *
532      * @param pos the position >= 0
533      * @param a the allocation to the interior of the box on entry,
534      * and the allocation of the view containing the position on exit
535      * @return the view representing the given position, or
536      * <code>null</code> if there isn't one
537      */

538     protected View JavaDoc getViewAtPosition(int pos, Rectangle a) {
539     int index = getViewIndexAtPosition(pos);
540     if ((index >= 0) && (index < getViewCount())) {
541         View JavaDoc v = getView(index);
542         if (a != null) {
543         childAllocation(index, a);
544         }
545         return v;
546     }
547     return null;
548     }
549
550     /**
551      * Fetches the child view index representing the given position in
552      * the model. This is implemented to fetch the view in the case
553      * where there is a child view for each child element.
554      *
555      * @param pos the position >= 0
556      * @return index of the view representing the given position, or
557      * -1 if no view represents that position
558      */

559     protected int getViewIndexAtPosition(int pos) {
560     Element JavaDoc elem = getElement();
561     return elem.getElementIndex(pos);
562     }
563
564     /**
565      * Translates the immutable allocation given to the view
566      * to a mutable allocation that represents the interior
567      * allocation (i.e. the bounds of the given allocation
568      * with the top, left, bottom, and right insets removed.
569      * It is expected that the returned value would be further
570      * mutated to represent an allocation to a child view.
571      * This is implemented to reuse an instance variable so
572      * it avoids creating excessive Rectangles. Typically
573      * the result of calling this method would be fed to
574      * the <code>childAllocation</code> method.
575      *
576      * @param a the allocation given to the view
577      * @return the allocation that represents the inside of the
578      * view after the margins have all been removed; if the
579      * given allocation was <code>null</code>,
580      * the return value is <code>null</code>
581      */

582     protected Rectangle getInsideAllocation(Shape a) {
583     if (a != null) {
584         // get the bounds, hopefully without allocating
585
// a new rectangle. The Shape argument should
586
// not be modified... we copy it into the
587
// child allocation.
588
Rectangle alloc;
589         if (a instanceof Rectangle) {
590         alloc = (Rectangle) a;
591         } else {
592         alloc = a.getBounds();
593         }
594
595         childAlloc.setBounds(alloc);
596         childAlloc.x += getLeftInset();
597         childAlloc.y += getTopInset();
598         childAlloc.width -= getLeftInset() + getRightInset();
599         childAlloc.height -= getTopInset() + getBottomInset();
600         return childAlloc;
601     }
602     return null;
603     }
604
605     /**
606      * Sets the insets from the paragraph attributes specified in
607      * the given attributes.
608      *
609      * @param attr the attributes
610      */

611     protected void setParagraphInsets(AttributeSet JavaDoc attr) {
612     // Since version 1.1 doesn't have scaling and assumes
613
// a pixel is equal to a point, we just cast the point
614
// sizes to integers.
615
top = (short) StyleConstants.getSpaceAbove(attr);
616     left = (short) StyleConstants.getLeftIndent(attr);
617     bottom = (short) StyleConstants.getSpaceBelow(attr);
618     right = (short) StyleConstants.getRightIndent(attr);
619     }
620
621     /**
622      * Sets the insets for the view.
623      *
624      * @param top the top inset >= 0
625      * @param left the left inset >= 0
626      * @param bottom the bottom inset >= 0
627      * @param right the right inset >= 0
628      */

629     protected void setInsets(short top, short left, short bottom, short right) {
630     this.top = top;
631     this.left = left;
632     this.right = right;
633     this.bottom = bottom;
634     }
635
636     /**
637      * Gets the left inset.
638      *
639      * @return the inset >= 0
640      */

641     protected short getLeftInset() {
642     return left;
643     }
644
645     /**
646      * Gets the right inset.
647      *
648      * @return the inset >= 0
649      */

650     protected short getRightInset() {
651     return right;
652     }
653
654     /**
655      * Gets the top inset.
656      *
657      * @return the inset >= 0
658      */

659     protected short getTopInset() {
660     return top;
661     }
662
663     /**
664      * Gets the bottom inset.
665      *
666      * @return the inset >= 0
667      */

668     protected short getBottomInset() {
669     return bottom;
670     }
671
672     /**
673      * Returns the next visual position for the cursor, in either the
674      * north or south direction.
675      *
676      * @param pos the position to convert >= 0
677      * @param b a bias value of either <code>Position.Bias.Forward</code>
678      * or <code>Position.Bias.Backward</code>
679      * @param a the allocated region to render into
680      * @param direction the direction from the current position that can
681      * be thought of as the arrow keys typically found on a keyboard;
682      * this may be one of the following:
683      * <ul>
684      * <li><code>SwingConstants.NORTH</code>
685      * <li><code>SwingConstants.SOUTH</code>
686      * </ul>
687      * @param biasRet an array containing the bias that was checked
688      * @return the location within the model that best represents the next
689      * north or south location
690      * @exception BadLocationException
691      * @exception IllegalArgumentException if <code>direction</code> is invalid
692      * @see #getNextVisualPositionFrom
693      *
694      * @return the next position west of the passed in position
695      */

696     protected int getNextNorthSouthVisualPositionFrom(int pos, Position.Bias JavaDoc b,
697                               Shape a, int direction,
698                               Position.Bias JavaDoc[] biasRet)
699                                             throws BadLocationException JavaDoc {
700         return Utilities.getNextVisualPositionFrom(
701                             this, pos, b, a, direction, biasRet);
702     }
703
704     /**
705      * Returns the next visual position for the cursor, in either the
706      * east or west direction.
707      *
708     * @param pos the position to convert >= 0
709      * @param b a bias value of either <code>Position.Bias.Forward</code>
710      * or <code>Position.Bias.Backward</code>
711      * @param a the allocated region to render into
712      * @param direction the direction from the current position that can
713      * be thought of as the arrow keys typically found on a keyboard;
714      * this may be one of the following:
715      * <ul>
716      * <li><code>SwingConstants.WEST</code>
717      * <li><code>SwingConstants.EAST</code>
718      * </ul>
719      * @param biasRet an array containing the bias that was checked
720      * @return the location within the model that best represents the next
721      * west or east location
722      * @exception BadLocationException
723      * @exception IllegalArgumentException if <code>direction</code> is invalid
724      * @see #getNextVisualPositionFrom
725      */

726     protected int getNextEastWestVisualPositionFrom(int pos, Position.Bias JavaDoc b,
727                             Shape a,
728                             int direction,
729                             Position.Bias JavaDoc[] biasRet)
730                                             throws BadLocationException JavaDoc {
731         return Utilities.getNextVisualPositionFrom(
732                             this, pos, b, a, direction, biasRet);
733     }
734
735     /**
736      * Determines in which direction the next view lays.
737      * Consider the <code>View</code> at index n. Typically the
738      * <code>View</code>s are layed out from left to right,
739      * so that the <code>View</code> to the EAST will be
740      * at index n + 1, and the <code>View</code> to the WEST
741      * will be at index n - 1. In certain situations,
742      * such as with bidirectional text, it is possible
743      * that the <code>View</code> to EAST is not at index n + 1,
744      * but rather at index n - 1, or that the <code>View</code>
745      * to the WEST is not at index n - 1, but index n + 1.
746      * In this case this method would return true, indicating the
747      * <code>View</code>s are layed out in descending order.
748      * <p>
749      * This unconditionally returns false, subclasses should override this
750      * method if there is the possibility for laying <code>View</code>s in
751      * descending order.
752      *
753      * @param position position into the model
754      * @param bias either <code>Position.Bias.Forward</code> or
755      * <code>Position.Bias.Backward</code>
756      * @return false
757      */

758     protected boolean flipEastAndWestAtEnds(int position,
759                         Position.Bias JavaDoc bias) {
760     return false;
761     }
762
763
764     // ---- member variables ---------------------------------------------
765

766     
767     private static View JavaDoc[] ZERO = new View JavaDoc[0];
768
769     private View JavaDoc[] children;
770     private int nchildren;
771     private short left;
772     private short right;
773     private short top;
774     private short bottom;
775     private Rectangle childAlloc;
776 }
777
Popular Tags