1 7 package javax.swing.text; 8 9 import java.awt.*; 10 import java.util.BitSet ; 11 import java.util.Vector ; 12 import javax.swing.SizeRequirements ; 13 import javax.swing.event.DocumentEvent ; 14 15 import javax.swing.text.html.HTML ; 16 17 53 public abstract class TableView extends BoxView { 54 55 60 public TableView(Element elem) { 61 super(elem, View.Y_AXIS); 62 rows = new Vector (); 63 gridValid = false; 64 } 65 66 72 protected TableRow createTableRow(Element elem) { 73 return new TableRow(elem); 74 } 75 76 84 @Deprecated 85 protected TableCell createTableCell(Element elem) { 86 return new TableCell(elem); 87 } 88 89 92 int getColumnCount() { 93 return columnSpans.length; 94 } 95 96 101 int getColumnSpan(int col) { 102 return columnSpans[col]; 103 } 104 105 108 int getRowCount() { 109 return rows.size(); 110 } 111 112 115 int getRowSpan(int row) { 116 View rv = getRow(row); 117 if (rv != null) { 118 return (int) rv.getPreferredSpan(Y_AXIS); 119 } 120 return 0; 121 } 122 123 TableRow getRow(int row) { 124 if (row < rows.size()) { 125 return (TableRow) rows.elementAt(row); 126 } 127 return null; 128 } 129 130 134 int getColumnsOccupied(View v) { 135 AttributeSet a = v.getElement().getAttributes(); 138 String s = (String ) a.getAttribute(HTML.Attribute.COLSPAN); 139 if (s != null) { 140 try { 141 return Integer.parseInt(s); 142 } catch (NumberFormatException nfe) { 143 } 145 } 146 147 return 1; 148 } 149 150 154 int getRowsOccupied(View v) { 155 AttributeSet a = v.getElement().getAttributes(); 158 String s = (String ) a.getAttribute(HTML.Attribute.ROWSPAN); 159 if (s != null) { 160 try { 161 return Integer.parseInt(s); 162 } catch (NumberFormatException nfe) { 163 } 165 } 166 167 return 1; 168 } 169 170 void invalidateGrid() { 171 gridValid = false; 172 } 173 174 protected void forwardUpdate(DocumentEvent.ElementChange ec, 175 DocumentEvent e, Shape a, ViewFactory f) { 176 super.forwardUpdate(ec, e, a, f); 177 if (a != null) { 180 Component c = getContainer(); 181 if (c != null) { 182 Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : 183 a.getBounds(); 184 c.repaint(alloc.x, alloc.y, alloc.width, alloc.height); 185 } 186 } 187 } 188 189 194 public void replace(int offset, int length, View [] views) { 195 super.replace(offset, length, views); 196 invalidateGrid(); 197 } 198 199 204 void updateGrid() { 205 if (! gridValid) { 206 rows.removeAllElements(); 209 int n = getViewCount(); 210 for (int i = 0; i < n; i++) { 211 View v = getView(i); 212 if (v instanceof TableRow) { 213 rows.addElement(v); 214 TableRow rv = (TableRow) v; 215 rv.clearFilledColumns(); 216 rv.setRow(i); 217 } 218 } 219 220 int maxColumns = 0; 221 int nrows = rows.size(); 222 for (int row = 0; row < nrows; row++) { 223 TableRow rv = getRow(row); 224 int col = 0; 225 for (int cell = 0; cell < rv.getViewCount(); cell++, col++) { 226 View cv = rv.getView(cell); 227 for (; rv.isFilled(col); col++); 229 int rowSpan = getRowsOccupied(cv); 230 int colSpan = getColumnsOccupied(cv); 231 if ((colSpan > 1) || (rowSpan > 1)) { 232 int rowLimit = row + rowSpan; 234 int colLimit = col + colSpan; 235 for (int i = row; i < rowLimit; i++) { 236 for (int j = col; j < colLimit; j++) { 237 if (i != row || j != col) { 238 addFill(i, j); 239 } 240 } 241 } 242 if (colSpan > 1) { 243 col += colSpan - 1; 244 } 245 } 246 } 247 maxColumns = Math.max(maxColumns, col); 248 } 249 250 columnSpans = new int[maxColumns]; 252 columnOffsets = new int[maxColumns]; 253 columnRequirements = new SizeRequirements [maxColumns]; 254 for (int i = 0; i < maxColumns; i++) { 255 columnRequirements[i] = new SizeRequirements (); 256 } 257 gridValid = true; 258 } 259 } 260 261 264 void addFill(int row, int col) { 265 TableRow rv = getRow(row); 266 if (rv != null) { 267 rv.fillColumn(col); 268 } 269 } 270 271 286 protected void layoutColumns(int targetSpan, int[] offsets, int[] spans, 287 SizeRequirements [] reqs) { 288 SizeRequirements.calculateTiledPositions(targetSpan, null, reqs, 290 offsets, spans); 291 } 292 293 317 protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { 318 updateGrid(); 320 321 int n = getRowCount(); 323 for (int i = 0; i < n; i++) { 324 TableRow row = getRow(i); 325 row.layoutChanged(axis); 326 } 327 328 layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements); 330 331 super.layoutMinorAxis(targetSpan, axis, offsets, spans); 333 } 334 335 343 protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) { 344 updateGrid(); 345 346 calculateColumnRequirements(axis); 348 349 350 if (r == null) { 352 r = new SizeRequirements (); 353 } 354 long min = 0; 355 long pref = 0; 356 long max = 0; 357 for (int i = 0; i < columnRequirements.length; i++) { 358 SizeRequirements req = columnRequirements[i]; 359 min += req.minimum; 360 pref += req.preferred; 361 max += req.maximum; 362 } 363 r.minimum = (int) min; 364 r.preferred = (int) pref; 365 r.maximum = (int) max; 366 r.alignment = 0; 367 return r; 368 } 369 370 380 381 395 void calculateColumnRequirements(int axis) { 396 boolean hasMultiColumn = false; 398 int nrows = getRowCount(); 399 for (int i = 0; i < nrows; i++) { 400 TableRow row = getRow(i); 401 int col = 0; 402 int ncells = row.getViewCount(); 403 for (int cell = 0; cell < ncells; cell++, col++) { 404 View cv = row.getView(cell); 405 for (; row.isFilled(col); col++); int rowSpan = getRowsOccupied(cv); 407 int colSpan = getColumnsOccupied(cv); 408 if (colSpan == 1) { 409 checkSingleColumnCell(axis, col, cv); 410 } else { 411 hasMultiColumn = true; 412 col += colSpan - 1; 413 } 414 } 415 } 416 417 if (hasMultiColumn) { 419 for (int i = 0; i < nrows; i++) { 420 TableRow row = getRow(i); 421 int col = 0; 422 int ncells = row.getViewCount(); 423 for (int cell = 0; cell < ncells; cell++, col++) { 424 View cv = row.getView(cell); 425 for (; row.isFilled(col); col++); int colSpan = getColumnsOccupied(cv); 427 if (colSpan > 1) { 428 checkMultiColumnCell(axis, col, colSpan, cv); 429 col += colSpan - 1; 430 } 431 } 432 } 433 } 434 435 443 } 444 445 448 void checkSingleColumnCell(int axis, int col, View v) { 449 SizeRequirements req = columnRequirements[col]; 450 req.minimum = Math.max((int) v.getMinimumSpan(axis), req.minimum); 451 req.preferred = Math.max((int) v.getPreferredSpan(axis), req.preferred); 452 req.maximum = Math.max((int) v.getMaximumSpan(axis), req.maximum); 453 } 454 455 459 void checkMultiColumnCell(int axis, int col, int ncols, View v) { 460 long min = 0; 462 long pref = 0; 463 long max = 0; 464 for (int i = 0; i < ncols; i++) { 465 SizeRequirements req = columnRequirements[col + i]; 466 min += req.minimum; 467 pref += req.preferred; 468 max += req.maximum; 469 } 470 471 int cmin = (int) v.getMinimumSpan(axis); 473 if (cmin > min) { 474 480 SizeRequirements [] reqs = new SizeRequirements [ncols]; 481 for (int i = 0; i < ncols; i++) { 482 SizeRequirements r = reqs[i] = columnRequirements[col + i]; 483 r.maximum = Math.max(r.maximum, (int) v.getMaximumSpan(axis)); 484 } 485 int[] spans = new int[ncols]; 486 int[] offsets = new int[ncols]; 487 SizeRequirements.calculateTiledPositions(cmin, null, reqs, 488 offsets, spans); 489 for (int i = 0; i < ncols; i++) { 491 SizeRequirements req = reqs[i]; 492 req.minimum = Math.max(spans[i], req.minimum); 493 req.preferred = Math.max(req.minimum, req.preferred); 494 req.maximum = Math.max(req.preferred, req.maximum); 495 } 496 } 497 498 int cpref = (int) v.getPreferredSpan(axis); 500 if (cpref > pref) { 501 507 SizeRequirements [] reqs = new SizeRequirements [ncols]; 508 for (int i = 0; i < ncols; i++) { 509 SizeRequirements r = reqs[i] = columnRequirements[col + i]; 510 } 511 int[] spans = new int[ncols]; 512 int[] offsets = new int[ncols]; 513 SizeRequirements.calculateTiledPositions(cpref, null, reqs, 514 offsets, spans); 515 for (int i = 0; i < ncols; i++) { 517 SizeRequirements req = reqs[i]; 518 req.preferred = Math.max(spans[i], req.preferred); 519 req.maximum = Math.max(req.preferred, req.maximum); 520 } 521 } 522 523 } 524 525 538 protected View getViewAtPosition(int pos, Rectangle a) { 539 int n = getViewCount(); 540 for (int i = 0; i < n; i++) { 541 View v = getView(i); 542 int p0 = v.getStartOffset(); 543 int p1 = v.getEndOffset(); 544 if ((pos >= p0) && (pos < p1)) { 545 if (a != null) { 547 childAllocation(i, a); 548 } 549 return v; 550 } 551 } 552 if (pos == getEndOffset()) { 553 View v = getView(n - 1); 554 if (a != null) { 555 this.childAllocation(n - 1, a); 556 } 557 return v; 558 } 559 return null; 560 } 561 562 564 int[] columnSpans; 565 int[] columnOffsets; 566 SizeRequirements [] columnRequirements; 567 Vector rows; 568 boolean gridValid; 569 static final private BitSet EMPTY = new BitSet (); 570 571 574 public class TableRow extends BoxView { 575 576 581 public TableRow(Element elem) { 582 super(elem, View.X_AXIS); 583 fillColumns = new BitSet (); 584 } 585 586 void clearFilledColumns() { 587 fillColumns.and(EMPTY); 588 } 589 590 void fillColumn(int col) { 591 fillColumns.set(col); 592 } 593 594 boolean isFilled(int col) { 595 return fillColumns.get(col); 596 } 597 598 599 int getRow() { 600 return row; 601 } 602 603 607 void setRow(int row) { 608 this.row = row; 609 } 610 611 614 int getColumnCount() { 615 int nfill = 0; 616 int n = fillColumns.size(); 617 for (int i = 0; i < n; i++) { 618 if (fillColumns.get(i)) { 619 nfill ++; 620 } 621 } 622 return getViewCount() + nfill; 623 } 624 625 630 public void replace(int offset, int length, View [] views) { 631 super.replace(offset, length, views); 632 invalidateGrid(); 633 } 634 635 656 protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { 657 int col = 0; 658 int ncells = getViewCount(); 659 for (int cell = 0; cell < ncells; cell++, col++) { 660 View cv = getView(cell); 661 for (; isFilled(col); col++); int colSpan = getColumnsOccupied(cv); 663 spans[cell] = columnSpans[col]; 664 offsets[cell] = columnOffsets[col]; 665 if (colSpan > 1) { 666 int n = columnSpans.length; 667 for (int j = 1; j < colSpan; j++) { 668 if ((col+j) < n) { 672 spans[cell] += columnSpans[col+j]; 673 } 674 } 675 col += colSpan - 1; 676 } 677 } 678 } 679 680 702 protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { 703 super.layoutMinorAxis(targetSpan, axis, offsets, spans); 704 int col = 0; 705 int ncells = getViewCount(); 706 for (int cell = 0; cell < ncells; cell++, col++) { 707 View cv = getView(cell); 708 for (; isFilled(col); col++); int colSpan = getColumnsOccupied(cv); 710 int rowSpan = getRowsOccupied(cv); 711 if (rowSpan > 1) { 712 for (int j = 1; j < rowSpan; j++) { 713 int row = getRow() + j; 717 if (row < TableView.this.getViewCount()) { 718 int span = TableView.this.getSpan(Y_AXIS, getRow()+j); 719 spans[cell] += span; 720 } 721 } 722 } 723 if (colSpan > 1) { 724 col += colSpan - 1; 725 } 726 } 727 } 728 729 737 public int getResizeWeight(int axis) { 738 return 1; 739 } 740 741 754 protected View getViewAtPosition(int pos, Rectangle a) { 755 int n = getViewCount(); 756 for (int i = 0; i < n; i++) { 757 View v = getView(i); 758 int p0 = v.getStartOffset(); 759 int p1 = v.getEndOffset(); 760 if ((pos >= p0) && (pos < p1)) { 761 if (a != null) { 763 childAllocation(i, a); 764 } 765 return v; 766 } 767 } 768 if (pos == getEndOffset()) { 769 View v = getView(n - 1); 770 if (a != null) { 771 this.childAllocation(n - 1, a); 772 } 773 return v; 774 } 775 return null; 776 } 777 778 779 BitSet fillColumns; 780 781 int row; 782 } 783 784 787 @Deprecated 788 public class TableCell extends BoxView implements GridCell { 789 790 795 public TableCell(Element elem) { 796 super(elem, View.Y_AXIS); 797 } 798 799 801 807 public int getColumnCount() { 808 return 1; 809 } 810 811 817 public int getRowCount() { 818 return 1; 819 } 820 821 822 828 public void setGridLocation(int row, int col) { 829 this.row = row; 830 this.col = col; 831 } 832 833 836 public int getGridRow() { 837 return row; 838 } 839 840 843 public int getGridColumn() { 844 return col; 845 } 846 847 int row; 848 int col; 849 } 850 851 858 interface GridCell { 859 860 866 public void setGridLocation(int row, int col); 867 868 871 public int getGridRow(); 872 873 876 public int getGridColumn(); 877 878 884 public int getColumnCount(); 885 886 892 public int getRowCount(); 893 894 } 895 896 } 897 | Popular Tags |