DatePicker with GNU license : DatePicker « GWT « Java






DatePicker with GNU license

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


package com.java2s.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. <br>
 * Example of use :  <br>
 * <code>
 * DatePicker datePicker = new DatePicker();<br>
 * RootPanel.get().add(datePicker);<br>
 * </code>
 * 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.com)
 * @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.com)
 * @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.com)
 * @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);
    
  }
}



           
         
    
  








GWT-calendar2.zip( 7 k)

Related examples in the same category

1.Simple Calendar Widget for GWT
2.Using DateItem to create date picker (Smart GWT)Using DateItem to create date picker (Smart GWT)
3.DateItem with direct date input (Smart GWT)DateItem with direct date input (Smart GWT)
4.Set default value for DateItem (Smart GWT)Set default value for DateItem (Smart GWT)
5.DatePicker with selection listener (Ext GWT)DatePicker with selection listener (Ext GWT)