com.bradrydzewski.gwt.calendar.client.agenda.AgendaView.java Source code

Java tutorial

Introduction

Here is the source code for com.bradrydzewski.gwt.calendar.client.agenda.AgendaView.java

Source

/*
 * This file is part of gwt-cal
 * Copyright (C) 2009  Scottsdale Software LLC
 * 
 * gwt-cal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
    
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/
 */

package com.bradrydzewski.gwt.calendar.client.agenda;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.bradrydzewski.gwt.calendar.client.Appointment;
import com.bradrydzewski.gwt.calendar.client.Attendee;
import com.bradrydzewski.gwt.calendar.client.CalendarView;
import com.bradrydzewski.gwt.calendar.client.CalendarWidget;
import com.bradrydzewski.gwt.calendar.client.DateUtils;
import com.bradrydzewski.gwt.calendar.client.util.AppointmentUtil;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;

public class AgendaView extends CalendarView {

    /**
     * Adapter class that maps an Appointment to the widgets (DIV's, etc) that represent
     * it on the screen. This is necessary because a single appointment is represented by
     * many widgets. For example, an appointment is represented by a title widget,
     * a description widget, and has a "get more details" label.
     * 
     * By mapping an appointment to these widgets we can easily figure out which
     * appointment the user is interacting with as they click around the AgendaView.
     * @author Brad Rydzewski
     * @version 1.0
     * @since 0.9.0
     */
    class AgendaViewAppointmentAdapter {
        private Widget titleLabel;
        private Widget dateLabel;
        private Widget detailsLabel;
        private Appointment appointment;
        private Widget detailsPanel;

        public AgendaViewAppointmentAdapter(Widget titleLabel, Widget dateLabel, Widget detailsPanel,
                Widget detailsLabel, Appointment appointment) {
            super();
            this.titleLabel = titleLabel;
            this.dateLabel = dateLabel;
            this.detailsLabel = detailsLabel;
            this.detailsPanel = detailsPanel;
            this.appointment = appointment;
        }

        public Widget getTitleLabel() {
            return titleLabel;
        }

        public Widget getDateLabel() {
            return dateLabel;
        }

        public Widget getDetailsLabel() {
            return detailsLabel;
        }

        public Appointment getAppointment() {
            return appointment;
        }

        public Widget getDetailsPanel() {
            return detailsPanel;
        }
    }

    class AppointmentDetailPanel extends Composite {

        private Label moreDetailsRow = new Label();

        public AppointmentDetailPanel(SimplePanel detailContainer, Appointment appt) {
            initWidget(detailContainer);

            // add the detail widget
            detailContainer.setStyleName("detailContainer");
            AbsolutePanel detailDecorator = new AbsolutePanel();
            detailDecorator.setStyleName("detailDecorator");
            detailContainer.setVisible(false);
            detailContainer.add(detailDecorator);

            if (appt.getLocation() != null && !appt.getLocation().isEmpty()) {
                AbsolutePanel whereRow = new AbsolutePanel();
                InlineLabel whereHeader = new InlineLabel("Where: ");
                whereHeader.setStyleName("detailHeader");
                whereRow.add(whereHeader);
                whereRow.add(new InlineLabel(appt.getLocation()));
                detailDecorator.add(whereRow);
            }
            if (appt.getCreatedBy() != null && !appt.getCreatedBy().isEmpty()) {
                AbsolutePanel creatorRow = new AbsolutePanel();
                InlineLabel creatorHeader = new InlineLabel("Creator: ");
                creatorHeader.setStyleName("detailHeader");
                creatorRow.add(creatorHeader);
                creatorRow.add(new InlineLabel(appt.getCreatedBy()));
                detailDecorator.add(creatorRow);
            }
            if (appt.getAttendees() != null && !appt.getAttendees().isEmpty()) {
                AbsolutePanel whoRow = new AbsolutePanel();
                InlineLabel whoHeader = new InlineLabel("Who: ");
                whoHeader.setStyleName("detailHeader");
                whoRow.add(whoHeader);
                for (int a = 0; a < appt.getAttendees().size(); a++) {
                    Attendee attendee = appt.getAttendees().get(a);
                    String comma = (a < appt.getAttendees().size() - 1) ? ", " : "";
                    String labelText = attendee.getEmail() + comma;
                    whoRow.add(new InlineLabel(labelText));
                }
                detailDecorator.add(whoRow);
            }

            DOM.setInnerHTML(moreDetailsRow.getElement(), "more details&#0187;");

            moreDetailsRow.setStyleName("moreDetailsButton");
            //moreDetailsRow.addClickHandler(appointmentClickHandler);
            detailDecorator.add(moreDetailsRow);
        }

        public Label getMoreDetailsLabel() {
            return moreDetailsRow;
        }
    }

    /**
     * FlexTable used to display a list of appointments.
     */
    private FlexTable appointmentGrid = new FlexTable();

    /**
     * List of appointment adapters, used to map widgets to the appointments
     * they represent.
     */
    private ArrayList<AgendaViewAppointmentAdapter> appointmentAdapterList = new ArrayList<AgendaViewAppointmentAdapter>();

    /**
     * DateTime format used to represent a day.
     */
    private static final DateTimeFormat DEFAULT_DATE_FORMAT = DateTimeFormat.getFormat("EEE MMM d");

    /**
     * DateTime format used when displaying an appointments start and end time.
     */
    private static final DateTimeFormat DEFAULT_TIME_FORMAT = DateTimeFormat.getShortTimeFormat();

    /**
     * Style used to format this view.
     */
    private String styleName = "gwt-cal-ListView";

    /**
     * Adds the calendar view to the calendar widget and performs required formatting.
     */
    public void attach(CalendarWidget widget) {
        super.attach(widget);

        appointmentGrid.setCellPadding(5);
        appointmentGrid.setCellSpacing(0);
        appointmentGrid.setBorderWidth(0);
        appointmentGrid.setWidth("100%");
        //DOM.setStyleAttribute(appointmentGrid.getElement(), "tableLayout", "fixed");
        calendarWidget.getRootPanel().add(appointmentGrid);
        calendarWidget.getRootPanel().add(appointmentGrid);
    }

    /**
     * Gets the style name associated with this particular view
     * @return Style name.
     */
    public String getStyleName() {
        return styleName;
    }

    @Override
    public void doLayout() {

        appointmentAdapterList.clear();
        appointmentGrid.clear();
        for (int i = appointmentGrid.getRowCount() - 1; i >= 0; i--) {
            appointmentGrid.removeRow(i);
        }

        //Get the start date, make sure time is 0:00:00 AM
        Date startDate = (Date) calendarWidget.getDate().clone();
        Date today = new Date();
        Date endDate = (Date) calendarWidget.getDate().clone();
        endDate.setDate(endDate.getDate() + 1);
        DateUtils.resetTime(today);
        DateUtils.resetTime(startDate);
        DateUtils.resetTime(endDate);

        int row = 0;

        for (int i = 0; i < calendarWidget.getDays(); i++) {

            // Filter the list by date
            List<Appointment> filteredList = AppointmentUtil.filterListByDate(calendarWidget.getAppointments(),
                    startDate, endDate);

            if (filteredList != null && filteredList.size() > 0) {

                appointmentGrid.setText(row, 0, DEFAULT_DATE_FORMAT.format(startDate));

                appointmentGrid.getCellFormatter().setVerticalAlignment(row, 0, HasVerticalAlignment.ALIGN_TOP);
                appointmentGrid.getFlexCellFormatter().setRowSpan(row, 0, filteredList.size());
                appointmentGrid.getFlexCellFormatter().setStyleName(row, 0, "dateCell");
                int startingCell = 1;

                //Row styles will alternate, so we set the style accordingly
                String rowStyle = (i % 2 == 0) ? "row" : "row-alt";

                //If a Row represents the current date (Today) then we style it differently
                if (startDate.equals(today))
                    rowStyle += "-today";

                for (Appointment appt : filteredList) {

                    // add the time range
                    String timeSpanString = DEFAULT_TIME_FORMAT.format(appt.getStart()) + " - "
                            + DEFAULT_TIME_FORMAT.format(appt.getEnd());
                    Label timeSpanLabel = new Label(timeSpanString.toLowerCase());
                    appointmentGrid.setWidget(row, startingCell, timeSpanLabel);

                    // add the title and description
                    FlowPanel titleContainer = new FlowPanel();
                    InlineLabel titleLabel = new InlineLabel(appt.getTitle());
                    titleContainer.add(titleLabel);
                    InlineLabel descLabel = new InlineLabel(" - " + appt.getDescription());
                    descLabel.setStyleName("descriptionLabel");
                    titleContainer.add(descLabel);
                    appointmentGrid.setWidget(row, startingCell + 1, titleContainer);

                    SimplePanel detailContainerPanel = new SimplePanel();
                    AppointmentDetailPanel detailContainer = new AppointmentDetailPanel(detailContainerPanel, appt);

                    appointmentAdapterList.add(new AgendaViewAppointmentAdapter(titleLabel, timeSpanLabel,
                            detailContainerPanel, detailContainer.getMoreDetailsLabel(), appt));

                    //add the detail container
                    titleContainer.add(detailContainer);

                    //add click handlers to title, date and details link
                    timeSpanLabel.addClickHandler(appointmentClickHandler);
                    titleLabel.addClickHandler(appointmentClickHandler);
                    detailContainer.getMoreDetailsLabel().addClickHandler(appointmentClickHandler);

                    // Format the Cells
                    appointmentGrid.getCellFormatter().setVerticalAlignment(row, startingCell,
                            HasVerticalAlignment.ALIGN_TOP);
                    appointmentGrid.getCellFormatter().setVerticalAlignment(row, startingCell + 1,
                            HasVerticalAlignment.ALIGN_TOP);
                    appointmentGrid.getCellFormatter().setStyleName(row, startingCell, "timeCell");
                    appointmentGrid.getCellFormatter().setStyleName(row, startingCell + 1, "titleCell");
                    appointmentGrid.getRowFormatter().setStyleName(row, rowStyle);

                    // increment the row
                    // make sure the starting column is reset to 0
                    startingCell = 0;
                    row++;
                }
            }

            // increment the date
            startDate.setDate(startDate.getDate() + 1);
            endDate.setDate(endDate.getDate() + 1);
        }
    }

    /**
     * Handles appointments being clicked. Based on the clicked widget will determine
     * exactly which appointment was clicked and may 1) expand / collaps the appointment
     * details 2) set the selected appointment or 3) trigger an appointment clicked
     * event.
     */
    private ClickHandler appointmentClickHandler = new ClickHandler() {

        public void onClick(ClickEvent event) {

            //get the appointment adapter based on the clicked widget
            AgendaViewAppointmentAdapter adapter = getAppointmentFromClickedWidget((Widget) event.getSource());

            if (adapter != null) {
                if (event.getSource().equals(adapter.getDetailsLabel())) {
                    //set the selected appointment
                    calendarWidget.setSelectedAppointment(adapter.getAppointment(), true);
                    //setSelectedAppointment(adapter.getAppointment(),false);
                    //calendarWidget.fireOpenEvent(adapter.getAppointment());
                } else {
                    //expand the panel if it is not yet expended
                    adapter.getDetailsPanel().setVisible(!adapter.getDetailsPanel().isVisible());
                }
            }
        }
    };

    /**
     * Given Widget w determine which appointment was clicked. This is necessary because
     * each appointment has 3 widgets that can be clicked - the title, date range and
     * description.
     * @param w Widget that was clicked.
     * @return Appointment mapped to that widget.
     */
    protected AgendaViewAppointmentAdapter getAppointmentFromClickedWidget(Widget w) {
        for (AgendaViewAppointmentAdapter a : appointmentAdapterList) {
            if (w.equals(a.dateLabel) || w.equals(a.detailsLabel) || w.equals(a.titleLabel)
                    || w.equals(a.getDetailsPanel())) {
                return a;
            }
        }
        return null;
    }

    @Override
    public void onDoubleClick(Element element, Event event) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSingleClick(Element element, Event event) {
        // TODO Auto-generated method stub

    }

    public void onMouseOver(Element element, Event event) {

    }

    @Override
    public void onAppointmentSelected(Appointment appt) {
        // TODO Auto-generated method stub

    }
}