History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/text/TableView.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/text/TableView.java+907−0
@@ -0,0 +1,907 @@
1/*
2 * Copyright (c) 1997, 2011, 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
23 * questions.
24 */
25package javax.swing.text;
26
27import java.awt.*;
28import java.util.BitSet;
29import java.util.Vector;
30import javax.swing.SizeRequirements;
31import javax.swing.event.DocumentEvent;
32
33import javax.swing.text.html.HTML;
34
35/**
36 * <p>
37 * Implements View interface for a table, that is composed of an
38 * element structure where the child elements of the element
39 * this view is responsible for represent rows and the child
40 * elements of the row elements are cells. The cell elements can
41 * have an arbitrary element structure under them, which will
42 * be built with the ViewFactory returned by the getViewFactory
43 * method.
44 * <pre>
45 *
46 * &nbsp; TABLE
47 * &nbsp; ROW
48 * &nbsp; CELL
49 * &nbsp; CELL
50 * &nbsp; ROW
51 * &nbsp; CELL
52 * &nbsp; CELL
53 *
54 * </pre>
55 * <p>
56 * This is implemented as a hierarchy of boxes, the table itself
57 * is a vertical box, the rows are horizontal boxes, and the cells
58 * are vertical boxes. The cells are allowed to span multiple
59 * columns and rows. By default, the table can be thought of as
60 * being formed over a grid (i.e. somewhat like one would find in
61 * gridbag layout), where table cells can request to span more
62 * than one grid cell. The default horizontal span of table cells
63 * will be based upon this grid, but can be changed by reimplementing
64 * the requested span of the cell (i.e. table cells can have independant
65 * spans if desired).
66 *
67 * @author Timothy Prinzing
68 * @see View
69 */
70public abstract class TableView extends BoxView {
71
72 /**
73 * Constructs a TableView for the given element.
74 *
75 * @param elem the element that this view is responsible for
76 */
77 public TableView(Element elem) {
78 super(elem, View.Y_AXIS);
79 rows = new Vector<TableRow>();
80 gridValid = false;
81 }
82
83 /**
84 * Creates a new table row.
85 *
86 * @param elem an element
87 * @return the row
88 */
89 protected TableRow createTableRow(Element elem) {
90 return new TableRow(elem);
91 }
92
93 /**
94 * @deprecated Table cells can now be any arbitrary
95 * View implementation and should be produced by the
96 * ViewFactory rather than the table.
97 *
98 * @param elem an element
99 * @return the cell
100 */
101 @Deprecated
102 protected TableCell createTableCell(Element elem) {
103 return new TableCell(elem);
104 }
105
106 /**
107 * The number of columns in the table.
108 */
109 int getColumnCount() {
110 return columnSpans.length;
111 }
112
113 /**
114 * Fetches the span (width) of the given column.
115 * This is used by the nested cells to query the
116 * sizes of grid locations outside of themselves.
117 */
118 int getColumnSpan(int col) {
119 return columnSpans[col];
120 }
121
122 /**
123 * The number of rows in the table.
124 */
125 int getRowCount() {
126 return rows.size();
127 }
128
129 /**
130 * Fetches the span (height) of the given row.
131 */
132 int getRowSpan(int row) {
133 View rv = getRow(row);
134 if (rv != null) {
135 return (int) rv.getPreferredSpan(Y_AXIS);
136 }
137 return 0;
138 }
139
140 TableRow getRow(int row) {
141 if (row < rows.size()) {
142 return rows.elementAt(row);
143 }
144 return null;
145 }
146
147 /**
148 * Determines the number of columns occupied by
149 * the table cell represented by given element.
150 */
151 /*protected*/ int getColumnsOccupied(View v) {
152 // PENDING(prinz) this code should be in the html
153 // paragraph, but we can't add api to enable it.
154 AttributeSet a = v.getElement().getAttributes();
155 String s = (String) a.getAttribute(HTML.Attribute.COLSPAN);
156 if (s != null) {
157 try {
158 return Integer.parseInt(s);
159 } catch (NumberFormatException nfe) {
160 // fall through to one column
161 }
162 }
163
164 return 1;
165 }
166
167 /**
168 * Determines the number of rows occupied by
169 * the table cell represented by given element.
170 */
171 /*protected*/ int getRowsOccupied(View v) {
172 // PENDING(prinz) this code should be in the html
173 // paragraph, but we can't add api to enable it.
174 AttributeSet a = v.getElement().getAttributes();
175 String s = (String) a.getAttribute(HTML.Attribute.ROWSPAN);
176 if (s != null) {
177 try {
178 return Integer.parseInt(s);
179 } catch (NumberFormatException nfe) {
180 // fall through to one row
181 }
182 }
183
184 return 1;
185 }
186
187 /*protected*/ void invalidateGrid() {
188 gridValid = false;
189 }
190
191 protected void forwardUpdate(DocumentEvent.ElementChange ec,
192 DocumentEvent e, Shape a, ViewFactory f) {
193 super.forwardUpdate(ec, e, a, f);
194 // A change in any of the table cells usually effects the whole table,
195 // so redraw it all!
196 if (a != null) {
197 Component c = getContainer();
198 if (c != null) {
199 Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a :
200 a.getBounds();
201 c.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
202 }
203 }
204 }
205
206 /**
207 * Change the child views. This is implemented to
208 * provide the superclass behavior and invalidate the
209 * grid so that rows and columns will be recalculated.
210 */
211 public void replace(int offset, int length, View[] views) {
212 super.replace(offset, length, views);
213 invalidateGrid();
214 }
215
216 /**
217 * Fill in the grid locations that are placeholders
218 * for multi-column, multi-row, and missing grid
219 * locations.
220 */
221 void updateGrid() {
222 if (! gridValid) {
223 // determine which views are table rows and clear out
224 // grid points marked filled.
225 rows.removeAllElements();
226 int n = getViewCount();
227 for (int i = 0; i < n; i++) {
228 View v = getView(i);
229 if (v instanceof TableRow) {
230 rows.addElement((TableRow) v);
231 TableRow rv = (TableRow) v;
232 rv.clearFilledColumns();
233 rv.setRow(i);
234 }
235 }
236
237 int maxColumns = 0;
238 int nrows = rows.size();
239 for (int row = 0; row < nrows; row++) {
240 TableRow rv = getRow(row);
241 int col = 0;
242 for (int cell = 0; cell < rv.getViewCount(); cell++, col++) {
243 View cv = rv.getView(cell);
244 // advance to a free column
245 for (; rv.isFilled(col); col++);
246 int rowSpan = getRowsOccupied(cv);
247 int colSpan = getColumnsOccupied(cv);
248 if ((colSpan > 1) || (rowSpan > 1)) {
249 // fill in the overflow entries for this cell
250 int rowLimit = row + rowSpan;
251 int colLimit = col + colSpan;
252 for (int i = row; i < rowLimit; i++) {
253 for (int j = col; j < colLimit; j++) {
254 if (i != row || j != col) {
255 addFill(i, j);
256 }
257 }
258 }
259 if (colSpan > 1) {
260 col += colSpan - 1;
261 }
262 }
263 }
264 maxColumns = Math.max(maxColumns, col);
265 }
266
267 // setup the column layout/requirements
268 columnSpans = new int[maxColumns];
269 columnOffsets = new int[maxColumns];
270 columnRequirements = new SizeRequirements[maxColumns];
271 for (int i = 0; i < maxColumns; i++) {
272 columnRequirements[i] = new SizeRequirements();
273 }
274 gridValid = true;
275 }
276 }
277
278 /**
279 * Mark a grid location as filled in for a cells overflow.
280 */
281 void addFill(int row, int col) {
282 TableRow rv = getRow(row);
283 if (rv != null) {
284 rv.fillColumn(col);
285 }
286 }
287
288 /**
289 * Lays out the columns to fit within the given target span.
290 * Returns the results through {@code offsets} and {@code spans}.
291 *
292 * @param targetSpan the given span for total of all the table
293 * columns
294 * @param reqs the requirements desired for each column. This
295 * is the column maximum of the cells minimum, preferred, and
296 * maximum requested span
297 * @param spans the return value of how much to allocated to
298 * each column
299 * @param offsets the return value of the offset from the
300 * origin for each column
301 */
302 protected void layoutColumns(int targetSpan, int[] offsets, int[] spans,
303 SizeRequirements[] reqs) {
304 // allocate using the convenience method on SizeRequirements
305 SizeRequirements.calculateTiledPositions(targetSpan, null, reqs,
306 offsets, spans);
307 }
308
309 /**
310 * Perform layout for the minor axis of the box (i.e. the
311 * axis orthoginal to the axis that it represents). The results
312 * of the layout should be placed in the given arrays which represent
313 * the allocations to the children along the minor axis. This
314 * is called by the superclass whenever the layout needs to be
315 * updated along the minor axis.
316 * <p>
317 * This is implemented to call the
318 * {@link #layoutColumns layoutColumns} method, and then
319 * forward to the superclass to actually carry out the layout
320 * of the tables rows.
321 *
322 * @param targetSpan the total span given to the view, which
323 * whould be used to layout the children.
324 * @param axis the axis being layed out.
325 * @param offsets the offsets from the origin of the view for
326 * each of the child views. This is a return value and is
327 * filled in by the implementation of this method.
328 * @param spans the span of each child view. This is a return
329 * value and is filled in by the implementation of this method.
330 */
331 protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
332 // make grid is properly represented
333 updateGrid();
334
335 // all of the row layouts are invalid, so mark them that way
336 int n = getRowCount();
337 for (int i = 0; i < n; i++) {
338 TableRow row = getRow(i);
339 row.layoutChanged(axis);
340 }
341
342 // calculate column spans
343 layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements);
344
345 // continue normal layout
346 super.layoutMinorAxis(targetSpan, axis, offsets, spans);
347 }
348
349 /**
350 * Calculate the requirements for the minor axis. This is called by
351 * the superclass whenever the requirements need to be updated (i.e.
352 * a preferenceChanged was messaged through this view).
353 * <p>
354 * This is implemented to calculate the requirements as the sum of the
355 * requirements of the columns.
356 */
357 protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
358 updateGrid();
359
360 // calculate column requirements for each column
361 calculateColumnRequirements(axis);
362
363
364 // the requirements are the sum of the columns.
365 if (r == null) {
366 r = new SizeRequirements();
367 }
368 long min = 0;
369 long pref = 0;
370 long max = 0;
371 for (SizeRequirements req : columnRequirements) {
372 min += req.minimum;
373 pref += req.preferred;
374 max += req.maximum;
375 }
376 r.minimum = (int) min;
377 r.preferred = (int) pref;
378 r.maximum = (int) max;
379 r.alignment = 0;
380 return r;
381 }
382
383 /*
384 boolean shouldTrace() {
385 AttributeSet a = getElement().getAttributes();
386 Object o = a.getAttribute(HTML.Attribute.ID);
387 if ((o != null) && o.equals("debug")) {
388 return true;
389 }
390 return false;
391 }
392 */
393
394 /**
395 * Calculate the requirements for each column. The calculation
396 * is done as two passes over the table. The table cells that
397 * occupy a single column are scanned first to determine the
398 * maximum of minimum, preferred, and maximum spans along the
399 * give axis. Table cells that span multiple columns are excluded
400 * from the first pass. A second pass is made to determine if
401 * the cells that span multiple columns are satisfied. If the
402 * column requirements are not satisified, the needs of the
403 * multi-column cell is mixed into the existing column requirements.
404 * The calculation of the multi-column distribution is based upon
405 * the proportions of the existing column requirements and taking
406 * into consideration any constraining maximums.
407 */
408 void calculateColumnRequirements(int axis) {
409 // pass 1 - single column cells
410 boolean hasMultiColumn = false;
411 int nrows = getRowCount();
412 for (int i = 0; i < nrows; i++) {
413 TableRow row = getRow(i);
414 int col = 0;
415 int ncells = row.getViewCount();
416 for (int cell = 0; cell < ncells; cell++, col++) {
417 View cv = row.getView(cell);
418 for (; row.isFilled(col); col++); // advance to a free column
419 int rowSpan = getRowsOccupied(cv);
420 int colSpan = getColumnsOccupied(cv);
421 if (colSpan == 1) {
422 checkSingleColumnCell(axis, col, cv);
423 } else {
424 hasMultiColumn = true;
425 col += colSpan - 1;
426 }
427 }
428 }
429
430 // pass 2 - multi-column cells
431 if (hasMultiColumn) {
432 for (int i = 0; i < nrows; i++) {
433 TableRow row = getRow(i);
434 int col = 0;
435 int ncells = row.getViewCount();
436 for (int cell = 0; cell < ncells; cell++, col++) {
437 View cv = row.getView(cell);
438 for (; row.isFilled(col); col++); // advance to a free column
439 int colSpan = getColumnsOccupied(cv);
440 if (colSpan > 1) {
441 checkMultiColumnCell(axis, col, colSpan, cv);
442 col += colSpan - 1;
443 }
444 }
445 }
446 }
447
448 /*
449 if (shouldTrace()) {
450 System.err.println("calc:");
451 for (int i = 0; i < columnRequirements.length; i++) {
452 System.err.println(" " + i + ": " + columnRequirements[i]);
453 }
454 }
455 */
456 }
457
458 /**
459 * check the requirements of a table cell that spans a single column.
460 */
461 void checkSingleColumnCell(int axis, int col, View v) {
462 SizeRequirements req = columnRequirements[col];
463 req.minimum = Math.max((int) v.getMinimumSpan(axis), req.minimum);
464 req.preferred = Math.max((int) v.getPreferredSpan(axis), req.preferred);
465 req.maximum = Math.max((int) v.getMaximumSpan(axis), req.maximum);
466 }
467
468 /**
469 * check the requirements of a table cell that spans multiple
470 * columns.
471 */
472 void checkMultiColumnCell(int axis, int col, int ncols, View v) {
473 // calculate the totals
474 long min = 0;
475 long pref = 0;
476 long max = 0;
477 for (int i = 0; i < ncols; i++) {
478 SizeRequirements req = columnRequirements[col + i];
479 min += req.minimum;
480 pref += req.preferred;
481 max += req.maximum;
482 }
483
484 // check if the minimum size needs adjustment.
485 int cmin = (int) v.getMinimumSpan(axis);
486 if (cmin > min) {
487 /*
488 * the columns that this cell spans need adjustment to fit
489 * this table cell.... calculate the adjustments. The
490 * maximum for each cell is the maximum of the existing
491 * maximum or the amount needed by the cell.
492 */
493 SizeRequirements[] reqs = new SizeRequirements[ncols];
494 for (int i = 0; i < ncols; i++) {
495 SizeRequirements r = reqs[i] = columnRequirements[col + i];
496 r.maximum = Math.max(r.maximum, (int) v.getMaximumSpan(axis));
497 }
498 int[] spans = new int[ncols];
499 int[] offsets = new int[ncols];
500 SizeRequirements.calculateTiledPositions(cmin, null, reqs,
501 offsets, spans);
502 // apply the adjustments
503 for (int i = 0; i < ncols; i++) {
504 SizeRequirements req = reqs[i];
505 req.minimum = Math.max(spans[i], req.minimum);
506 req.preferred = Math.max(req.minimum, req.preferred);
507 req.maximum = Math.max(req.preferred, req.maximum);
508 }
509 }
510
511 // check if the preferred size needs adjustment.
512 int cpref = (int) v.getPreferredSpan(axis);
513 if (cpref > pref) {
514 /*
515 * the columns that this cell spans need adjustment to fit
516 * this table cell.... calculate the adjustments. The
517 * maximum for each cell is the maximum of the existing
518 * maximum or the amount needed by the cell.
519 */
520 SizeRequirements[] reqs = new SizeRequirements[ncols];
521 for (int i = 0; i < ncols; i++) {
522 SizeRequirements r = reqs[i] = columnRequirements[col + i];
523 }
524 int[] spans = new int[ncols];
525 int[] offsets = new int[ncols];
526 SizeRequirements.calculateTiledPositions(cpref, null, reqs,
527 offsets, spans);
528 // apply the adjustments
529 for (int i = 0; i < ncols; i++) {
530 SizeRequirements req = reqs[i];
531 req.preferred = Math.max(spans[i], req.preferred);
532 req.maximum = Math.max(req.preferred, req.maximum);
533 }
534 }
535
536 }
537
538 /**
539 * Fetches the child view that represents the given position in
540 * the model. This is implemented to walk through the children
541 * looking for a range that contains the given position. In this
542 * view the children do not necessarily have a one to one mapping
543 * with the child elements.
544 *
545 * @param pos the search position >= 0
546 * @param a the allocation to the table on entry, and the
547 * allocation of the view containing the position on exit
548 * @return the view representing the given position, or
549 * <code>null</code> if there isn't one
550 */
551 protected View getViewAtPosition(int pos, Rectangle a) {
552 int n = getViewCount();
553 for (int i = 0; i < n; i++) {
554 View v = getView(i);
555 int p0 = v.getStartOffset();
556 int p1 = v.getEndOffset();
557 if ((pos >= p0) && (pos < p1)) {
558 // it's in this view.
559 if (a != null) {
560 childAllocation(i, a);
561 }
562 return v;
563 }
564 }
565 if (pos == getEndOffset()) {
566 View v = getView(n - 1);
567 if (a != null) {
568 this.childAllocation(n - 1, a);
569 }
570 return v;
571 }
572 return null;
573 }
574
575 // ---- variables ----------------------------------------------------
576
577 int[] columnSpans;
578 int[] columnOffsets;
579 SizeRequirements[] columnRequirements;
580 Vector<TableRow> rows;
581 boolean gridValid;
582 static final private BitSet EMPTY = new BitSet();
583
584 /**
585 * View of a row in a row-centric table.
586 */
587 public class TableRow extends BoxView {
588
589 /**
590 * Constructs a TableView for the given element.
591 *
592 * @param elem the element that this view is responsible for
593 * @since 1.4
594 */
595 public TableRow(Element elem) {
596 super(elem, View.X_AXIS);
597 fillColumns = new BitSet();
598 }
599
600 void clearFilledColumns() {
601 fillColumns.and(EMPTY);
602 }
603
604 void fillColumn(int col) {
605 fillColumns.set(col);
606 }
607
608 boolean isFilled(int col) {
609 return fillColumns.get(col);
610 }
611
612 /** get location in the overall set of rows */
613 int getRow() {
614 return row;
615 }
616
617 /**
618 * set location in the overall set of rows, this is
619 * set by the TableView.updateGrid() method.
620 */
621 void setRow(int row) {
622 this.row = row;
623 }
624
625 /**
626 * The number of columns present in this row.
627 */
628 int getColumnCount() {
629 int nfill = 0;
630 int n = fillColumns.size();
631 for (int i = 0; i < n; i++) {
632 if (fillColumns.get(i)) {
633 nfill ++;
634 }
635 }
636 return getViewCount() + nfill;
637 }
638
639 /**
640 * Change the child views. This is implemented to
641 * provide the superclass behavior and invalidate the
642 * grid so that rows and columns will be recalculated.
643 */
644 public void replace(int offset, int length, View[] views) {
645 super.replace(offset, length, views);
646 invalidateGrid();
647 }
648
649 /**
650 * Perform layout for the major axis of the box (i.e. the
651 * axis that it represents). The results of the layout should
652 * be placed in the given arrays which represent the allocations
653 * to the children along the major axis.
654 * <p>
655 * This is re-implemented to give each child the span of the column
656 * width for the table, and to give cells that span multiple columns
657 * the multi-column span.
658 *
659 * @param targetSpan the total span given to the view, which
660 * whould be used to layout the children.
661 * @param axis the axis being layed out.
662 * @param offsets the offsets from the origin of the view for
663 * each of the child views. This is a return value and is
664 * filled in by the implementation of this method.
665 * @param spans the span of each child view. This is a return
666 * value and is filled in by the implementation of this method.
667 */
668 protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
669 int col = 0;
670 int ncells = getViewCount();
671 for (int cell = 0; cell < ncells; cell++, col++) {
672 View cv = getView(cell);
673 for (; isFilled(col); col++); // advance to a free column
674 int colSpan = getColumnsOccupied(cv);
675 spans[cell] = columnSpans[col];
676 offsets[cell] = columnOffsets[col];
677 if (colSpan > 1) {
678 int n = columnSpans.length;
679 for (int j = 1; j < colSpan; j++) {
680 // Because the table may be only partially formed, some
681 // of the columns may not yet exist. Therefore we check
682 // the bounds.
683 if ((col+j) < n) {
684 spans[cell] += columnSpans[col+j];
685 }
686 }
687 col += colSpan - 1;
688 }
689 }
690 }
691
692 /**
693 * Perform layout for the minor axis of the box (i.e. the
694 * axis orthoginal to the axis that it represents). The results
695 * of the layout should be placed in the given arrays which represent
696 * the allocations to the children along the minor axis. This
697 * is called by the superclass whenever the layout needs to be
698 * updated along the minor axis.
699 * <p>
700 * This is implemented to delegate to the superclass, then adjust
701 * the span for any cell that spans multiple rows.
702 *
703 * @param targetSpan the total span given to the view, which
704 * whould be used to layout the children.
705 * @param axis the axis being layed out.
706 * @param offsets the offsets from the origin of the view for
707 * each of the child views. This is a return value and is
708 * filled in by the implementation of this method.
709 * @param spans the span of each child view. This is a return
710 * value and is filled in by the implementation of this method.
711 */
712 protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
713 super.layoutMinorAxis(targetSpan, axis, offsets, spans);
714 int col = 0;
715 int ncells = getViewCount();
716 for (int cell = 0; cell < ncells; cell++, col++) {
717 View cv = getView(cell);
718 for (; isFilled(col); col++); // advance to a free column
719 int colSpan = getColumnsOccupied(cv);
720 int rowSpan = getRowsOccupied(cv);
721 if (rowSpan > 1) {
722 for (int j = 1; j < rowSpan; j++) {
723 // test bounds of each row because it may not exist
724 // either because of error or because the table isn't
725 // fully loaded yet.
726 int row = getRow() + j;
727 if (row < TableView.this.getViewCount()) {
728 int span = TableView.this.getSpan(Y_AXIS, getRow()+j);
729 spans[cell] += span;
730 }
731 }
732 }
733 if (colSpan > 1) {
734 col += colSpan - 1;
735 }
736 }
737 }
738
739 /**
740 * Determines the resizability of the view along the
741 * given axis. A value of 0 or less is not resizable.
742 *
743 * @param axis may be either View.X_AXIS or View.Y_AXIS
744 * @return the resize weight
745 * @exception IllegalArgumentException for an invalid axis
746 */
747 public int getResizeWeight(int axis) {
748 return 1;
749 }
750
751 /**
752 * Fetches the child view that represents the given position in
753 * the model. This is implemented to walk through the children
754 * looking for a range that contains the given position. In this
755 * view the children do not necessarily have a one to one mapping
756 * with the child elements.
757 *
758 * @param pos the search position >= 0
759 * @param a the allocation to the table on entry, and the
760 * allocation of the view containing the position on exit
761 * @return the view representing the given position, or
762 * <code>null</code> if there isn't one
763 */
764 protected View getViewAtPosition(int pos, Rectangle a) {
765 int n = getViewCount();
766 for (int i = 0; i < n; i++) {
767 View v = getView(i);
768 int p0 = v.getStartOffset();
769 int p1 = v.getEndOffset();
770 if ((pos >= p0) && (pos < p1)) {
771 // it's in this view.
772 if (a != null) {
773 childAllocation(i, a);
774 }
775 return v;
776 }
777 }
778 if (pos == getEndOffset()) {
779 View v = getView(n - 1);
780 if (a != null) {
781 this.childAllocation(n - 1, a);
782 }
783 return v;
784 }
785 return null;
786 }
787
788 /** columns filled by multi-column or multi-row cells */
789 BitSet fillColumns;
790 /** the row within the overall grid */
791 int row;
792 }
793
794 /**
795 * @deprecated A table cell can now be any View implementation.
796 */
797 @Deprecated
798 public class TableCell extends BoxView implements GridCell {
799
800 /**
801 * Constructs a TableCell for the given element.
802 *
803 * @param elem the element that this view is responsible for
804 * @since 1.4
805 */
806 public TableCell(Element elem) {
807 super(elem, View.Y_AXIS);
808 }
809
810 // --- GridCell methods -------------------------------------
811
812 /**
813 * Gets the number of columns this cell spans (e.g. the
814 * grid width).
815 *
816 * @return the number of columns
817 */
818 public int getColumnCount() {
819 return 1;
820 }
821
822 /**
823 * Gets the number of rows this cell spans (that is, the
824 * grid height).
825 *
826 * @return the number of rows
827 */
828 public int getRowCount() {
829 return 1;
830 }
831
832
833 /**
834 * Sets the grid location.
835 *
836 * @param row the row >= 0
837 * @param col the column >= 0
838 */
839 public void setGridLocation(int row, int col) {
840 this.row = row;
841 this.col = col;
842 }
843
844 /**
845 * Gets the row of the grid location
846 */
847 public int getGridRow() {
848 return row;
849 }
850
851 /**
852 * Gets the column of the grid location
853 */
854 public int getGridColumn() {
855 return col;
856 }
857
858 int row;
859 int col;
860 }
861
862 /**
863 * <em>
864 * THIS IS NO LONGER USED, AND WILL BE REMOVED IN THE
865 * NEXT RELEASE. THE JCK SIGNATURE TEST THINKS THIS INTERFACE
866 * SHOULD EXIST
867 * </em>
868 */
869 interface GridCell {
870
871 /**
872 * Sets the grid location.
873 *
874 * @param row the row >= 0
875 * @param col the column >= 0
876 */
877 public void setGridLocation(int row, int col);
878
879 /**
880 * Gets the row of the grid location
881 */
882 public int getGridRow();
883
884 /**
885 * Gets the column of the grid location
886 */
887 public int getGridColumn();
888
889 /**
890 * Gets the number of columns this cell spans (e.g. the
891 * grid width).
892 *
893 * @return the number of columns
894 */
895 public int getColumnCount();
896
897 /**
898 * Gets the number of rows this cell spans (that is, the
899 * grid height).
900 *
901 * @return the number of rows
902 */
903 public int getRowCount();
904
905 }
906
907}