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