org.vaadin.addons.tuningdatefield.widgetset.client.ui.calendar.AbstractCalendarTable.java Source code

Java tutorial

Introduction

Here is the source code for org.vaadin.addons.tuningdatefield.widgetset.client.ui.calendar.AbstractCalendarTable.java

Source

/*
 * Copyright (C) 2013 Frederic Dreyfus
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.vaadin.addons.tuningdatefield.widgetset.client.ui.calendar;

import org.vaadin.addons.tuningdatefield.widgetset.client.ui.events.CalendarItemClickEvent;
import org.vaadin.addons.tuningdatefield.widgetset.client.ui.events.NextControlClickEvent;
import org.vaadin.addons.tuningdatefield.widgetset.client.ui.events.PreviousControlClickEvent;
import org.vaadin.addons.tuningdatefield.widgetset.client.ui.events.ResolutionControlClickEvent;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.FlexTable;

/**
 * A calendar table that holds cell items and controls.<br>
 * This table is ususally composed of :
 * <ol>
 * <li>A row for controls with 3 cells (previous, resolution and next control)</li>
 * <li>X rows for cellItems which can be days, months or years depending on the resolution</li>
 * </ol>
 * 
 * @author Frederic.Dreyfus
 */
public abstract class AbstractCalendarTable extends FlexTable {

    /**
     * The parent {@link TuningDateFieldCalendarWidget}
     */
    protected TuningDateFieldCalendarWidget tuningDateFieldCalendar;

    /**
     * The text in the resolution control cell
     */
    protected String resolutionControlText;

    /**
     * The cell items
     */
    protected CalendarItem[] calendarItems;

    /**
     * True if the controls are enabled
     */
    protected boolean controlsEnabled;

    public AbstractCalendarTable(TuningDateFieldCalendarWidget tuningDateFieldCalendar,
            String resolutionControlText, CalendarItem[] calendarItems, boolean controlsEnabled) {
        super();
        this.tuningDateFieldCalendar = tuningDateFieldCalendar;
        this.resolutionControlText = resolutionControlText;
        this.calendarItems = calendarItems;
        this.controlsEnabled = controlsEnabled;
        setCellSpacing(0);
        setCellPadding(0);

        init();
    }

    /**
     * Returns the number of columns in the table
     * 
     * @return the number of columns in the table
     */
    protected abstract int getNumberOfColumns();

    /**
     * Returns the primary stylename of cells
     * 
     * @return the primary stylename of cells
     */
    protected abstract String getCellItemPrimaryStylename();

    /**
     * Returns the primary stylename of rows
     * 
     * @return the primary stylename of rows
     */
    protected abstract String getRowPrimaryStylename();

    /**
     * The row number of controls (usually 0)
     * 
     * @return row number of controls (usually 0)
     */
    protected int getControlsRow() {
        return 0;
    }

    /**
     * @return The row of the first cellItem : 2 for day resolution as there is a row with day names, 1 for other
     *         calendars
     */
    protected int getFirstCellItemsRow() {
        return 1;
    }

    /**
     * @return the column of the previous control (usually 0)
     */
    protected int getPreviousControlColumn() {
        return 0;
    }

    /**
     * @return the column of the resolution control (usually 1)
     */
    protected int getResolutionControlColumn() {
        return 1;
    }

    /**
     * @return the column of the next control (usually 2)
     */
    protected int getNextControlColumn() {
        return 2;
    }

    private void init() {

        renderHeader();

        renderCalendarItems();

        // There is only one clickHandler for the table which will dispatch the correct events
        addClickHandler(new ClickHandler() {
            Cell selectedCell = null;

            @Override
            public void onClick(ClickEvent event) {
                Cell clickedCell = getCellForEvent(event);
                if (clickedCell.getRowIndex() >= getFirstCellItemsRow()) { // click on cellItem
                    int itemIndex = getItemIndex(clickedCell.getRowIndex(), clickedCell.getCellIndex());
                    CalendarItem calendarItem = calendarItems[itemIndex];
                    if (calendarItem.isEnabled()) {
                        if (selectedCell != null) {
                            getFlexCellFormatter().removeStyleName(selectedCell.getRowIndex(),
                                    selectedCell.getCellIndex(), "selected");
                        }
                        selectedCell = clickedCell;
                        getFlexCellFormatter().addStyleName(selectedCell.getRowIndex(), selectedCell.getCellIndex(),
                                "selected");
                        cellItemClick(itemIndex, event);
                    }
                } else if (clickedCell.getRowIndex() == getControlsRow()) {
                    if (clickedCell.getCellIndex() == getPreviousControlColumn()) {
                        previousControlClick();
                    } else if (clickedCell.getCellIndex() == getNextControlColumn()) {
                        nextControlClick();
                    } else if (clickedCell.getCellIndex() == getResolutionControlColumn()) {
                        resolutionControlClick();
                    }
                }

            }
        });
    }

    private void renderCalendarItems() {
        for (CalendarItem cellItem : calendarItems) {
            int row = getRow(cellItem.getIndex());
            int column = getColumn(cellItem.getIndex());

            setHTML(row, column, cellItem.getText());

            StringBuilder styleNamesBuilder = new StringBuilder(getCellItemPrimaryStylename());
            if (cellItem.isEnabled()) {
                styleNamesBuilder.append(" enabled");
            } else {
                styleNamesBuilder.append(" disabled");
            }

            if (cellItem.getStyle() != null && !cellItem.getStyle().isEmpty()) {
                styleNamesBuilder.append(" ").append(cellItem.getStyle());
            }
            if (cellItem.getTooltip() != null && !cellItem.getTooltip().isEmpty()) {
                DOM.setElementAttribute(getFlexCellFormatter().getElement(row, column), "title",
                        cellItem.getTooltip());
            }

            getFlexCellFormatter().addStyleName(row, column, styleNamesBuilder.toString());
        }

        // For each row add stylename
        int numberOfCellItemRows = calendarItems.length / getNumberOfColumns();
        int firstRow = getFirstCellItemsRow();
        int lastRow = getFirstCellItemsRow() + numberOfCellItemRows - 1;
        for (int i = firstRow; i <= lastRow; i++) {
            getRowFormatter().setStyleName(i, getRowPrimaryStylename());
            getCellFormatter().addStyleName(i, 0, "first-column");
            getCellFormatter().addStyleName(i, getNumberOfColumns() - 1, "last-column");
            if (i == firstRow) {
                getRowFormatter().addStyleName(i, "first-row");
            }
            if (i == lastRow) {
                getRowFormatter().addStyleName(i, "last-row");
            }
        }

    }

    protected void renderHeader() {
        renderControls();
    }

    protected void renderControls() {

        renderPreviousControl();

        renderResolutionControl();

        renderNextControl();

        getRowFormatter().setStyleName(getControlsRow(), "controls");

    }

    protected void renderPreviousControl() {
        if (controlsEnabled) {
            setText(getControlsRow(), getPreviousControlColumn(), "<");
            getFlexCellFormatter().setStylePrimaryName(getControlsRow(), getPreviousControlColumn(),
                    "previous-control");
            getFlexCellFormatter().addStyleName(getControlsRow(), getPreviousControlColumn(), "enabled");
        } else {
            setText(getControlsRow(), getPreviousControlColumn(), "");
            getFlexCellFormatter().setStylePrimaryName(getControlsRow(), getPreviousControlColumn(),
                    "previous-control");
            getFlexCellFormatter().addStyleName(getControlsRow(), getPreviousControlColumn(), "disabled");
        }

    }

    protected void renderNextControl() {
        if (controlsEnabled) {
            setText(getControlsRow(), getNextControlColumn(), ">");
            getFlexCellFormatter().setStylePrimaryName(getControlsRow(), getNextControlColumn(), "next-control");
            getFlexCellFormatter().addStyleName(getControlsRow(), getNextControlColumn(), "enabled");
        } else {
            setText(getControlsRow(), getNextControlColumn(), "");
            getFlexCellFormatter().setStylePrimaryName(getControlsRow(), getNextControlColumn(), "next-control");
            getFlexCellFormatter().addStyleName(getControlsRow(), getNextControlColumn(), "disabled");
        }

    }

    protected void renderResolutionControl() {
        setText(getControlsRow(), getResolutionControlColumn(), resolutionControlText);
        getFlexCellFormatter().setStylePrimaryName(getControlsRow(), getResolutionControlColumn(),
                "resolution-control");
        if (controlsEnabled) {
            getFlexCellFormatter().addStyleName(getControlsRow(), getResolutionControlColumn(), "enabled");
        } else {
            getFlexCellFormatter().addStyleName(getControlsRow(), getResolutionControlColumn(), "disabled");
        }

        int colspan = getNumberOfColumns() - 2;
        getFlexCellFormatter().setColSpan(getControlsRow(), getResolutionControlColumn(), colspan);

    }

    /**
     * Returns the row from a cellItem index.
     * 
     * @param itemIndex
     *            the cellItem index
     * @return the row from a cellItem index.
     */
    protected int getRow(int itemIndex) {
        return getFirstCellItemsRow() + itemIndex / getNumberOfColumns();

    }

    /**
     * Returns the column from a cellItem index.
     * 
     * @param itemIndex
     *            the cellItem index
     * @return the column from a cellItem index.
     */
    protected int getColumn(int itemIndex) {
        return itemIndex % getNumberOfColumns();
    }

    /**
     * Returns the cellItem index from its coordinates.
     * 
     * @param row
     *            the row
     * @param column
     *            the column
     * @return the cellItem index from its coordinates.
     */
    protected int getItemIndex(int row, int column) {
        return (row - getFirstCellItemsRow()) * getNumberOfColumns() + column;
    }

    public void cellItemClick(int itemIndex, ClickEvent event) {
        tuningDateFieldCalendar.fireEvent(
                new CalendarItemClickEvent(calendarItems[itemIndex].getRelativeDateIndex(), itemIndex, event));
    }

    public void previousControlClick() {
        tuningDateFieldCalendar.fireEvent(new PreviousControlClickEvent());
    }

    public void nextControlClick() {
        tuningDateFieldCalendar.fireEvent(new NextControlClickEvent());
    }

    public void resolutionControlClick() {
        tuningDateFieldCalendar.fireEvent(new ResolutionControlClickEvent());
    }

}