Blog do projektu Open Source JavaHotel

czwartek, 13 września 2012

CellTable and line wrapping

Introduction
In the previous (before GWT 2.4) it was difficult to add "no wrap" attribute to the CellTable.







































It was easy while creating user interface in HTML/CSS - just add "no-wrap" attribute to
tag or "white-space: nowrap" style. But it was difficult in GWT because there was no direct API for modifying (cell) attribute.
The only solution I found was to make copy and paste of DefaultCellTableBuilder and and modify it a little bit.


/**
 * IMPORTANT: copy and paste of DefaultCellTableBuilder. The only difference is
 * to add "nowrap" to td tag. Because all attributes in class are private I have
 * to copy also constructor with all attributes (cannot extends
 * DefaultCellTableBuilder)
 * 
 */

class MyCellTableBuilder<T> extends AbstractCellTableBuilder<T> {

    private final String evenRowStyle;
    private final String oddRowStyle;
    private final String selectedRowStyle;
    private final String cellStyle;
    private final String evenCellStyle;
    private final String oddCellStyle;
    private final String firstColumnStyle;
    private final String lastColumnStyle;
    private final String selectedCellStyle;

    // enhancement
    private boolean addNoWrap = false;
    
    /**
     * @return the addNoWrap
     */
    boolean isAddNoWrap() {
        return addNoWrap;
    }

    /**
     * @param addNoWrap the addNoWrap to set
     */
    void setAddNoWrap(boolean addNoWrap) {
        this.addNoWrap = addNoWrap;
    }
    // ===========


    MyCellTableBuilder(AbstractCellTable<T> cellTable) {
        super(cellTable);

        // Cache styles for faster access.
        Style style = cellTable.getResources().style();
        evenRowStyle = style.evenRow();
        oddRowStyle = style.oddRow();
        selectedRowStyle = " " + style.selectedRow();
        cellStyle = style.cell();
        evenCellStyle = " " + style.evenRowCell();
        oddCellStyle = " " + style.oddRowCell();
        firstColumnStyle = " " + style.firstColumn();
        lastColumnStyle = " " + style.lastColumn();
        selectedCellStyle = " " + style.selectedRowCell();
    }

    @Override
    public void buildRowImpl(T rowValue, int absRowIndex) {

        // Calculate the row styles.
        SelectionModel<? super T> selectionModel = cellTable
                .getSelectionModel();
        boolean isSelected = (selectionModel == null || rowValue == null) ? false
                : selectionModel.isSelected(rowValue);
        boolean isEven = absRowIndex % 2 == 0;
        StringBuilder trClasses = new StringBuilder(isEven ? evenRowStyle
                : oddRowStyle);
        if (isSelected) {
            trClasses.append(selectedRowStyle);
        }

        // Add custom row styles.
        RowStyles<T> rowStyles = cellTable.getRowStyles();
        if (rowStyles != null) {
            String extraRowStyles = rowStyles.getStyleNames(rowValue,
                    absRowIndex);
            if (extraRowStyles != null) {
                trClasses.append(" ").append(extraRowStyles);
            }
        }

        // Build the row.
        TableRowBuilder tr = startRow();
        tr.className(trClasses.toString());

        // Build the columns.
        int columnCount = cellTable.getColumnCount();
        for (int curColumn = 0; curColumn < columnCount; curColumn++) {
            Column<T, ?> column = cellTable.getColumn(curColumn);
            // Create the cell styles.
            StringBuilder tdClasses = new StringBuilder(cellStyle);
            tdClasses.append(isEven ? evenCellStyle : oddCellStyle);
            if (curColumn == 0) {
                tdClasses.append(firstColumnStyle);
            }
            if (isSelected) {
                tdClasses.append(selectedCellStyle);
            }
            // The first and last column could be the same column.
            if (curColumn == columnCount - 1) {
                tdClasses.append(lastColumnStyle);
            }

            // Add class names specific to the cell.
            Context context = new Context(absRowIndex, curColumn,
                    cellTable.getValueKey(rowValue));
            String cellStyles = column.getCellStyleNames(context, rowValue);
            if (cellStyles != null) {
                tdClasses.append(" " + cellStyles);
            }

            // Build the cell.
            HorizontalAlignmentConstant hAlign = column
                    .getHorizontalAlignment();
            VerticalAlignmentConstant vAlign = column.getVerticalAlignment();
            TableCellBuilder td = tr.startTD();
            td.className(tdClasses.toString());
            if (hAlign != null) {
                td.align(hAlign.getTextAlignString());
            }
            if (vAlign != null) {
                td.vAlign(vAlign.getVerticalAlignString());
            }
            // wrap enhancement
            if (addNoWrap) {
              td.attribute("nowrap", "true");
            }

            // Add the inner div.
            DivBuilder div = td.startDiv();
            div.style().outlineStyle(OutlineStyle.NONE).endStyle();

            // Render the cell into the div.
            renderCell(div, context, column, rowValue);

            // End the cell.
            div.endDiv();
            td.endTD();
        }

        // End the row.
        tr.endTR();
    }
}

The only important difference is
 // wrap enhancement
            if (addNoWrap) {
              td.attribute("nowrap", "true");
            }
in the middle. But because of code duplication I felt unhappy with that rather lame solution.
How it can be resolved now
Starting from GWT 2.4 version things have looked better because additional method setCellStyleName was added to the  Column interface which resolved the issue. So the solution now is:
Add class name to the css file.
.no_wrap_cell_style {
  white-space: nowrap;
}
And main code now is (source file PresentationTable)
    @Override
    public void setNoWrap(boolean noWrap) {
        for (int i = 0; i < table.getColumnCount(); i++) {
            Column co = table.getColumn(i);
            co.setCellStyleNames(noWrap ? "" : IConsts.nowrapStyle);
        }
        table.redraw();
    }
Demo version is available here. "FindTest"->"Ustawienia"->"Zawijaj linie"

Brak komentarzy:

Publikowanie komentarza