use of org.apache.pivot.wtk.TablePane in project pivot by apache.
the class TablePaneSkin method getRowHeights.
/**
* Gets the height of each row of a table pane given the specified
* constraints.
*
* @param height The height constraint of the table pane
* @param columnWidthsArgument The widths of the table pane's columns, which
* will be used as width constraints to the row heights when necessary, or
* <tt>null</tt> if the column widths are not yet known (the row heights
* will be unconstrained)
* @return An array containing the height of each row in the table pane given
* the specified constraints
*/
private int[] getRowHeights(int height, int[] columnWidthsArgument) {
Utils.checkNull(columnWidthsArgument, "columnWidths");
TablePane tablePane = (TablePane) getComponent();
TablePane.RowSequence rows = tablePane.getRows();
int rowCount = rows.getLength();
int columnCount = tablePane.getColumns().getLength();
int[] rowHeightsLocal = new int[rowCount];
boolean[] defaultHeightRows = new boolean[rowCount];
int totalRelativeWeight = 0;
int visibleRowCount = 0;
int reservedHeight = padding.getHeight();
for (int i = 0; i < rowCount; i++) {
if (isRowVisible(i)) {
TablePane.Row row = rows.get(i);
int rowHeight = row.getHeight();
if (row.isRelative()) {
rowHeightsLocal[i] = -rowHeight;
totalRelativeWeight += rowHeight;
} else {
if (rowHeight < 0) {
// Default height row; we must calculate the height
rowHeight = getPreferredRowHeight(i, columnWidthsArgument);
defaultHeightRows[i] = true;
}
rowHeightsLocal[i] = rowHeight;
reservedHeight += rowHeight;
}
visibleRowCount++;
} else {
rowHeightsLocal[i] = 0;
}
}
if (visibleRowCount > 1) {
reservedHeight += (visibleRowCount - 1) * verticalSpacing;
}
for (int i = 0; i < rowCount; i++) {
TablePane.Row row = rows.get(i);
for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
Component component = row.get(j);
if (component != null && component.isVisible()) {
int rowSpan = TablePane.getRowSpan(component);
if (rowSpan > 1) {
// We might need to adjust row heights to accommodate
// this spanning cell. First, we find out if any of the
// spanned cells are default height and how much space
// we've allocated thus far for those cells
boolean adjustCells = true;
int spannedDefaultHeightCellCount = 0;
int spannedHeight = 0;
for (int k = 0; k < rowSpan && i + k < rowCount; k++) {
if (rowHeightsLocal[i + k] < 0) {
adjustCells = false;
break;
}
if (defaultHeightRows[i + k]) {
spannedDefaultHeightCellCount++;
}
spannedHeight += rowHeightsLocal[i + k];
}
if (adjustCells && spannedDefaultHeightCellCount > 0) {
int componentPreferredHeight = component.getPreferredHeight(columnWidthsArgument[j]);
if (componentPreferredHeight > spannedHeight) {
// The component's preferred height is larger
// than the height we've allocated thus far, so
// an adjustment is necessary
int adjustment = componentPreferredHeight - spannedHeight;
// among the default-height rows
for (int k = 0; k < rowSpan && i + k < rowCount; k++) {
if (defaultHeightRows[i + k]) {
int rowAdjustment = adjustment / spannedDefaultHeightCellCount;
rowHeightsLocal[i + k] += rowAdjustment;
reservedHeight += rowAdjustment;
// Adjust these to avoid rounding errors
adjustment -= rowAdjustment;
spannedDefaultHeightCellCount--;
}
}
}
}
}
}
}
}
// Finally, we allocate the heights of the relative rows by divvying
// up the remaining height
int remainingHeight = height - reservedHeight;
if (totalRelativeWeight > 0 && remainingHeight > 0) {
for (int i = 0; i < rowCount; i++) {
if (rowHeightsLocal[i] < 0) {
int relativeWeight = -rowHeightsLocal[i];
float weightPercentage = relativeWeight / (float) totalRelativeWeight;
int rowHeight = (int) (remainingHeight * weightPercentage);
rowHeightsLocal[i] = rowHeight;
// NOTE we adjust remainingHeight and totalRelativeWeight as
// we
// go to avoid potential rounding errors in the rowHeight
// calculation
remainingHeight -= rowHeight;
totalRelativeWeight -= relativeWeight;
}
}
}
// If we have don't actually have enough height available
// prevent infinite loop
boolean progress = true;
while (remainingHeight < 0 && progress) {
progress = false;
for (int i = 0; i < rowCount; i++) {
if (isRowVisible(i)) {
TablePane.Row row = rows.get(i);
if (!row.isRelative()) {
if (rowHeightsLocal[i] > 0) {
rowHeightsLocal[i]--;
remainingHeight++;
progress = true;
if (remainingHeight >= 0) {
break;
}
}
}
}
}
}
return rowHeightsLocal;
}
use of org.apache.pivot.wtk.TablePane in project pivot by apache.
the class TablePaneSkin method columnHighlightedChanged.
@Override
public void columnHighlightedChanged(TablePane.Column column) {
TablePane tablePane = column.getTablePane();
repaintComponent(getColumnBounds(tablePane.getColumns().indexOf(column)));
}
use of org.apache.pivot.wtk.TablePane in project pivot by apache.
the class TablePaneSkin method getPreferredWidth.
@Override
public int getPreferredWidth(int height) {
TablePane tablePane = (TablePane) getComponent();
TablePane.RowSequence rows = tablePane.getRows();
TablePane.ColumnSequence columns = tablePane.getColumns();
int rowCount = rows.getLength();
int columnCount = columns.getLength();
int[] columnWidthsLocal = new int[columnCount];
int[] relativeWeights = new int[columnCount];
boolean[] defaultWidthColumns = new boolean[columnCount];
int totalRelativeWeight = 0;
for (int i = 0; i < columnCount; i++) {
TablePane.Column column = columns.get(i);
int columnWidth = column.getWidth();
boolean isRelative = column.isRelative();
defaultWidthColumns[i] = (columnWidth < 0);
if (isRelative) {
relativeWeights[i] = columnWidth;
totalRelativeWeight += columnWidth;
}
if (columnWidth < 0 || isRelative) {
columnWidth = getPreferredColumnWidth(i);
}
columnWidthsLocal[i] = columnWidth;
}
if (totalRelativeWeight > 0) {
int totalRelativeWidth = 0;
for (int i = 0; i < columnCount; i++) {
int columnWidth = columnWidthsLocal[i];
int relativeWeight = relativeWeights[i];
if (relativeWeight > 0) {
float weightPercentage = relativeWeight / (float) totalRelativeWeight;
totalRelativeWidth = Math.max(totalRelativeWidth, (int) (columnWidth / weightPercentage));
}
}
for (int i = 0; i < columnCount; i++) {
int relativeWeight = relativeWeights[i];
if (relativeWeight > 0) {
float weightPercentage = relativeWeight / (float) totalRelativeWeight;
columnWidthsLocal[i] = (int) (weightPercentage * totalRelativeWidth);
}
}
}
for (int i = 0; i < rowCount; i++) {
TablePane.Row row = rows.get(i);
for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
Component component = row.get(j);
if (component != null && component.isVisible()) {
int columnSpan = TablePane.getColumnSpan(component);
if (columnSpan > 1) {
// We might need to adjust column widths to accomodate
// this spanning cell. First, we find out if any of the
// spanned cells are default width and how much space
// we've allocated thus far for those cells
int spannedDefaultWidthCellCount = 0;
int spannedRelativeWeight = 0;
int spannedWidth = 0;
for (int k = 0; k < columnSpan && j + k < columnCount; k++) {
if (defaultWidthColumns[j + k]) {
spannedDefaultWidthCellCount++;
}
spannedRelativeWeight += relativeWeights[j + k];
spannedWidth += columnWidthsLocal[j + k];
}
if (spannedRelativeWeight > 0 || spannedDefaultWidthCellCount > 0) {
int rowHeight = row.isRelative() ? -1 : row.getHeight();
int componentPreferredWidth = component.getPreferredWidth(rowHeight);
if (componentPreferredWidth > spannedWidth) {
// The component's preferred width is larger
// than the width we've allocated thus far, so
// an adjustment is necessary
int adjustment = componentPreferredWidth - spannedWidth;
if (spannedRelativeWeight > 0) {
// We'll distribute the adjustment across
// the spanned relative columns and adjust
// other relative column widths to keep all
// relative column widths reconciled
float unitAdjustment = adjustment / (float) spannedRelativeWeight;
for (int k = 0; k < columnCount; k++) {
int relativeWeight = relativeWeights[k];
if (relativeWeight > 0) {
int columnAdjustment = Math.round(unitAdjustment * relativeWeight);
columnWidthsLocal[k] += columnAdjustment;
}
}
} else {
// among the default-width columns
for (int k = 0; k < columnSpan && j + k < columnCount; k++) {
if (defaultWidthColumns[j + k]) {
int columnAdjustment = adjustment / spannedDefaultWidthCellCount;
columnWidthsLocal[j + k] += columnAdjustment;
// Adjust these to avoid rounding
// errors
adjustment -= columnAdjustment;
spannedDefaultWidthCellCount--;
}
}
}
}
}
}
}
}
}
// The preferred width of the table pane is the sum of the column
// widths, plus padding and spacing
boolean[][] occupiedCells = getOccupiedCells();
int visibleColumnCount = 0;
int preferredWidth = padding.getWidth();
for (int j = 0; j < columnCount; j++) {
boolean columnVisible = false;
for (int i = 0; i < rowCount; i++) {
if (occupiedCells[i][j]) {
columnVisible = true;
break;
}
}
if (columnVisible) {
preferredWidth += columnWidthsLocal[j];
visibleColumnCount++;
}
}
if (visibleColumnCount > 1) {
preferredWidth += (visibleColumnCount - 1) * horizontalSpacing;
}
return preferredWidth;
}
use of org.apache.pivot.wtk.TablePane in project pivot by apache.
the class TablePaneSkin method install.
@Override
public void install(Component component) {
super.install(component);
TablePane tablePane = (TablePane) component;
tablePane.getTablePaneListeners().add(this);
tablePane.getTablePaneAttributeListeners().add(this);
}
Aggregations