?? tableview.java
字號:
public void replace(int offset, int length, View[] views) { super.replace(offset, length, views); invalidateGrid(); } // --- ViewFactory methods ------------------------------------------ /** * The table itself acts as a factory for the various * views that actually represent pieces of the table. * All other factory activity is delegated to the factory * returned by the parent of the table. */ public View create(Element elem) { Object o = elem.getAttributes().getAttribute(StyleConstants.NameAttribute); if (o instanceof HTML.Tag) { HTML.Tag kind = (HTML.Tag) o; if (kind == HTML.Tag.TR) { return createTableRow(elem); } else if ((kind == HTML.Tag.TD) || (kind == HTML.Tag.TH)) { return new CellView(elem); } else if (kind == HTML.Tag.CAPTION) { return new javax.swing.text.html.ParagraphView(elem); } } // default is to delegate to the normal factory View p = getParent(); if (p != null) { ViewFactory f = p.getViewFactory(); if (f != null) { return f.create(elem); } } return null; } // ---- variables ---------------------------------------------------- private AttributeSet attr; private StyleSheet.BoxPainter painter; private int cellSpacing; /** * The index of the caption view if there is a caption. * This has a value of -1 if there is no caption. The * caption lives in the inset area of the table, and is * updated with each time the grid is recalculated. */ private int captionIndex; /** * Do any of the table cells contain a relative size * specification? This is updated with each call to * updateGrid(). If this is true, the ColumnIterator * will do extra work to calculate relative cell * specifications. */ private boolean relativeCells; /** * Do any of the table cells span multiple rows? If * true, the RowRequirementIterator will do additional * work to adjust the requirements of rows spanned by * a single table cell. This is updated with each call to * updateGrid(). */ private boolean multiRowCells; int[] columnSpans; int[] columnOffsets; /** * SizeRequirements for all the columns. */ SizeRequirements totalColumnRequirements; SizeRequirements[] columnRequirements; RowIterator rowIterator = new RowIterator(); ColumnIterator colIterator = new ColumnIterator(); Vector rows; boolean gridValid; static final private BitSet EMPTY = new BitSet(); class ColumnIterator implements CSS.LayoutIterator { /** * Disable percentage adjustments which should only apply * when calculating layout, not requirements. */ void disablePercentages() { percentages = null; } /** * Update percentage adjustments if they are needed. */ private void updatePercentagesAndAdjustmentWeights(int span) { adjustmentWeights = new int[columnRequirements.length]; for (int i = 0; i < columnRequirements.length; i++) { adjustmentWeights[i] = 0; } if (relativeCells) { percentages = new int[columnRequirements.length]; } else { percentages = null; } int nrows = getRowCount(); for (int rowIndex = 0; rowIndex < nrows; rowIndex++) { RowView row = getRow(rowIndex); int col = 0; int ncells = row.getViewCount(); for (int cell = 0; cell < ncells; cell++, col++) { View cv = row.getView(cell); for (; row.isFilled(col); col++); // advance to a free column int rowSpan = getRowsOccupied(cv); int colSpan = getColumnsOccupied(cv); AttributeSet a = cv.getAttributes(); CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(CSS.Attribute.WIDTH); if ( lv != null ) { int len = (int) (lv.getValue(span) / colSpan + 0.5f); for (int i = 0; i < colSpan; i++) { if (lv.isPercentage()) { // add a percentage requirement percentages[col+i] = Math.max(percentages[col+i], len); } adjustmentWeights[col+i] = WorstAdjustmentWeight; } } col += colSpan - 1; } } } /** * Set the layout arrays to use for holding layout results */ public void setLayoutArrays(int offsets[], int spans[], int targetSpan) { this.offsets = offsets; this.spans = spans; updatePercentagesAndAdjustmentWeights(targetSpan); } // --- RequirementIterator methods ------------------- public int getCount() { return columnRequirements.length; } public void setIndex(int i) { col = i; } public void setOffset(int offs) { offsets[col] = offs; } public int getOffset() { return offsets[col]; } public void setSpan(int span) { spans[col] = span; } public int getSpan() { return spans[col]; } public float getMinimumSpan(float parentSpan) { if ((percentages != null) && (percentages[col] != 0)) { return Math.max(percentages[col], columnRequirements[col].minimum); } return columnRequirements[col].minimum; } public float getPreferredSpan(float parentSpan) { if ((percentages != null) && (percentages[col] != 0)) { return Math.max(percentages[col], columnRequirements[col].preferred); } return columnRequirements[col].preferred; } public float getMaximumSpan(float parentSpan) { if ((percentages != null) && (percentages[col] != 0)) { return Math.max(percentages[col], columnRequirements[col].preferred); } return columnRequirements[col].maximum; } public float getLeadingCollapseSpan() { return cellSpacing; } public float getTrailingCollapseSpan() { return cellSpacing; } public int getAdjustmentWeight() { return adjustmentWeights[col]; } /** * Current column index */ private int col; /** * percentage values (may be null since there * might not be any). */ private int[] percentages; private int[] adjustmentWeights; private int[] offsets; private int[] spans; } class RowIterator implements CSS.LayoutIterator { RowIterator() { } void updateAdjustments() { int axis = Y_AXIS; if (multiRowCells) { // adjust requirements of multi-row cells int n = getRowCount(); adjustments = new int[n]; for (int i = 0; i < n; i++) { RowView rv = getRow(i); if (rv.multiRowCells == true) { int ncells = rv.getViewCount(); for (int j = 0; j < ncells; j++) { View v = rv.getView(j); int nrows = getRowsOccupied(v); if (nrows > 1) { int spanNeeded = (int) v.getPreferredSpan(axis); adjustMultiRowSpan(spanNeeded, nrows, i); } } } } } else { adjustments = null; } } /** * Fixup preferences to accomodate a multi-row table cell * if not already covered by existing preferences. This is * a no-op if not all of the rows needed (to do this check/fixup) * have arrived yet. */ void adjustMultiRowSpan(int spanNeeded, int nrows, int rowIndex) { if ((rowIndex + nrows) > getCount()) { // rows are missing (could be a bad rowspan specification) // or not all the rows have arrived. Do the best we can with // the current set of rows. nrows = getCount() - rowIndex; if (nrows < 1) { return; } } int span = 0; for (int i = 0; i < nrows; i++) { RowView rv = getRow(rowIndex + i); span += rv.getPreferredSpan(Y_AXIS); } if (spanNeeded > span) { int adjust = (spanNeeded - span); int rowAdjust = adjust / nrows; int firstAdjust = rowAdjust + (adjust - (rowAdjust * nrows)); RowView rv = getRow(rowIndex); adjustments[rowIndex] = Math.max(adjustments[rowIndex], firstAdjust); for (int i = 1; i < nrows; i++) { adjustments[rowIndex + i] = Math.max( adjustments[rowIndex + i], rowAdjust); } } } void setLayoutArrays(int[] offsets, int[] spans) { this.offsets = offsets; this.spans = spans; } // --- RequirementIterator methods ------------------- public void setOffset(int offs) { RowView rv = getRow(row); if (rv != null) { offsets[rv.viewIndex] = offs; } } public int getOffset() { RowView rv = getRow(row); if (rv != null) { return offsets[rv.viewIndex]; } return 0; } public void setSpan(int span) { RowView rv = getRow(row); if (rv != null) { spans[rv.viewIndex] = span; } } public int getSpan() { RowView rv = getRow(row); if (rv != null) { return spans[rv.viewIndex]; } return 0; } public int getCount() { return rows.size(); } public void setIndex(int i) { row = i; } public float getMinimumSpan(float parentSpan) { return getPreferredSpan(parentSpan); } public float getPreferredSpan(float parentSpan) { RowView rv = getRow(row); if (rv != null) { int adjust = (adjustments != null) ? adjustments[row] : 0; adjust += 2 * cellSpacing; return rv.getPreferredSpan(TableView.this.getAxis()) + adjust; } return 0; } public float getMaximumSpan(float parentSpan) { return getPreferredSpan(parentSpan); } public float getLeadingCollapseSpan() { return cellSpacing; } public float getTrailingCollapseSpan() { return cellSpacing; } public int getAdjustmentWeight() { return 0; } /** * Current row index */ private int row; /** * Adjustments to the row requirements to handle multi-row * table cells. */ private int[] adjustments; private int[] offsets; private int[] spans; } /** * View of a row in a row-centric table. */ public class RowView extends BoxView { /** * Constructs a TableView for the given element. * * @param elem the element that this view is responsible for */ public RowView(Element elem) { super(elem, View.X_AXIS); fillColumns = new BitSet(); RowView.this.setPropertiesFromAttributes(); } void clearFilledColumns() { fillColumns.and(EMPTY); } void fillColumn(int col) { fillColumns.set(col); } boolean isFilled(int col) { return fillColumns.get(col); } /** * The number of columns present in this row. */ int getColumnCount() { int nfill = 0; int n = fillColumns.size(); for (int i = 0; i < n; i++) { if (fillColumns.get(i)) { nfill ++; } } return getViewCount() + nfill; } /** * Fetches the attributes to use when rendering. This is * implemented to multiplex the attributes specified in the * model with a StyleSheet. */ public AttributeSet getAttributes() { return attr; } View findViewAtPoint(int x, int y, Rectangle alloc) { int n = getViewCount(); for (int i = 0; i < n; i++) { if (getChildAllocation(i, alloc).contains(x, y)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -