Search in sources :

Example 6 with TablePane

use of org.apache.pivot.wtk.TablePane in project pivot by apache.

the class TablePaneSkin method getPreferredColumnWidth.

/**
 * Gets the preferred width of a table pane column, which is defined as the
 * maximum preferred width of the column's visible components. <p> Because
 * their preferred width relates to the preferred widths of other columns,
 * components that span multiple columns will not be considered in this
 * calculation (even if they live in the column directly). It is up to the
 * caller to factor such components into the column widths calculation.
 *
 * @param columnIndex The index of the column whose preferred width we're
 * calculating
 */
private int getPreferredColumnWidth(int columnIndex) {
    TablePane tablePane = (TablePane) getComponent();
    TablePane.RowSequence rows = tablePane.getRows();
    int preferredWidth = 0;
    for (int i = 0, n = rows.getLength(); i < n; i++) {
        TablePane.Row row = rows.get(i);
        if (row.getLength() > columnIndex) {
            Component component = row.get(columnIndex);
            if (component != null && component.isVisible() && TablePane.getColumnSpan(component) == 1) {
                preferredWidth = Math.max(preferredWidth, component.getPreferredWidth(-1));
            }
        }
    }
    return preferredWidth;
}
Also used : Component(org.apache.pivot.wtk.Component) TablePane(org.apache.pivot.wtk.TablePane)

Example 7 with TablePane

use of org.apache.pivot.wtk.TablePane in project pivot by apache.

the class TablePaneSkin method getOccupiedCells.

/**
 * Returns a grid indicating which cells are occupied. A component is said
 * to occupy a cell if it is visible and either lives in the cell directly
 * or spans the cell. Conversely, vacant cells do not have visible
 * components within them or spanning them.
 *
 * @return A grid of booleans, where occupied cells are denoted by
 * <tt>true</tt>, and vacant cells are denoted by <tt>false</tt>
 */
private boolean[][] getOccupiedCells() {
    TablePane tablePane = (TablePane) getComponent();
    TablePane.RowSequence rows = tablePane.getRows();
    TablePane.ColumnSequence columns = tablePane.getColumns();
    int rowCount = rows.getLength();
    int columnCount = columns.getLength();
    boolean[][] occupiedCells = new boolean[rowCount][columnCount];
    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);
                int columnSpan = TablePane.getColumnSpan(component);
                for (int k = 0; k < rowSpan && i + k < rowCount; k++) {
                    for (int l = 0; l < columnSpan && j + l < columnCount; l++) {
                        occupiedCells[i + k][j + l] = true;
                    }
                }
            }
        }
    }
    return occupiedCells;
}
Also used : Component(org.apache.pivot.wtk.Component) TablePane(org.apache.pivot.wtk.TablePane)

Example 8 with TablePane

use of org.apache.pivot.wtk.TablePane in project pivot by apache.

the class TablePaneSkin method layout.

@Override
public void layout() {
    TablePane tablePane = (TablePane) getComponent();
    TablePane.RowSequence rows = tablePane.getRows();
    TablePane.ColumnSequence columns = tablePane.getColumns();
    int rowCount = rows.getLength();
    int columnCount = columns.getLength();
    int width = getWidth();
    int height = getHeight();
    // NOTE We cache column widths and row heights to make getColumnAt()
    // and getRowAt() more efficient
    columnWidths = getColumnWidths(width);
    rowHeights = getRowHeights(height, columnWidths);
    // Determine which rows and column should be visible so we know which
    // ones should be collapsed
    boolean[] visibleRows = new boolean[rowCount];
    boolean[] visibleColumns = new boolean[columnCount];
    boolean[][] occupiedCells = getOccupiedCells();
    for (int i = 0; i < rowCount; i++) {
        for (int j = 0; j < columnCount; j++) {
            if (occupiedCells[i][j]) {
                visibleRows[i] = true;
                visibleColumns[j] = true;
            }
        }
    }
    int componentY = padding.top;
    for (int i = 0; i < rowCount; i++) {
        TablePane.Row row = rows.get(i);
        int componentX = padding.left;
        for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
            Component child = row.get(j);
            if (child != null && child.isVisible()) {
                child.setLocation(componentX, componentY);
                int columnSpan = TablePane.getColumnSpan(child);
                columnSpan = Math.min(columnSpan, columnCount - j);
                int childWidth = (columnSpan - 1) * horizontalSpacing;
                for (int k = 0; k < columnSpan && j + k < columnCount; k++) {
                    childWidth += columnWidths[j + k];
                }
                int rowSpan = TablePane.getRowSpan(child);
                rowSpan = Math.min(rowSpan, rowCount - i);
                int childHeight = (rowSpan - 1) * verticalSpacing;
                for (int k = 0; k < rowSpan && i + k < rowCount; k++) {
                    childHeight += rowHeights[i + k];
                }
                // Set the component's size
                child.setSize(Math.max(childWidth, 0), Math.max(childHeight, 0));
            }
            if (visibleColumns[j]) {
                componentX += (columnWidths[j] + horizontalSpacing);
            }
        }
        if (visibleRows[i]) {
            componentY += (rowHeights[i] + verticalSpacing);
        }
    }
}
Also used : Component(org.apache.pivot.wtk.Component) TablePane(org.apache.pivot.wtk.TablePane)

Example 9 with TablePane

use of org.apache.pivot.wtk.TablePane in project pivot by apache.

the class TablePaneSkin method getColumnWidths.

/**
 * Gets the width of each table pane column given the specified table pane
 * width.
 *
 * @param width The width constraint of the table pane
 * @return An array containing the width of each column in the table pane
 * given the specified constraint
 */
private int[] getColumnWidths(int width) {
    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];
    boolean[] defaultWidthColumns = new boolean[columnCount];
    int totalRelativeWeight = 0;
    int visibleColumnCount = 0;
    int reservedWidth = padding.getWidth();
    for (int j = 0; j < columnCount; j++) {
        if (isColumnVisible(j)) {
            TablePane.Column column = columns.get(j);
            int columnWidth = column.getWidth();
            if (column.isRelative()) {
                columnWidthsLocal[j] = -columnWidth;
                totalRelativeWeight += columnWidth;
            } else {
                if (columnWidth < 0) {
                    // Default width column; we must calculate the width
                    columnWidth = getPreferredColumnWidth(j);
                    defaultWidthColumns[j] = true;
                }
                columnWidthsLocal[j] = columnWidth;
                reservedWidth += columnWidth;
            }
            visibleColumnCount++;
        } else {
            columnWidthsLocal[j] = 0;
        }
    }
    if (visibleColumnCount > 1) {
        reservedWidth += (visibleColumnCount - 1) * horizontalSpacing;
    }
    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
                    boolean adjustCells = true;
                    int spannedDefaultWidthCellCount = 0;
                    int spannedWidth = 0;
                    for (int k = 0; k < columnSpan && j + k < columnCount; k++) {
                        if (columnWidthsLocal[j + k] < 0) {
                            adjustCells = false;
                            break;
                        }
                        if (defaultWidthColumns[j + k]) {
                            spannedDefaultWidthCellCount++;
                        }
                        spannedWidth += columnWidthsLocal[j + k];
                    }
                    if (adjustCells && spannedDefaultWidthCellCount > 0) {
                        int componentPreferredWidth = component.getPreferredWidth(-1);
                        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;
                            // 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;
                                    reservedWidth += columnAdjustment;
                                    // Adjust these to avoid rounding errors
                                    adjustment -= columnAdjustment;
                                    spannedDefaultWidthCellCount--;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // Finally, we allocate the widths of the relative columns by divvying
    // up the remaining width
    int remainingWidth = Math.max(width - reservedWidth, 0);
    if (totalRelativeWeight > 0 && remainingWidth > 0) {
        for (int j = 0; j < columnCount; j++) {
            if (columnWidthsLocal[j] < 0) {
                int relativeWeight = -columnWidthsLocal[j];
                float weightPercentage = relativeWeight / (float) totalRelativeWeight;
                int columnWidth = (int) (remainingWidth * weightPercentage);
                columnWidthsLocal[j] = columnWidth;
                // NOTE we adjust remainingWidth and totalRelativeWeight as
                // we go
                // to avoid potential rounding errors in the columnWidth
                // calculation
                remainingWidth -= columnWidth;
                totalRelativeWeight -= relativeWeight;
            }
        }
    }
    return columnWidthsLocal;
}
Also used : Component(org.apache.pivot.wtk.Component) TablePane(org.apache.pivot.wtk.TablePane)

Example 10 with TablePane

use of org.apache.pivot.wtk.TablePane in project pivot by apache.

the class TablePaneSkin method getPreferredHeight.

@Override
public int getPreferredHeight(int width) {
    TablePane tablePane = (TablePane) getComponent();
    TablePane.RowSequence rows = tablePane.getRows();
    TablePane.ColumnSequence columns = tablePane.getColumns();
    int rowCount = rows.getLength();
    int columnCount = columns.getLength();
    int[] rowHeightsLocal = new int[rowCount];
    int[] relativeWeights = new int[rowCount];
    boolean[] defaultHeightRows = new boolean[rowCount];
    int totalRelativeWeight = 0;
    int widthUpdated = width;
    if (widthUpdated < 0) {
        widthUpdated = getPreferredWidth(-1);
    }
    int[] columnWidthsLocal = getColumnWidths(widthUpdated);
    for (int i = 0; i < rowCount; i++) {
        TablePane.Row row = rows.get(i);
        int rowHeight = row.getHeight();
        boolean isRelative = row.isRelative();
        defaultHeightRows[i] = (rowHeight < 0);
        if (isRelative) {
            relativeWeights[i] = rowHeight;
            totalRelativeWeight += rowHeight;
        }
        if (rowHeight < 0 || isRelative) {
            rowHeight = getPreferredRowHeight(i, columnWidthsLocal);
        }
        rowHeightsLocal[i] = rowHeight;
    }
    if (totalRelativeWeight > 0) {
        int totalRelativeHeight = 0;
        for (int i = 0; i < rowCount; i++) {
            int rowHeight = rowHeightsLocal[i];
            int relativeWeight = relativeWeights[i];
            if (relativeWeight > 0) {
                float weightPercentage = relativeWeight / (float) totalRelativeWeight;
                totalRelativeHeight = Math.max(totalRelativeHeight, (int) (rowHeight / weightPercentage));
            }
        }
        for (int i = 0; i < rowCount; i++) {
            int relativeWeight = relativeWeights[i];
            if (relativeWeight > 0) {
                float weightPercentage = relativeWeight / (float) totalRelativeWeight;
                rowHeightsLocal[i] = (int) (weightPercentage * totalRelativeHeight);
            }
        }
    }
    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 accomodate
                    // 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
                    int spannedDefaultHeightCellCount = 0;
                    int spannedRelativeWeight = 0;
                    int spannedHeight = 0;
                    for (int k = 0; k < rowSpan && i + k < rowCount; k++) {
                        if (defaultHeightRows[i + k]) {
                            spannedDefaultHeightCellCount++;
                        }
                        spannedRelativeWeight += relativeWeights[i + k];
                        spannedHeight += rowHeightsLocal[i + k];
                    }
                    if (spannedRelativeWeight > 0 || spannedDefaultHeightCellCount > 0) {
                        int componentPreferredHeight = component.getPreferredHeight(columnWidthsLocal[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;
                            if (spannedRelativeWeight > 0) {
                                // We'll distribute the adjustment across
                                // the spanned relative rows and adjust
                                // other relative row heights to keep all
                                // relative row heights reconciled
                                float unitAdjustment = adjustment / (float) spannedRelativeWeight;
                                for (int k = 0; k < rowCount; k++) {
                                    int relativeWeight = relativeWeights[k];
                                    if (relativeWeight > 0) {
                                        int rowAdjustment = Math.round(unitAdjustment * relativeWeight);
                                        rowHeightsLocal[k] += rowAdjustment;
                                    }
                                }
                            } else {
                                // 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;
                                        // Adjust these to avoid rounding
                                        // errors
                                        adjustment -= rowAdjustment;
                                        spannedDefaultHeightCellCount--;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // The preferred height of the table pane is the sum of the row
    // heights, plus padding and spacing
    boolean[][] occupiedCells = getOccupiedCells();
    int visibleRowCount = 0;
    int preferredHeight = padding.getHeight();
    for (int i = 0; i < rowCount; i++) {
        boolean rowVisible = false;
        for (int j = 0; j < columnCount; j++) {
            if (occupiedCells[i][j]) {
                rowVisible = true;
                break;
            }
        }
        if (rowVisible) {
            preferredHeight += rowHeightsLocal[i];
            visibleRowCount++;
        }
    }
    if (visibleRowCount > 1) {
        preferredHeight += (visibleRowCount - 1) * verticalSpacing;
    }
    return preferredHeight;
}
Also used : Component(org.apache.pivot.wtk.Component) TablePane(org.apache.pivot.wtk.TablePane)

Aggregations

TablePane (org.apache.pivot.wtk.TablePane)19 Component (org.apache.pivot.wtk.Component)12 Label (org.apache.pivot.wtk.Label)4 Window (org.apache.pivot.wtk.Window)4 BoxPane (org.apache.pivot.wtk.BoxPane)3 PushButton (org.apache.pivot.wtk.PushButton)3 Button (org.apache.pivot.wtk.Button)2 ButtonPressListener (org.apache.pivot.wtk.ButtonPressListener)2 ImageView (org.apache.pivot.wtk.ImageView)2 Spinner (org.apache.pivot.wtk.Spinner)2 SVGElementException (com.kitfox.svg.SVGElementException)1 SVGException (com.kitfox.svg.SVGException)1 BasicStroke (java.awt.BasicStroke)1 Graphics2D (java.awt.Graphics2D)1 Area (java.awt.geom.Area)1 Rectangle2D (java.awt.geom.Rectangle2D)1 URL (java.net.URL)1 BeanAdapter (org.apache.pivot.beans.BeanAdapter)1 DefaultProperty (org.apache.pivot.beans.DefaultProperty)1 Sequence (org.apache.pivot.collections.Sequence)1