📄 tableview.java
字号:
/** * check the requirements of a table cell that spans multiple * columns. */ void checkMultiColumnCell(int axis, int col, int ncols, View v) { // calculate the totals long min = 0; long pref = 0; long max = 0; for (int i = 0; i < ncols; i++) { SizeRequirements req = columnRequirements[col + i]; min += req.minimum; pref += req.preferred; max += req.maximum; } // check if the minimum size needs adjustment. int cmin = (int) v.getMinimumSpan(axis); if (cmin > min) { /* * the columns that this cell spans need adjustment to fit * this table cell.... calculate the adjustments. */ SizeRequirements[] reqs = new SizeRequirements[ncols]; for (int i = 0; i < ncols; i++) { reqs[i] = columnRequirements[col + i]; } int[] spans = new int[ncols]; int[] offsets = new int[ncols]; SizeRequirements.calculateTiledPositions(cmin, null, reqs, offsets, spans); // apply the adjustments for (int i = 0; i < ncols; i++) { SizeRequirements req = reqs[i]; req.minimum = Math.max(spans[i], req.minimum); req.preferred = Math.max(req.minimum, req.preferred); req.maximum = Math.max(req.preferred, req.maximum); } } // check if the preferred size needs adjustment. int cpref = (int) v.getPreferredSpan(axis); if (cpref > pref) { /* * the columns that this cell spans need adjustment to fit * this table cell.... calculate the adjustments. */ SizeRequirements[] reqs = new SizeRequirements[ncols]; for (int i = 0; i < ncols; i++) { reqs[i] = columnRequirements[col + i]; } int[] spans = new int[ncols]; int[] offsets = new int[ncols]; SizeRequirements.calculateTiledPositions(cpref, null, reqs, offsets, spans); // apply the adjustments for (int i = 0; i < ncols; i++) { SizeRequirements req = reqs[i]; req.preferred = Math.max(spans[i], req.preferred); req.maximum = Math.max(req.preferred, req.maximum); } } } // --- BoxView methods ----------------------------------------- /** * Calculate the requirements for the minor axis. This is called by * the superclass whenever the requirements need to be updated (i.e. * a preferenceChanged was messaged through this view). * <p> * This is implemented to calculate the requirements as the sum of the * requirements of the columns and then adjust it if the * CSS width or height attribute is specified and applicable to * the axis. */ protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) { updateGrid(); // calculate column requirements for each column calculateColumnRequirements(axis); // the requirements are the sum of the columns. if (r == null) { r = new SizeRequirements(); } long min = 0; long pref = 0; int n = columnRequirements.length; for (int i = 0; i < n; i++) { SizeRequirements req = columnRequirements[i]; min += req.minimum; pref += req.preferred; } int adjust = (n + 1) * cellSpacing + 2 * borderWidth; min += adjust; pref += adjust; r.minimum = (int) min; r.preferred = (int) pref; r.maximum = (int) pref; AttributeSet attr = getAttributes(); CSS.LengthValue cssWidth = (CSS.LengthValue)attr.getAttribute( CSS.Attribute.WIDTH); if (BlockView.spanSetFromAttributes(axis, r, cssWidth, null)) { if (r.minimum < (int)min) { // The user has requested a smaller size than is needed to // show the table, override it. r.maximum = r.minimum = r.preferred = (int) min; } } totalColumnRequirements.minimum = r.minimum; totalColumnRequirements.preferred = r.preferred; totalColumnRequirements.maximum = r.maximum; // set the alignment Object o = attr.getAttribute(CSS.Attribute.TEXT_ALIGN); if (o != null) { // set horizontal alignment String ta = o.toString(); if (ta.equals("left")) { r.alignment = 0; } else if (ta.equals("center")) { r.alignment = 0.5f; } else if (ta.equals("right")) { r.alignment = 1; } else { r.alignment = 0; } } else { r.alignment = 0; } return r; } /** * Calculate the requirements for the major axis. This is called by * the superclass whenever the requirements need to be updated (i.e. * a preferenceChanged was messaged through this view). * <p> * This is implemented to provide the superclass behavior adjusted for * multi-row table cells. */ protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) { updateInsets(); rowIterator.updateAdjustments(); r = CSS.calculateTiledRequirements(rowIterator, r); r.maximum = r.preferred; return r; } /** * Perform layout for the minor axis of the box (i.e. the * axis orthoginal to the axis that it represents). The results * of the layout should be placed in the given arrays which represent * the allocations to the children along the minor axis. This * is called by the superclass whenever the layout needs to be * updated along the minor axis. * <p> * This is implemented to call the * <a href="#layoutColumns">layoutColumns</a> method, and then * forward to the superclass to actually carry out the layout * of the tables rows. * * @param targetSpan the total span given to the view, which * whould be used to layout the children * @param axis the axis being layed out * @param offsets the offsets from the origin of the view for * each of the child views. This is a return value and is * filled in by the implementation of this method * @param spans the span of each child view; this is a return * value and is filled in by the implementation of this method * @return the offset and span for each child view in the * offsets and spans parameters */ protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { // make grid is properly represented updateGrid(); // all of the row layouts are invalid, so mark them that way int n = getRowCount(); for (int i = 0; i < n; i++) { RowView row = getRow(i); row.layoutChanged(axis); } // calculate column spans layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements); // continue normal layout super.layoutMinorAxis(targetSpan, axis, offsets, spans); } /** * Perform layout for the major axis of the box (i.e. the * axis that it represents). The results * of the layout should be placed in the given arrays which represent * the allocations to the children along the minor axis. This * is called by the superclass whenever the layout needs to be * updated along the minor axis. * <p> * This method is where the layout of the table rows within the * table takes place. This method is implemented to call the use * the RowIterator and the CSS collapsing tile to layout * with border spacing and border collapsing capabilities. * * @param targetSpan the total span given to the view, which * whould be used to layout the children * @param axis the axis being layed out * @param offsets the offsets from the origin of the view for * each of the child views; this is a return value and is * filled in by the implementation of this method * @param spans the span of each child view; this is a return * value and is filled in by the implementation of this method * @return the offset and span for each child view in the * offsets and spans parameters */ protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { rowIterator.setLayoutArrays(offsets, spans); CSS.calculateTiledLayout(rowIterator, targetSpan); if (captionIndex != -1) { // place the caption View caption = getView(captionIndex); int h = (int) caption.getPreferredSpan(Y_AXIS); spans[captionIndex] = h; short boxBottom = (short) painter.getInset(BOTTOM, this); if (boxBottom != getBottomInset()) { offsets[captionIndex] = targetSpan + boxBottom; } else { offsets[captionIndex] = - getTopInset(); } } } /** * Fetches the child view that represents the given position in * the model. This is implemented to walk through the children * looking for a range that contains the given position. In this * view the children do not necessarily have a one to one mapping * with the child elements. * * @param pos the search position >= 0 * @param a the allocation to the table on entry, and the * allocation of the view containing the position on exit * @return the view representing the given position, or * null if there isn't one */ protected View getViewAtPosition(int pos, Rectangle a) { int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); int p0 = v.getStartOffset(); int p1 = v.getEndOffset(); if ((pos >= p0) && (pos < p1)) { // it's in this view. if (a != null) { childAllocation(i, a); } return v; } } if (pos == getEndOffset()) { View v = getView(n - 1); if (a != null) { this.childAllocation(n - 1, a); } return v; } return null; } // --- View methods --------------------------------------------- /** * Fetches the attributes to use when rendering. This is * implemented to multiplex the attributes specified in the * model with a StyleSheet. */ public AttributeSet getAttributes() { if (attr == null) { StyleSheet sheet = getStyleSheet(); attr = sheet.getViewAttributes(this); } return attr; } /** * Renders using the given rendering surface and area on that * surface. This is implemented to delegate to the css box * painter to paint the border and background prior to the * interior. The superclass culls rendering the children * that don't directly intersect the clip and the row may * have cells hanging from a row above in it. The table * does not use the superclass rendering behavior and instead * paints all of the rows and lets the rows cull those * cells not intersecting the clip region. * * @param g the rendering surface to use * @param allocation the allocated region to render into * @see View#paint */ public void paint(Graphics g, Shape allocation) { // paint the border Rectangle a = allocation.getBounds(); setSize(a.width, a.height); if (captionIndex != -1) { // adjust the border for the caption short top = (short) painter.getInset(TOP, this); short bottom = (short) painter.getInset(BOTTOM, this); if (top != getTopInset()) { int h = getTopInset() - top; a.y += h; a.height -= h; } else { a.height -= getBottomInset() - bottom; } } painter.paint(g, a.x, a.y, a.width, a.height, this); // paint interior int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); v.paint(g, getChildAllocation(i, allocation)); } //super.paint(g, a); } /** * Establishes the parent view for this view. This is * guaranteed to be called before any other methods if the * parent view is functioning properly. * <p> * This is implemented * to forward to the superclass as well as call the * <a href="#setPropertiesFromAttributes">setPropertiesFromAttributes</a> * method to set the paragraph properties from the css * attributes. The call is made at this time to ensure * the ability to resolve upward through the parents * view attributes. * * @param parent the new parent, or null if the view is * being removed from a parent it was previously added * to */ public void setParent(View parent) { super.setParent(parent); if (parent != null) { setPropertiesFromAttributes(); } } /** * Fetches the ViewFactory implementation that is feeding * the view hierarchy. * This replaces the ViewFactory with an implementation that * calls through to the createTableRow and createTableCell * methods. If the element given to the factory isn't a * table row or cell, the request is delegated to the factory * produced by the superclass behavior. * * @return the factory, null if none */ public ViewFactory getViewFactory() { return this; } /** * Gives notification that something was inserted into * the document in a location that this view is responsible for. * This replaces the ViewFactory with an implementation that * calls through to the createTableRow and createTableCell * methods. If the element given to the factory isn't a * table row or cell, the request is delegated to the factory * passed as an argument. * * @param e the change information from the associated document * @param a the current allocation of the view * @param f the factory to use to rebuild if the view has children * @see View#insertUpdate */ public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { super.insertUpdate(e, a, this); } /** * Gives notification that something was removed from the document * in a location that this view is responsible for. * This replaces the ViewFactory with an implementation that * calls through to the createTableRow and createTableCell * methods. If the element given to the factory isn't a * table row or cell, the request is delegated to the factory * passed as an argument. * * @param e the change information from the associated document * @param a the current allocation of the view * @param f the factory to use to rebuild if the view has children * @see View#removeUpdate */ public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { super.removeUpdate(e, a, this); } /** * Gives notification from the document that attributes were changed * in a location that this view is responsible for. * This replaces the ViewFactory with an implementation that * calls through to the createTableRow and createTableCell * methods. If the element given to the factory isn't a * table row or cell, the request is delegated to the factory * passed as an argument. * * @param e the change information from the associated document * @param a the current allocation of the view * @param f the factory to use to rebuild if the view has children * @see View#changedUpdate */ public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) { super.changedUpdate(e, a, this); } protected void forwardUpdate(DocumentEvent.ElementChange ec, DocumentEvent e, Shape a, ViewFactory f) { super.forwardUpdate(ec, e, a, f); // A change in any of the table cells usually effects the whole table, // so redraw it all! if (a != null) { Component c = getContainer(); if (c != null) { Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds(); c.repaint(alloc.x, alloc.y, alloc.width, alloc.height); } } } /** * Change the child views. This is implemented to * provide the superclass behavior and invalidate the * grid so that rows and columns will be recalculated. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -