Methods Summary |
---|
void | addFill(int row, int col)Mark a grid location as filled in for a cells overflow.
RowView rv = getRow(row);
if (rv != null) {
rv.fillColumn(col);
}
|
void | calculateColumnRequirements(int axis)Calculate the requirements for each column. The calculation
is done as two passes over the table. The table cells that
occupy a single column are scanned first to determine the
maximum of minimum, preferred, and maximum spans along the
give axis. Table cells that span multiple columns are excluded
from the first pass. A second pass is made to determine if
the cells that span multiple columns are satisfied. If the
column requirements are not satisified, the needs of the
multi-column cell is mixed into the existing column requirements.
The calculation of the multi-column distribution is based upon
the proportions of the existing column requirements and taking
into consideration any constraining maximums.
Container host = getContainer();
if (host != null) {
if (host instanceof JTextComponent) {
skipComments = !((JTextComponent)host).isEditable();
} else {
skipComments = true;
}
}
// pass 1 - single column cells
boolean hasMultiColumn = false;
int nrows = getRowCount();
for (int i = 0; i < nrows; i++) {
RowView row = getRow(i);
int col = 0;
int ncells = row.getViewCount();
for (int cell = 0; cell < ncells; cell++) {
View cv = row.getView(cell);
if (skipComments && !(cv instanceof CellView)) {
continue;
}
for (; row.isFilled(col); col++); // advance to a free column
int rowSpan = getRowsOccupied(cv);
int colSpan = getColumnsOccupied(cv);
if (colSpan == 1) {
checkSingleColumnCell(axis, col, cv);
} else {
hasMultiColumn = true;
col += colSpan - 1;
}
col++;
}
}
// pass 2 - multi-column cells
if (hasMultiColumn) {
for (int i = 0; i < nrows; i++) {
RowView row = getRow(i);
int col = 0;
int ncells = row.getViewCount();
for (int cell = 0; cell < ncells; cell++) {
View cv = row.getView(cell);
if (skipComments && !(cv instanceof CellView)) {
continue;
}
for (; row.isFilled(col); col++); // advance to a free column
int colSpan = getColumnsOccupied(cv);
if (colSpan > 1) {
checkMultiColumnCell(axis, col, colSpan, cv);
col += colSpan - 1;
}
col++;
}
}
}
|
protected javax.swing.SizeRequirements | calculateMajorAxisRequirements(int axis, javax.swing.SizeRequirements 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).
This is implemented to provide the superclass behavior adjusted for
multi-row table cells.
updateInsets();
rowIterator.updateAdjustments();
r = CSS.calculateTiledRequirements(rowIterator, r);
r.maximum = r.preferred;
return r;
|
protected javax.swing.SizeRequirements | calculateMinorAxisRequirements(int axis, javax.swing.SizeRequirements r)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).
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.
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;
|
public void | changedUpdate(javax.swing.event.DocumentEvent e, java.awt.Shape a, javax.swing.text.ViewFactory f)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.
super.changedUpdate(e, a, this);
|
void | checkMultiColumnCell(int axis, int col, int ncols, javax.swing.text.View v)check the requirements of a table cell that spans multiple
columns.
// 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);
}
}
|
void | checkSingleColumnCell(int axis, int col, javax.swing.text.View v)check the requirements of a table cell that spans a single column.
SizeRequirements req = columnRequirements[col];
req.minimum = Math.max((int) v.getMinimumSpan(axis), req.minimum);
req.preferred = Math.max((int) v.getPreferredSpan(axis), req.preferred);
|
public javax.swing.text.View | create(javax.swing.text.Element elem)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.
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;
|
protected javax.swing.text.html.TableView$RowView | createTableRow(javax.swing.text.Element elem)Creates a new table row.
// PENDING(prinz) need to add support for some of the other
// elements, but for now just ignore anything that is not
// a TR.
Object o = elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
if (o == HTML.Tag.TR) {
return new RowView(elem);
}
return null;
|
protected void | forwardUpdate(javax.swing.event.DocumentEvent$ElementChange ec, javax.swing.event.DocumentEvent e, java.awt.Shape a, javax.swing.text.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);
}
}
|
public javax.swing.text.AttributeSet | getAttributes()Fetches the attributes to use when rendering. This is
implemented to multiplex the attributes specified in the
model with a StyleSheet.
if (attr == null) {
StyleSheet sheet = getStyleSheet();
attr = sheet.getViewAttributes(this);
}
return attr;
|
public int | getColumnCount()The number of columns in the table.
return columnSpans.length;
|
public int | getColumnSpan(int col)Fetches the span (width) of the given column.
This is used by the nested cells to query the
sizes of grid locations outside of themselves.
if (col < columnSpans.length) {
return columnSpans[col];
}
return 0;
|
protected int | getColumnsOccupied(javax.swing.text.View v)Determines the number of columns occupied by
the table cell represented by given element.
AttributeSet a = v.getElement().getAttributes();
if (a.isDefined(HTML.Attribute.COLSPAN)) {
String s = (String) a.getAttribute(HTML.Attribute.COLSPAN);
if (s != null) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException nfe) {
// fall through to one column
}
}
}
return 1;
|
public int | getMultiRowSpan(int row0, int row1)Fetch the span of multiple rows. This includes
the border area.
RowView rv0 = getRow(row0);
RowView rv1 = getRow(row1);
if ((rv0 != null) && (rv1 != null)) {
int index0 = rv0.viewIndex;
int index1 = rv1.viewIndex;
int span = getOffset(Y_AXIS, index1) - getOffset(Y_AXIS, index0) +
getSpan(Y_AXIS, index1);
return span;
}
return 0;
|
javax.swing.text.html.TableView$RowView | getRow(int row)
if (row < rows.size()) {
return (RowView) rows.elementAt(row);
}
return null;
|
public int | getRowCount()The number of rows in the table.
return rows.size();
|
public int | getRowSpan(int row)Fetches the span (height) of the given row.
RowView rv = getRow(row);
if (rv != null) {
return getSpan(Y_AXIS, rv.viewIndex);
}
return 0;
|
protected int | getRowsOccupied(javax.swing.text.View v)Determines the number of rows occupied by
the table cell represented by given element.
AttributeSet a = v.getElement().getAttributes();
if (a.isDefined(HTML.Attribute.ROWSPAN)) {
String s = (String) a.getAttribute(HTML.Attribute.ROWSPAN);
if (s != null) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException nfe) {
// fall through to one row
}
}
}
return 1;
|
protected javax.swing.text.html.StyleSheet | getStyleSheet()
HTMLDocument doc = (HTMLDocument) getDocument();
return doc.getStyleSheet();
|
protected javax.swing.text.View | getViewAtPoint(int x, int y, java.awt.Rectangle alloc)
int n = getViewCount();
View v = null;
Rectangle allocation = new Rectangle();
for (int i = 0; i < n; i++) {
allocation.setBounds(alloc);
childAllocation(i, allocation);
v = getView(i);
if (v instanceof RowView) {
v = ((RowView)v).findViewAtPoint(x, y, allocation);
if (v != null) {
alloc.setBounds(allocation);
return v;
}
}
}
return super.getViewAtPoint(x, y, alloc);
|
protected javax.swing.text.View | getViewAtPosition(int pos, java.awt.Rectangle a)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.
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;
|
public javax.swing.text.ViewFactory | getViewFactory()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 this;
|
public void | insertUpdate(javax.swing.event.DocumentEvent e, java.awt.Shape a, javax.swing.text.ViewFactory f)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.
super.insertUpdate(e, a, this);
|
protected void | invalidateGrid()
gridValid = false;
|
protected void | layoutColumns(int targetSpan, int[] offsets, int[] spans, javax.swing.SizeRequirements[] reqs)Layout the columns to fit within the given target span.
colIterator.setLayoutArrays(offsets, spans, targetSpan);
CSS.calculateTiledLayout(colIterator, targetSpan);
|
protected void | layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] 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.
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.
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();
}
}
|
protected void | layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans)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.
This is implemented to call the
layoutColumns method, and then
forward to the superclass to actually carry out the layout
of the tables rows.
// 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);
|
public void | paint(java.awt.Graphics g, java.awt.Shape allocation)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.
// 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;
}
}
for (int i = borderWidth; i > 0; i--) {
painter.paint(g, a.x + i, a.y + i, a.width - 2 * i, a.height - 2 * i, 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);
|
public void | removeUpdate(javax.swing.event.DocumentEvent e, java.awt.Shape a, javax.swing.text.ViewFactory f)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.
super.removeUpdate(e, a, this);
|
public void | replace(int offset, int length, javax.swing.text.View[] views)Change the child views. This is implemented to
provide the superclass behavior and invalidate the
grid so that rows and columns will be recalculated.
super.replace(offset, length, views);
invalidateGrid();
|
public void | setParent(javax.swing.text.View parent)Establishes the parent view for this view. This is
guaranteed to be called before any other methods if the
parent view is functioning properly.
This is implemented
to forward to the superclass as well as call the
setPropertiesFromAttributes
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.
super.setParent(parent);
if (parent != null) {
setPropertiesFromAttributes();
}
|
protected void | setPropertiesFromAttributes()Update any cached values that come from attributes.
StyleSheet sheet = getStyleSheet();
attr = sheet.getViewAttributes(this);
painter = sheet.getBoxPainter(attr);
if (attr != null) {
setInsets((short) painter.getInset(TOP, this),
(short) painter.getInset(LEFT, this),
(short) painter.getInset(BOTTOM, this),
(short) painter.getInset(RIGHT, this));
CSS.LengthValue lv = (CSS.LengthValue)
attr.getAttribute(CSS.Attribute.BORDER_SPACING);
if (lv != null) {
cellSpacing = (int) lv.getValue();
} else {
cellSpacing = 0;
}
lv = (CSS.LengthValue)
attr.getAttribute(CSS.Attribute.BORDER_TOP_WIDTH);
if (lv != null) {
borderWidth = (int) lv.getValue();
} else {
borderWidth = 0;
}
}
|
void | updateGrid()Fill in the grid locations that are placeholders
for multi-column, multi-row, and missing grid
locations.
if (! gridValid) {
relativeCells = false;
multiRowCells = false;
// determine which views are table rows and clear out
// grid points marked filled.
captionIndex = -1;
rows.removeAllElements();
int n = getViewCount();
for (int i = 0; i < n; i++) {
View v = getView(i);
if (v instanceof RowView) {
rows.addElement(v);
RowView rv = (RowView) v;
rv.clearFilledColumns();
rv.rowIndex = rows.size() - 1;
rv.viewIndex = i;
} else {
Object o = v.getElement().getAttributes().getAttribute(StyleConstants.NameAttribute);
if (o instanceof HTML.Tag) {
HTML.Tag kind = (HTML.Tag) o;
if (kind == HTML.Tag.CAPTION) {
captionIndex = i;
}
}
}
}
int maxColumns = 0;
int nrows = rows.size();
for (int row = 0; row < nrows; row++) {
RowView rv = getRow(row);
int col = 0;
for (int cell = 0; cell < rv.getViewCount(); cell++, col++) {
View cv = rv.getView(cell);
if (! relativeCells) {
AttributeSet a = cv.getAttributes();
CSS.LengthValue lv = (CSS.LengthValue)
a.getAttribute(CSS.Attribute.WIDTH);
if ((lv != null) && (lv.isPercentage())) {
relativeCells = true;
}
}
// advance to a free column
for (; rv.isFilled(col); col++);
int rowSpan = getRowsOccupied(cv);
if (rowSpan > 1) {
multiRowCells = true;
}
int colSpan = getColumnsOccupied(cv);
if ((colSpan > 1) || (rowSpan > 1)) {
// fill in the overflow entries for this cell
int rowLimit = row + rowSpan;
int colLimit = col + colSpan;
for (int i = row; i < rowLimit; i++) {
for (int j = col; j < colLimit; j++) {
if (i != row || j != col) {
addFill(i, j);
}
}
}
if (colSpan > 1) {
col += colSpan - 1;
}
}
}
maxColumns = Math.max(maxColumns, col);
}
// setup the column layout/requirements
columnSpans = new int[maxColumns];
columnOffsets = new int[maxColumns];
columnRequirements = new SizeRequirements[maxColumns];
for (int i = 0; i < maxColumns; i++) {
columnRequirements[i] = new SizeRequirements();
columnRequirements[i].maximum = Integer.MAX_VALUE;
}
gridValid = true;
}
|
void | updateInsets()Update the insets, which contain the caption if there
is a caption.
short top = (short) painter.getInset(TOP, this);
short bottom = (short) painter.getInset(BOTTOM, this);
if (captionIndex != -1) {
View caption = getView(captionIndex);
short h = (short) caption.getPreferredSpan(Y_AXIS);
AttributeSet a = caption.getAttributes();
Object align = a.getAttribute(CSS.Attribute.CAPTION_SIDE);
if ((align != null) && (align.equals("bottom"))) {
bottom += h;
} else {
top += h;
}
}
setInsets(top, (short) painter.getInset(LEFT, this),
bottom, (short) painter.getInset(RIGHT, this));
|