Java/GWT/DatePicker

Материал из Java эксперт
Перейти к: навигация, поиск

DatePicker with GNU license

   <source lang="java">

From: http://code.google.ru/p/gwt-datepicker/ License: GNU Lesser public license!

package com.jexp.gwt.client; import com.google.gwt.i18n.client.*; import com.google.gwt.user.client.*; import com.google.gwt.user.client.ui.*; import com.google.gwt.core.client.*; import java.util.Date; /**

* Main class of the DatePicker. It extends the TextBox widget and manages a Date object.
* When it is clicked, it opens a PopupCalendar on which we can select a new date. 
* Example of use :
* * DatePicker datePicker = new DatePicker();
* RootPanel.get().add(datePicker);
*
* You can specify a theme (see the CSS file DatePickerStyle.css) and * the date to initialize the date picker. * Enjoy xD * @author Nicolas Wetzel (nicolas.wetzel@zenika.ru) * @author Jean-Philippe Dournel */

class DatePicker extends TextBox {

 private PopupCalendar popup;
 private Date date;
 private DateTimeFormat dateFormatter;
 
 {
   dateFormatter = DateUtil.getDateTimeFormat();
   popup = new PopupCalendar(this);
 }
 /**
  * Default constructor. It creates a DatePicker which shows the current
  * month.
  */
 public DatePicker() {
   super();
   setText("");  
   sinkEvents(Event.ONCHANGE | Event.ONKEYPRESS);
 }
 /**
  * Create a DatePicker which show a specific Date.
  * @param date Date to show
  */
 public DatePicker(Date date) {
   this();
   this.date = date;
   synchronizeFromDate();
 }
 
 /**
  * Create a DatePicker which uses a specific theme.
  * @param theme Theme name
  */
 public DatePicker(String theme) {
   this();
   setTheme(theme);
 }
 
 /**
  * Create a DatePicker which specifics date and theme.
  * @param date Date to show
  * @param theme Theme name
  */
 public DatePicker(Date date, String theme) {
   this();
   this.date = date;
   synchronizeFromDate();
   setTheme(theme);
 }
 /**
  * Return the Date contained in the DatePicker.
  * @return The Date
  */
 public Date getDate() {
   return date;
 }
 /**
  * Set the Date of the datePicker and synchronize it with the display.
  * @param value
  */
 public void setDate(Date value) {
   this.date = value;
   synchronizeFromDate();
 }
 /**
  * Return the theme name.
  * @return Theme name
  */
 public String getTheme() {
   return popup.getTheme();
 }
 /**
  * Set the theme name.
  * @param theme Theme name
  */
 public void setTheme(String theme) {
   popup.setTheme(theme);
 }
 public void onBrowserEvent(Event event) {
   switch (DOM.eventGetType(event)) {
     case Event.ONCLICK:
       showPopup();
     break;
     case Event.ONBLUR:
       popup.hidePopupCalendar();
     break;
     case Event.ONCHANGE:
       parseDate();
     break;
     case Event.ONKEYPRESS:
       if (DOM.eventGetKeyCode(event) == 13) {
         parseDate();
         showPopup();
         break;
       }
   }
 }
 
 /**
  * Display the date in the DatePicker.
  */
 public void synchronizeFromDate() {
   this.setText(dateFormatter.format(this.date));
 }
 /**
  * Display the PopupCalendar.
  */
 private void showPopup() {
   if (this.date != null) {
     popup.setDisplayedMonth(this.date);
   }
   popup.setPopupPosition(this.getAbsoluteLeft()+150, this.getAbsoluteTop());
   popup.displayMonth();
 }
 /**
  * Parse the date entered in the DatePicker.
  */
 private void parseDate() {
   date = dateFormatter.parse(getText());
   synchronizeFromDate();
 }

} /**

* Popup used by the datePicker. It represents a calendar and allows the user to
* select a date. It is localizable thanks to the DateTimerFormat class(GWT
* class) and the DateLocale class.
* 
* @author Nicolas Wetzel (nicolas.wetzel@zenika.ru)
* @author Jean-Philippe Dournel
*/

class PopupCalendar extends PopupPanel {

 private boolean leave;
 private String theme;
 private final DatePicker datePicker;
 private DateTimeFormat dayNameFormat;
 private DateTimeFormat monthFormat;
 private DateTimeFormat dayNumberFormat;
 private Label currentMonth;
 private Grid daysGrid;
 private Date displayedMonth;
 {
   this.leave = true;
   this.theme = "blue";
   this.dayNameFormat = DateTimeFormat.getFormat("E");
   this.monthFormat = DateTimeFormat.getFormat("MMMM yyyy");
   this.dayNumberFormat = DateTimeFormat.getFormat("d");
   this.daysGrid = new Grid(7, 7);
 }
 /**
  * Create a calendar popup. You have to call the displayMonth method to
  * display the the popup.
  * 
  * @param datePicker
  *            The date picker on which the popup is attached
  */
 public PopupCalendar(DatePicker datePicker) {
   super(true);
   this.datePicker = datePicker;
   this.setStyleName(theme + "-date-picker");
   VerticalPanel panel = new VerticalPanel();
   this.add(panel);
   sinkEvents(Event.ONBLUR);
   drawMonthLine(panel);
   drawWeekLine(panel);
   drawDayGrid(panel);
 }
 
 /**
  * Return the month displayed by the PopupCalendar.
  * @return a Date pointing to the month
  */
 public Date getDisplayedMonth() {
   return displayedMonth;
 }
 /**
  * Set the month which is display by the PopupCalendar.
  * @param displayedMonth The Date to display
  */
 public void setDisplayedMonth(Date displayedMonth) {
   this.displayedMonth = displayedMonth;
 }
 
 /**
  * Return the theme used by the PopupCalendar.
  * @return Name of the theme
  */
 public String getTheme() {
   return this.theme;
 }
 /**
  * Set the theme used by the PopupCalendar.
  * @param theme Name of the theme
  */
 public void setTheme(String theme) {
   this.theme = theme;
   this.setStyleName(theme + "-date-picker");
 }  
 /**
  * Refresh the PopupCalendar and show it.
  */
 public void displayMonth() {
   if (this.displayedMonth == null) {
     if (datePicker.getDate() != null)
       this.displayedMonth = datePicker.getDate();
     else {
       this.displayedMonth = new Date();
     }
   }
   this.drawLabelMoisAnnee();
   this.drawDaysGridContent(this.displayedMonth);
   show();
 }
 /**
  * This method is destined to be used by the DatePicker in case of focus lost.
  * It creates a delay before the popup hides to allows the popup to catch
  * a click and eventually update the Date of the DatePicker.
  */
 public void hidePopupCalendar() {
   DeferredCommand.addCommand(new Command() {
     public void execute() {
       Timer t = new Timer() {
         public void run() {
           if (leave) {
             hide();
           } else {
             leave = true;
           }
         }
       };
       t.schedule(300);
     }
   });
 }
 /**
  * Draw the monthLine with contains navigations buttons (change the month
  * and the year) and displayed the displayed month.
  * 
  * @param panel
  *            The panel contained in the popup
  */
 private void drawMonthLine(Panel panel) {
   Grid monthLine = new Grid(1, 5);
   monthLine.setStyleName(theme + "-" + "month-line");
   HTMLTable.CellFormatter monthCellFormatter = monthLine.getCellFormatter();
   Label previousYear = new Label("?);
   previousYear.addClickListener(new ClickListener() {
     public void onClick(Widget sender) {
       leave = false;
       PopupCalendar.this.changeMonth(-12);
     }
   });
   monthLine.setWidget(0, 0, previousYear);
   Label previousMonth = new Label("?);
   previousMonth.addClickListener(new ClickListener() {
     public void onClick(com.google.gwt.user.client.ui.Widget sender) {
       leave = false;
       PopupCalendar.this.changeMonth(-1);
     };
   });
   monthLine.setWidget(0, 1, previousMonth);
   monthCellFormatter.setWidth(0, 2, "60%");
   currentMonth = new Label();
   currentMonth.addClickListener(new ClickListener() {
     public void onClick(Widget sender) {
       leave = false;
     }
   });
   monthLine.setWidget(0, 2, currentMonth);
   Label nextMonth = new Label("?);
   nextMonth.addClickListener(new ClickListener() {
     public void onClick(com.google.gwt.user.client.ui.Widget sender) {
       leave = false;
       PopupCalendar.this.changeMonth(1);
     };
   });
   monthLine.setWidget(0, 3, nextMonth);
   Label nextYear = new Label("?);
   nextYear.addClickListener(new ClickListener() {
     public void onClick(Widget sender) {
       leave = false;
       PopupCalendar.this.changeMonth(12);
     }
   });
   monthLine.setWidget(0, 4, nextYear);
   panel.add(monthLine);
 }
 /**
  * Draw the week line which displays first letter of week days. example : S
  * M T ....etc
  * 
  * @param panel
  *            The panel contained in the popup
  */
 private void drawWeekLine(Panel panel) {
   Grid weekLine = new Grid(1, 7);
   weekLine.setStyleName(theme + "-" + "week-line");
   Date weekFirstday = DateUtil.getWeekFirstDay();
   for (int i = 0; i < 7; i++) {
     weekLine.setText(0, i, dayNameFormat.format(
         DateUtil.addDays(weekFirstday, i)).substring(0, 1)
         .toUpperCase());
   }
   panel.add(weekLine);
 }
 /**
  * Display the grid which contains the days. When a day is clicked, it
  * updates the Date contained in the DatePicker.
  * @param panel
  *            The panel contained in the popup
  */
 private void drawDayGrid(Panel panel) {
   this.daysGrid.addTableListener(new TableListener() {
     public void onCellClicked(SourcesTableEvents sender, int row,
         int cell) {
       Date selectedDay = DateUtil.addDays(
           getDaysGridOrigin(displayedMonth), row * 7 + cell);
       datePicker.setDate(selectedDay);
       datePicker.synchronizeFromDate();
       PopupCalendar.this.hide();
       leave = true;
     };
   });
   daysGrid.setStyleName(theme + "-" + "day-grid");
   panel.add(daysGrid);
 }
 /**
  * Update the Label which shows the displayed month (in the month line).
  */
 private void drawLabelMoisAnnee() {
   currentMonth
       .setText(monthFormat.format(this.displayedMonth).toLowerCase());
 }
 /**
  * Draw the days into the days grid. Days drawn are the days of the displayed month
  * and few days after and before the displayed month.
  * @param displayedMonth Date of the displayed month
  */
 private void drawDaysGridContent(Date displayedMonth) {
   HTMLTable.CellFormatter cfJours = daysGrid.getCellFormatter();
   Date cursor = this.getDaysGridOrigin(displayedMonth);
   for (int i = 0; i < 7; i++) {
     for (int j = 0; j < 7; j++) {
       daysGrid.setText(i, j, dayNumberFormat.format(cursor));
       cfJours.removeStyleName(i, j, theme + "-" + "selected");
       cfJours.removeStyleName(i, j, theme + "-"
           + "current-month-selected");
       cfJours.removeStyleName(i, j, theme + "-" + "other-day");
       cfJours.removeStyleName(i, j, theme + "-"
           + "current-month-other-day");
       cfJours.removeStyleName(i, j, theme + "-" + "week-end");
       cfJours.removeStyleName(i, j, theme + "-"
           + "current-month-week-end");
       if (datePicker.getDate() != null
           && DateUtil.areEquals(datePicker.getDate(), cursor))
         if (displayedMonth.getMonth() == cursor.getMonth())
           cfJours.addStyleName(i, j, theme + "-"
               + "current-month-selected");
         else
           cfJours.addStyleName(i, j, theme + "-" + "selected");
       else if (DateUtil.isInWeekEnd(cursor))
         if (displayedMonth.getMonth() == cursor.getMonth())
           cfJours.addStyleName(i, j, theme + "-"
               + "current-month-week-end");
         else
           cfJours.addStyleName(i, j, theme + "-" + "week-end");
       else if (displayedMonth.getMonth() == cursor.getMonth())
         cfJours.addStyleName(i, j, theme + "-"
             + "current-month-other-day");
       else
         cfJours.addStyleName(i, j, theme + "-" + "other-day");
       cursor = DateUtil.addDays(cursor, 1);
     }
   }
 }
 /**
  * Change the displayed month.
  * @param i Number of month to add to the displayed month
  */
 protected void changeMonth(int i) {
   this.displayedMonth = DateUtil.addMonths(this.displayedMonth, i);
   this.displayMonth();
 }
 /**
  * Return the first day to display. If the month first day is after the 5th
  * day of the week, it return the first day of the week. Else, it returns
  * the first day of the week before.
  * 
  * @param displayedMonth
  * @return The first day to display in the grid
  */
 private Date getDaysGridOrigin(Date displayedMonth) {
   int currentYear = displayedMonth.getYear();
   int currentMonth = displayedMonth.getMonth();
   HTMLTable.CellFormatter cfJours = daysGrid.getCellFormatter();
   Date monthFirstDay = new Date(currentYear, currentMonth, 1);
   int indice = DateUtil.getWeekDayIndex(monthFirstDay);
   Date origineTableau;
   if (indice > 4) {
     origineTableau = DateUtil.getWeekFirstDay(monthFirstDay);
   } else {
     origineTableau = DateUtil.getWeekFirstDay(DateUtil.addDays(
         monthFirstDay, -7));
   }
   return origineTableau;
 }

}

/**

* Utility class which ease the use of Date classes with the DatePicker.
* 
* @author Nicolas Wetzel (nicolas.wetzel@zenika.ru)
* @author Jean-Philippe Dournel
* 
*/

class DateUtil {

 /**
  * Add days to the Date object.
  * 
  * @param date
  *            The Date to modify
  * @param days
  *            Number of day to add
  * @return The modified Date object
  */
 public static Date addDays(Date date, int days) {
   return new Date(date.getYear(), date.getMonth(), date.getDate() + days);
 }
 /**
  * Add months to the Date object.
  * 
  * @param date
  *            The Date to modify
  * @param months
  *            Number of month to add
  * @return The modified Date object
  */
 public static Date addMonths(Date date, int months) {
   return new Date(date.getYear(), date.getMonth() + months, date
       .getDate());
 }
 /**
  * Test if two Date objects represent the same day. It tests if the days,
  * the months and the years are equals.
  * 
  * @param date1
  *            First Date
  * @param date2
  *            Second Date
  * @return true if the days are the same
  */
 public static boolean areEquals(Date date1, Date date2) {
   return date1.getDate() == date2.getDate()
       && date1.getMonth() == date2.getMonth()
       && date1.getYear() == date2.getYear();
 }
 /**
  * Return a Date object with represents the first day of a month contained
  * in another Date object.
  * 
  * @param date The Date containing the month
  * @return The first day of the month
  */
 public static Date getMonthFirstDay(Date date) {
   Date current = date;
   while (current.getDate() != 1) {
     current = new Date(current.getYear(), current.getMonth(), current
         .getDate() - 1);
   }
   return current;
 }
 /**
  * Returns the place of the day in the week.
  * Example : sunday = 0, monday = 1 ....
  * Depends on the locale. 
  * @param day The day
  * @return The place of the day
  */
 public static int getWeekDayIndex(Date day) {
   DateLocale locale = (DateLocale) GWT.create(DateLocale.class);
   int[] daysOrder = locale.getDAY_ORDER();
   int dayIndex = day.getDay();
   for (int i = 0; i < 7; i++) {
     if (dayIndex == daysOrder[i]) {
       return i;
     }
   }
   return -1;
 }
 /**
  * Returns the first day of the current week.
  * @return Date pointing to the first day 
  */
 public static Date getWeekFirstDay() {
   return getWeekFirstDay(new Date());
 }
 /**
  * Returns the first day of the week containing a Date object.
  * @param date The Date
  * @return The Date pointing to the first day
  */
 public static Date getWeekFirstDay(Date date) {
   Date current = date;
   DateLocale local = (DateLocale) GWT.create(DateLocale.class);
   int firstDay = local.getDAY_ORDER()[0];
   while (current.getDay() != firstDay) {
     current = new Date(current.getYear(), current.getMonth(), current
         .getDate() - 1);
   }
   return current;
 }
 /**
  * Test if a day is a weekend day.
  * @param day The Date to test
  * @return true if the Date is a weekend day
  */
 public static boolean isInWeekEnd(Date day) {
   int dayIndex = day.getDay();
   return (dayIndex == 0 | dayIndex == 6) ? true : false;
 }
 /**
  * Get the DateTimeFormat corresponding to the locale.
  * @return DateTimeFormat
  */
 public static DateTimeFormat getDateTimeFormat() {
   DateLocale locale = (DateLocale) GWT.create(DateLocale.class);
   DateTimeFormat format = locale.getDateTimeFormat();
   return format;
 }

}

/**

* This interface is used to extend the localization property
* of the DateTimeFormat of GWT. It adds the support of the days order 
* which is not the same in all countries. 
* It uses the Localizable interface. See GWT documentation for more detail.
* @author Jean-Philippe Dournel
*
*/

interface DateLocale extends Localizable{

 /**
  * Returns an array containing the order of days in the week.
  * For a week starting by the monday, it"ll return {1,2,3,4,5,6,0}.
  * @return Array of days index
  */
 public int[] getDAY_ORDER();
 
 /**
  * Return the DateTimeFormat corresponding to the date pattern used in
  * the country. For example : "dd/MM/yyyy" in France and "MM/dd/yyyy" in the US.
  * @return DateTimeFormat
  */
 public DateTimeFormat getDateTimeFormat();
 

} /**

* DateLocale implementation for US.
* @author Jean-Philippe Dournel
*
*/

class DateLocale_ implements DateLocale {

 public int[] DAYS_ORDER = { 0, 1, 2, 3, 4, 5, 6 };
 public int[] getDAY_ORDER() {
   return DAYS_ORDER;
 }
 public DateTimeFormat getDateTimeFormat() {
   DateTimeFormat format = DateTimeFormat.getFormat("MM/dd/yyyy");
   return format;
 }

} /**

* DateLocale implementation for UK.
* @author Jean-Philippe Dournel
*
*/

class DateLocale_en_GB implements DateLocale {

 public int[] DAYS_ORDER = { 1, 2, 3, 4, 5, 6, 0 };
 public int[] getDAY_ORDER() {
   return DAYS_ORDER;
 }
 public DateTimeFormat getDateTimeFormat() {
   DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy");
   return format;
 }

} /**

* DateLocale implementation for french-speaking Canada.
* @author Jean-Philippe Dournel
*
*/

class DateLocale_fr_CA implements DateLocale {

 public int[] DAYS_ORDER = { 0, 1, 2, 3, 4, 5, 6 };
 public int[] getDAY_ORDER() {
   return DAYS_ORDER;
 }
 
 public DateTimeFormat getDateTimeFormat() {
   DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy");
   return format;
 }

} /**

* DateLocale implementation for France.
* @author Jean-Philippe Dournel
*
*/

class DateLocale_fr implements DateLocale {

 public int[] DAYS_ORDER = { 1, 2, 3, 4, 5, 6, 0 };
 public int[] getDAY_ORDER() {
   return DAYS_ORDER;
 }
 
 public DateTimeFormat getDateTimeFormat() {
   DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy");
   return format;
 }
 

} public class GWTClient implements EntryPoint{

 public void onModuleLoad() {
   DatePicker datePicker = new DatePicker("blue");
   RootPanel.get().add(datePicker);
   
 }

}


      </source>
   
  
 
  



Simple Calendar Widget for GWT

   <source lang="java">

package com.jexp.gwt.client; import com.google.gwt.core.client.*; import com.google.gwt.user.client.*; import java.util.Date; import com.google.gwt.user.client.ui.*; public class GWTClient implements EntryPoint {

   FlowPanel fp = new FlowPanel();
 public GWTClient() {
       final CalendarWidget calendar = new CalendarWidget();
         calendar.addChangeListener(new ChangeListener() {
       
         public void onChange(Widget sender) {
           Window.alert("Date selected: " + calendar.getDate());
         }
       });
    fp.add(calendar);
 }
 public void onModuleLoad() {
   RootPanel.get().add(fp);
 }

} /* Simple Calendar Widget for GWT Copyright (C) 2006 Alexei Sokolov http://gwt.ruponents.googlepages.ru/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

  • /

//package com.gwt.ruponents.client;

class CalendarWidget extends Composite 
   implements ClickListener, SourcesChangeEvents {
 private class NavBar extends Composite implements ClickListener{
   public final DockPanel bar = new DockPanel();
   public final Button prevMonth = new Button("<", this);
   public final Button prevYear = new Button("<<", this);
   public final Button nextYear = new Button(">>", this);
   public final Button nextMonth = new Button(">", this);
   public final HTML title = new HTML();
   private final CalendarWidget calendar;
   public NavBar(CalendarWidget calendar) {
     this.calendar = calendar;
     setWidget(bar);
     bar.setStyleName("navbar");
     title.setStyleName("header");
     HorizontalPanel prevButtons = new HorizontalPanel();
     prevButtons.add(prevMonth);
     prevButtons.add(prevYear);
     HorizontalPanel nextButtons = new HorizontalPanel();
     nextButtons.add(nextYear);
     nextButtons.add(nextMonth);
     bar.add(prevButtons, DockPanel.WEST);
     bar.setCellHorizontalAlignment(prevButtons, DockPanel.ALIGN_LEFT);
     bar.add(nextButtons, DockPanel.EAST);
     bar.setCellHorizontalAlignment(nextButtons, DockPanel.ALIGN_RIGHT);
     bar.add(title, DockPanel.CENTER);
     bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);
     bar.setCellHorizontalAlignment(title, HasAlignment.ALIGN_CENTER);
     bar.setCellVerticalAlignment(title, HasAlignment.ALIGN_MIDDLE);
     bar.setCellWidth(title, "100%");
   }
   public void onClick(Widget sender) {
     if (sender == prevMonth) {
       calendar.prevMonth();
     } else if (sender == prevYear) {
       calendar.prevYear();
     } else if (sender == nextYear) {
       calendar.nextYear();
     } else if (sender == nextMonth) {
       calendar.nextMonth();
     }
   }
 }
 private static class CellHTML extends HTML {
   private int day;
      
   public CellHTML(String text, int day) {
     super(text);
     this.day = day;
   }
      
   public int getDay() {
     return day;
   }
 }
 
 private final NavBar navbar = new NavBar(this);
 private final DockPanel outer = new DockPanel();
 private final Grid grid = new Grid(6, 7) {
   public boolean clearCell(int row, int column) {
     boolean retValue = super.clearCell(row, column);
          
     Element td = getCellFormatter().getElement(row, column);
     DOM.setInnerHTML(td, "");
     return retValue;
   }
 };
 private Date date = new Date();
 private ChangeListenerCollection changeListeners;
  
 private String[] days = new String[] { "Sunday", "Monday", "Tuesday",
     "Wednesday", "Thursday", "Friday", "Saturday" };
 private String[] months = new String[] { "January", "February", "March",
     "April", "May", "June", "July", "August", "September", "October",
     "November", "December" };
 public CalendarWidget() {
   setWidget(outer);
   grid.setStyleName("table");
   grid.setCellSpacing(0);
   outer.add(navbar, DockPanel.NORTH);
   outer.add(grid, DockPanel.CENTER);
   drawCalendar();
   setStyleName("CalendarWidget");
 }
 private void drawCalendar() {
   int year = getYear();
   int month = getMonth();
   int day = getDay();
   setHeaderText(year, month);
   grid.getRowFormatter().setStyleName(0, "weekheader");
   for (int i = 0; i < days.length; i++) {
     grid.getCellFormatter().setStyleName(0, i, "days");
     grid.setText(0, i, days[i].substring(0, 3));
   }
   Date now = new Date();
   int sameDay = now.getDate();
   int today = (now.getMonth() == month && now.getYear()+1900 == year) ? sameDay : 0;
      
   int firstDay = new Date(year - 1900, month, 1).getDay();
   int numOfDays = getDaysInMonth(year, month);
   int j = 0;
   for (int i = 1; i < 6; i++) {
     for (int k = 0; k < 7; k++, j++) {
       int displayNum = (j - firstDay + 1);
       if (j < firstDay || displayNum > numOfDays) {
         grid.getCellFormatter().setStyleName(i, k, "empty");
         grid.setHTML(i, k, " ");
       } else {
         HTML html = new CellHTML(
           "" + String.valueOf(displayNum) + "", 
           displayNum);
         html.addClickListener(this);
         grid.getCellFormatter().setStyleName(i, k, "cell");
         if (displayNum == today) {
           grid.getCellFormatter().addStyleName(i, k, "today");
         } else if (displayNum == sameDay) {
           grid.getCellFormatter().addStyleName(i, k, "day");
         }
         grid.setWidget(i, k, html);
       }
     }
   }
 }
 protected void setHeaderText(int year, int month) {
   navbar.title.setText(months[month] + ", " + year);
 }
  
 private int getDaysInMonth(int year, int month) {
   switch (month) {
     case 1:
       if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
         return 29; // leap year
       else
         return 28;
     case 3:
       return 30;
     case 5:
       return 30;
     case 8:
       return 30;
     case 10:
       return 30;
     default:
       return 31;
   }
 }
 public void prevMonth() {
   int month = getMonth() - 1;
   if (month < 0) {
     setDate(getYear() - 1, 11, getDay());
   } else {
     setMonth(month);
   }
   drawCalendar();
 }
 public void nextMonth() {
   int month = getMonth() + 1;
   if (month > 11) {
     setDate(getYear() + 1, 0, getDay());
   } else {
     setMonth(month);
   }
   drawCalendar();
 }
  
 public void prevYear() {
   setYear(getYear() - 1);
   drawCalendar();
 }
 public void nextYear() {
   setYear(getYear() + 1);
   drawCalendar();
 }
 private void setDate(int year, int month, int day) {
   date = new Date(year - 1900, month, day);
 }
  
 private void setYear(int year) {
   date.setYear(year - 1900);
 }
 private void setMonth(int month) {
   date.setMonth(month);
 }
 public int getYear() {
   return 1900 + date.getYear();
 }
 public int getMonth() {
   return date.getMonth();
 }
 public int getDay() {
   return date.getDate();
 }
  
 public Date getDate() {
   return date;
 }
 public void onClick(Widget sender) {
   CellHTML cell = (CellHTML)sender;
   setDate(getYear(), getMonth(), cell.getDay());
   drawCalendar();
   if (changeListeners != null) {
     changeListeners.fireChange(this);
   }
 }
 public void addChangeListener(ChangeListener listener) {
   if (changeListeners == null)
     changeListeners = new ChangeListenerCollection();
   changeListeners.add(listener);
 }
 public void removeChangeListener(ChangeListener listener) {
   if (changeListeners != null)
     changeListeners.remove(listener);
 }

} /// .CalendarWidget {

 border: 1px solid #ACA899;

} .CalendarWidget .navbar {

 width: 100%;
 background-color: #C3D9FF;
 vertical-align: middle;
 border-bottom: 1px solid #ACA899;

} .CalendarWidget .navbar .gwt-Button {

 padding-left: 5px;
 padding-right: 5px;

} .CalendarWidget .table {

 font: 10pt sans-serif;
 text-align: center;

} .CalendarWidget .weekheader {

 background-color: #ACA899;

} .CalendarWidget .weekheader .days {

 width: 3em;

} .CalendarWidget .cell {

 cursor:pointer;

} .CalendarWidget .cell .gwt-HTML {

 border: 1px solid #ACA899;

} .CalendarWidget .cell .gwt-HTML span {

 width: 100%;
 height: 100%;
 line-height: 2em;

} .CalendarWidget .today .gwt-HTML {

 background-color: #C3D9FF;

} .CalendarWidget .day .gwt-HTML {

 border: 1px solid #C3D9FF;

}

      </source>