Java tutorial
/* * Copyright 2007 Manuel Carrasco Moino. (manuel_carrasco at users.sourceforge.net) * http://code.google.com/p/gwtchismes * * 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 com.google.code.p.gwtchismes.client; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Vector; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; 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.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.DockPanel; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.HasHTML; import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.MenuBar; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; /** * <p> * <b>Abstract class used for creating complex and customized DatePickers.</b> * </p> * @author Manuel Carrasco Moino * * <h3>Features</h3> * <ul> * <li>It can be implemented as a modal and dragable dialog or it can be included into a standard panel.</li> * <li>It can be in a decorated box with rounded corners</li> * <li>The dialog position is calculated on the fly to avoid be positioned out of the viewport area</li> * <li>Display multiple months</li> * <li>Month selector menu</li> * <li>Configurable restrictions: minimalDate, maximalDate</li> * <li>Configurable texts: caption, help and buttons</li> * <li>Configurable button style: flat, rounded</li> * <li>Configurable button layout (6 rows, 3 at top and 3 at bottom)</li> * <li>Uses GWT-i18n for date formating.</li> * <li>It extends GWTSimpleDatePicker that has useful methods for date manipulation</li> * </ul> * * <h3>Example</h3> * <pre> public class GWTCDatePickerCustom extends GWTCDatePickerAbstract { // You have to call createInstance in the constructor public GWTCDatePickerCustom() { createInstance(CONFIG_DIALOG | CONFIG_BACKGROUND); } // You have to implement drawDatePickerWidget // You can use either configure() or layoutButtons() & layoutCalendar() Override void drawDatePickerWidget() { int monthsToDisplay = 6; int numberOfColumns = 2; int monthsIncrement = 6; int maxMonthsInMenu = 32; // Buttons can be placed in any of the 6 availabe rows, // @see com.google.code.p.gwtchismes.client.GWTCDatePickerAbstract#configure() for a detailed explanation. String buttonsLayout = "? x;p<m>n"; configure(buttonsLayout, monthsToDisplay, numberOfColumns, monthsIncrement, maxMonthsInMenu); setMinimalDate(increaseMonth(new Date(), -24)); setMaximalDate(increaseMonth(new Date(), 24)); addStyleName("GWTCDatePicker-custom"); } } * </pre> * * <h3>CSS Style Rules</h3> * <ul> * <li>.GWTCDatePicker { GWTCDatePicket container }</li> * <li>.GWTCDatePicker .GWTCDatePicker-help { help dialog } </li> * <li>.GWTCDatePicker-dlg { Dependent style when it is a modal dialog } </li> * <li>.GWTCDatePicker-no-dlg { Dependent style when it is not placed in a dialog } </li> * <li>.GWTCDatePicker-box { Dependent style when it is in a GWTCBox } </li> * <li>.GWTCDatePicker-no-box { Dependent style when it is not in a GWTCBox } </li> * <li>.GWTCDatePicker .Caption { calendar title }</li> * <li>.GWTCDatePicker .panelButtons { panel container with navigation buttons at top }</li> * <li>.GWTCDatePicker .panelButtons .buttonsRow_1 { 1st row in top buttons panel }</li> * <li>.GWTCDatePicker .panelButtons .buttonsRow_2 { 2nd row in top buttons panel }</li> * <li>.GWTCDatePicker .panelButtons .buttonsRow_3 { 3th row in top buttons panel }</li> * <li>.GWTCDatePicker .panelButtonsBottom { panel container with navigation buttons at bottom }</li> * <li>.GWTCDatePicker .panelButtonsBottom .buttonsRow_1 { 1st row in bottom buttons panel }</li> * <li>.GWTCDatePicker .panelButtonsBottom .buttonsRow_2 { 2nd row in bottom buttons panel }</li> * <li>.GWTCDatePicker .panelButtonsBottom .buttonsRow_3 { 3th row in bottom buttons panel }</li> * * <li>.GWTCDatePicker .panelMonths { container for the displayed months }</li> * <li>.GWTCDatePicker .panelMonths .monthLabels { labels with the header of each displayed month }</li> * <li>.GWTCDatePicker .panelMonths .monthSeparator { cell between two months }</li> * * <li>.GWTCDatePicker-MenuBar { horizontal and vertical menu selector items }</li> * <li>.GWTCDatePicker-MenuBar-horizontal { horizontal item of menu selector }</li> * <li>.GWTCDatePicker-MenuBar-vertical { vertical items of menu selector }</li> * </ul> * * <h3>Inherited CSS Styles</h3> * <ul> * <li>.GWTCDatePicker .weekHeader { week headers row}</li> * <li>.GWTCDatePicker .weekHeader .cellDayNames { cells with day names} </li> * <li>.GWTCDatePicker .panelDays { panel that contains all days }</li> * <li>.GWTCDatePicker .panelDays .cellEmpty { cell without days }</li> * <li>.GWTCDatePicker .panelDays .cellDays { primary style on each cell that has days }</li> * <li>.GWTCDatePicker .panelDays .invalidDay { cell with a day which can not be selected because are out of the allowed interval }</li> * <li>.GWTCDatePicker .panelDays .validDay { cell with selectable day }</li> * <li>.GWTCDatePicker .panelDays .today { today } </li> * <li>.GWTCDatePicker .panelDays .selectedDay { selected day }</li> * <li>.GWTCDatePicker .panelDays .afterSelected { days after the selected day and before the maximal day } </li> * <li>.GWTCDatePicker .panelDays .beforeSelected { days before the selected day and after the minimal day}</li> * <li>.GWTCDatePicker-MenuBar .gwt-MenuItem { month selector items }</li> * <li>.GWTCDatePicker-MenuBar .gwt-MenuItem-selected { selected month selector items }</li> * </ul> * */ public abstract class GWTCDatePickerAbstract extends GWTCSimpleDatePicker { protected static final String styleName = "GWTCDatePicker"; protected static final String StyleHelp = styleName + "-help"; protected static final String StyleDialog = "dialog"; protected static final String StyleEmbeded = "embeded"; protected static final String StyleBox = "box"; protected static final String StyleNoBox = "no-box"; protected static final String StyleCButtonsTop = "panelButtons"; protected static final String StyleCButtonsBottom = "panelButtonsBottom"; protected static final String StyleCButtonsRow = "buttonsRow_"; protected static final String StyleMonthGrid = "panelMonths"; protected static final String StyleMonthLabels = "monthLabels"; protected static final String StyleMonthLabel = "monthLabel"; protected static final String StyleMonthSeparator = "monthSeparator"; protected static final String StyleMonthCell = "monthCells"; static int constant_cont = 0; public static final int CONFIG_DEFAULT = constant_cont; public static final int CONFIG_DIALOG = (int) Math.pow(2, constant_cont++); public static final int CONFIG_ROUNDED_BOX = (int) Math.pow(2, constant_cont++); public static final int CONFIG_NO_AUTOHIDE = (int) Math.pow(2, constant_cont++); public static final int CONFIG_NO_ANIMATION = (int) Math.pow(2, constant_cont++); public static final int CONFIG_BACKGROUND = (int) Math.pow(2, constant_cont++); public static final int CONFIG_FLAT_BUTTONS = (int) Math.pow(2, constant_cont++); public static final int CONFIG_STANDARD_BUTTONS = (int) Math.pow(2, constant_cont++); public static final String MONTH_FORMAT = "MMMM, yyyy"; protected GWTCAlert helpDlg = new GWTCAlert(GWTCAlert.OPTION_ROUNDED_BLUE); protected String helpStr = "Calendar-Picker is a component of GWTChismes library.\n" + "(c) Manuel Carrasco 2007\n" + "http://code.google.com/p/gwtchismes\n\n" + "Navigation buttons:\n" + "\u003c Previous Month\n" + "\u003e Next Month\n" + "\u00AB Previous Year\n" + "\u00BB Next Year\n" + "- Actual Month\n" + "x Close\n "; // Containers protected GWTCModalBox calendarDlg = null; protected Panel outer; // Dates panel protected final FlexTable calendarGrid = new FlexTable(); // Navigation Buttons protected final DockPanel navButtonsTop = new DockPanel(); protected final DockPanel navButtonsBottom = new DockPanel(); protected final DockPanel topButtonsRow1 = new DockPanel(); protected final DockPanel topButtonsRow0 = new DockPanel(); protected final DockPanel topButtonsRow2 = new DockPanel(); protected final DockPanel bottomButtonsRow0 = new DockPanel(); protected final DockPanel bottomButtonsRow1 = new DockPanel(); protected final DockPanel bottomButtonsRow2 = new DockPanel(); protected final DockPanel leftButtons = new DockPanel(); protected final DockPanel rightButtons = new DockPanel(); protected Button helpBtn; protected Button closeBtn; protected Button todayBtn; protected Button prevMBtn; protected Button prevYBtn; protected Button nextMBtn; protected Button nextYBtn; // Month selector menu MenuBar monthSelectorHeader = new MenuBar(); Vector<Label> monthHeaders = new Vector<Label>(); protected MenuBar monthMenu = new MenuBar(true); // Vector of montly datepickers to display Vector<GWTCSimpleDatePicker> simpleDatePickers = new Vector<GWTCSimpleDatePicker>(); // Configuration parameters protected int monthColumns = 3; protected int monthSelector = 12; protected int monthStep = 1; private boolean showWeekNumbers = false; private boolean clickOnWeekNumbers = false; /** * Classes implementing this abstract class, have to implement this method */ protected abstract void drawDatePickerWidget(); /** * Creates the calendar instance based in the configuration provided. * * Options can be passed joining these using the or bit wise operator * <ul> * <li>CONFIG_DIALOG show as modal dialog</li> * <li>CONFIG_ROUNDED_BOX wrap with a rounded-corner box</li> * <li>CONFIG_NO_AUTOHIDE don't autohide dialog when the user click out of the picker</li> * <li>CONFIG_NO_ANIMATION don't animate the dialog box when it is showed/hidden</li> * <li>CONFIG_NO_ANIMATION don't animate the dialog box when it is showed/hidden</li> * <li>CONFIG_BACKGROUND show a semitransparent background covering all the document</li> * <li>CONFIG_FLAT_BUTTONS use native Buttons instead of GWTCButton also add the dependent class 'flat'</li> * <li>CONFIG_STANDARD_BUTTONS use native browser Buttons instead of GWTCButton</li> * </ul> */ public void initialize(int config) { int buttonsType = config & CONFIG_FLAT_BUTTONS | config & CONFIG_STANDARD_BUTTONS; helpBtn = createButton(buttonsType, "?", this); closeBtn = createButton(buttonsType, "x", this); todayBtn = createButton(buttonsType, "-", this); prevMBtn = createButton(buttonsType, "\u003c", this); prevYBtn = createButton(buttonsType, "\u00AB", this); nextMBtn = createButton(buttonsType, "\u003e", this); nextYBtn = createButton(buttonsType, "\u00BB", this); if ((config & CONFIG_DIALOG) == CONFIG_DIALOG) { int opt = 0; if ((config & CONFIG_ROUNDED_BOX) == CONFIG_ROUNDED_BOX) { opt |= GWTCModalBox.OPTION_ROUNDED_FLAT; } if ((config & CONFIG_BACKGROUND) != CONFIG_BACKGROUND) { opt |= GWTCModalBox.OPTION_DISABLE_BACKGROUND; if ((config & CONFIG_NO_AUTOHIDE) == CONFIG_NO_AUTOHIDE) { opt |= GWTCModalBox.OPTION_DISABLE_AUTOHIDE; } } calendarDlg = new GWTCModalBox(opt); calendarDlg.setAnimationEnabled((config & CONFIG_NO_ANIMATION) != CONFIG_NO_ANIMATION); outer = calendarDlg; initWidget(new DockPanel()); setStyleName(styleName); addStyleDependentName(StyleDialog); setZIndex(999); } else { if ((config & CONFIG_ROUNDED_BOX) == CONFIG_ROUNDED_BOX) { outer = new GWTCBox(GWTCBox.STYLE_FLAT); } else { outer = new VerticalPanel(); } String s = outer.getStyleName(); initWidget(outer); setStyleName(styleName); addStyleDependentName(StyleEmbeded); if (s != null && s.length() > 0) addStyleName(s); } helpDlg.addStyleName(StyleHelp); navButtonsTop.setStyleName(StyleCButtonsTop); navButtonsBottom.setStyleName(StyleCButtonsBottom); calendarGrid.setStyleName(StyleMonthGrid); navButtonsTop.setWidth("100%"); calendarGrid.setWidth("100%"); navButtonsBottom.setWidth("100%"); if ((config & CONFIG_ROUNDED_BOX) == CONFIG_ROUNDED_BOX) addStyleDependentName(StyleBox); else addStyleDependentName(StyleNoBox); if ((config & CONFIG_DIALOG) != CONFIG_DIALOG) closeBtn.setVisible(false); monthSelectorHeader.setAnimationEnabled(true); outer.add(navButtonsTop); outer.add(calendarGrid); outer.add(navButtonsBottom); drawDatePickerWidget(); refresh(); DOM.sinkEvents(outer.getElement(), Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONCLICK); DOM.setStyleAttribute(outer.getElement(), "cursor", "default"); DOM.setElementAttribute(monthMenu.getElement(), "align", "center"); } /** * * Configure this calendarPicker. * * * @param buttonsLayout a string representation with the disposition of buttons.<br/> * There are 6 rows of buttons, 3 at top and 3 at bottom.<br/> * Each row has to be separated by the ';' character.<br/> * Available buttons are:<br/> * help(?), close(x), nextMonth(>), previowusMonsh(<), nextYear(n), prevYear(p)<br/> * monthMenu(m), today(-), empty(space)<br/> * * @param months number of months to display * @param monthsPerRow number of month columns * @param monthsStep number of months to jump when the buttons > or < are pushed * @param monthsInSelector number of items (months) in the months selector menu. */ public void configure(String buttonsLayout, int months, int monthsPerRow, int monthsStep, int monthsInSelector) { monthColumns = monthsPerRow; monthSelector = monthsInSelector; monthStep = monthsStep; setNumberOfMonths(months); monthSelectorHeader.removeFromParent(); layoutButtons(buttonsLayout); layoutCalendar(); refresh(); } protected void setNumberOfMonths(int months) { monthColumns = Math.min(monthColumns, months); monthStep = Math.min(monthStep, months); simpleDatePickers = new Vector<GWTCSimpleDatePicker>(); for (int i = 0; i < Math.max(1, months); i++) { GWTCSimpleDatePicker picker = new GWTCSimpleDatePicker(true); picker.showWeekNumbers(showWeekNumbers); picker.clickOnWeekNumbers(clickOnWeekNumbers); simpleDatePickers.add(picker); Label l = new Label(); DOM.setElementAttribute(l.getElement(), "align", "center"); monthHeaders.add(l); } setMinimalDate(super.getMinimalDate()); setMaximalDate(super.getMaximalDate()); setSelectedDate(super.getSelectedDate()); } private Widget getButton(String s, int pos) { if (pos < s.length()) { int c = s.charAt(pos); if (c == '_' || c == ' ') return new Label(" "); if (c == 'x') return closeBtn; if (c == '?') return helpBtn; if (c == '-') return todayBtn; if (c == '>') return nextMBtn; if (c == '<') return prevMBtn; if (c == 'n') return nextYBtn; if (c == 'p') return prevYBtn; if (c == 'm') return monthSelectorHeader; } return null; } protected void layoutButtons(String distribution) { navButtonsBottom.clear(); navButtonsTop.clear(); DockPanel[] panels = { topButtonsRow0, topButtonsRow1, topButtonsRow2, bottomButtonsRow0, bottomButtonsRow1, bottomButtonsRow2, leftButtons, rightButtons }; String s[] = distribution.split("[;:,]"); Widget w = null, m = null; for (int i = 0; i < panels.length && i < s.length; i++) { DockPanel p = panels[i]; p.clear(); if (s[i].length() == 0) continue; for (int j = 0; j < s[i].length(); j++) { if ((w = getButton(s[i], j)) != null) { p.add(w, p != rightButtons ? DockPanel.WEST : DockPanel.EAST); } if (j == s[i].length() / 2) m = w; } if (!p.iterator().hasNext()) continue; p.setWidth("100%"); if (p != leftButtons && p != rightButtons) { if (m != null) { p.setCellWidth(m, "100%"); m.setWidth("100%"); } } if (i < 3) navButtonsTop.add(p, DockPanel.NORTH); else if (i < 6) navButtonsBottom.add(p, DockPanel.NORTH); if (i < 6) p.addStyleName(StyleCButtonsRow + (i % 3)); } } protected void layoutCalendar() { calendarGrid.clear(); calendarGrid.setCellSpacing(0); for (int i = 0, row = -2, col = 0; i < simpleDatePickers.size(); i++) { if ((i % monthColumns) == 0) { col = 0; row += 2; } else if (i > 0) { calendarGrid.setHTML(row, col, " "); calendarGrid.setHTML(row + 1, col, " "); calendarGrid.getCellFormatter().addStyleName(row, col, StyleMonthSeparator); calendarGrid.getCellFormatter().addStyleName(row + 1, col, StyleMonthSeparator); col += 1; } if (monthSelectorHeader.getParent() == null || simpleDatePickers.size() > 1) { if (i == 0 || (i % monthColumns) == 0) { calendarGrid.getRowFormatter().addStyleName(row, StyleMonthLabels); calendarGrid.getRowFormatter().addStyleName(row + 1, StyleMonthCell); } Widget w = null; if (i == 0 && monthSelectorHeader.getElement().getParentElement() == null) w = monthSelectorHeader; //calendarGrid.setWidget(row, col, monthSelectorHeader); else w = monthHeaders.get(i); //calendarGrid.setWidget(row, col, monthHeaders.get(i)); DockPanel p = null; if (leftButtons.iterator().hasNext() && leftButtons.getParent() == null && col == 0) { p = leftButtons; p.add(w, DockPanel.WEST); p.setCellWidth(w, "100%"); w = p; if (simpleDatePickers.size() == 1) { Iterator<Widget> it = p.iterator(); while (it.hasNext()) { p.add(it.next(), DockPanel.WEST); } } } if (rightButtons.iterator().hasNext() && rightButtons.getParent() == null && ((i + 1) % monthColumns) == 0) { p = rightButtons; p.add(w, DockPanel.WEST); p.setCellWidth(w, "100%"); w = p; } calendarGrid.setWidget(row, col, w); } calendarGrid.setWidget(row + 1, col, simpleDatePickers.get(i)); calendarGrid.getColumnFormatter().addStyleName(i, "Month-" + i); simpleDatePickers.get(i).addValueChangeHandler(onDaySelected); col++; } } /** * Redraw all calendar elements into the container */ @Override public void refresh() { needsRedraw = false; prevMBtn.setEnabled(simpleDatePickers.get(0).isVisibleMonth(-1)); nextMBtn.setEnabled(simpleDatePickers.get(0).isVisibleMonth(1)); prevYBtn.setEnabled(simpleDatePickers.get(0).isVisibleMonth(-1)); nextYBtn.setEnabled(simpleDatePickers.get(0).isVisibleMonth(1)); todayBtn.setEnabled(getMonthNumber(simpleDatePickers.get(0).getCursorDate()) != getMonthNumber(new Date())); fillMenuItems(); for (int i = 0; i < simpleDatePickers.size(); i++) { simpleDatePickers.get(i) .setCursorDate(GWTCSimpleDatePicker.increaseMonth(simpleDatePickers.get(0).getCursorDate(), i)); simpleDatePickers.get(i).refresh(); monthHeaders.get(i).setText( GWTCSimpleDatePicker.formatDate(MONTH_FORMAT, simpleDatePickers.get(i).getCursorDate())); } } private void fillMenuItems() { monthSelectorHeader.clearItems(); monthMenu.clearItems(); monthSelectorHeader.addItem( GWTCSimpleDatePicker.formatDate(MONTH_FORMAT, simpleDatePickers.get(0).getCursorDate()), monthMenu); int n = -1 * (monthSelector / 2); Date d = new Date(GWTCSimpleDatePicker.getFirstDayOfMonth(getCursorDate()).getTime()); Date md = new Date( GWTCSimpleDatePicker.getFirstDayOfMonth(simpleDatePickers.get(0).getMinimalDate()).getTime()); d = GWTCSimpleDatePicker.increaseMonth(d, n); while (GWTCSimpleDatePicker.compareDate(md, d) < 0) { d = GWTCSimpleDatePicker.increaseMonth(d, 1); n++; } n += monthSelector; d = GWTCSimpleDatePicker.increaseMonth(getCursorDate(), n); while (GWTCSimpleDatePicker.compareDate(simpleDatePickers.get(0).getMaximalDate(), d) > 0) { d = GWTCSimpleDatePicker.increaseMonth(d, -1); n--; } n -= monthSelector; d = GWTCSimpleDatePicker.increaseMonth(getCursorDate(), n); for (int i = n; i < monthSelector; i++) { String t = GWTCSimpleDatePicker.formatDate(MONTH_FORMAT, d); MenuCommand c = new MenuCommand(d); d = GWTCSimpleDatePicker.increaseMonth(d, 1); if (GWTCSimpleDatePicker.compareDate(d, simpleDatePickers.get(0).getMaximalDate()) >= 0 && GWTCSimpleDatePicker.compareDate(simpleDatePickers.get(0).getMinimalDate(), d) > 0) { monthMenu.addItem(t, c); } } } public static void internationalize(Widget b, Map<String, String> strs, String ktext) { if (strs == null) return; String text = strs.get(ktext); String title = strs.get(ktext + ".title"); if (text != null && text.length() > 0) { if (b instanceof HasHTML) ((HasHTML) b).setText(text); else if (b instanceof HasText) ((HasText) b).setText(text); else if (b instanceof GWTCDatePickerAbstract) ((GWTCDatePickerAbstract) b).setCaptionText(text); else System.out.println( "GWTCDatePickerAbstract.internationalize: unknown element " + b + " " + ktext + " " + text); } if (title != null && title.length() > 0) b.setTitle(title); } public void setI18nMessages(Map<String, String> strs) { internationalize(nextMBtn, strs, "key.next.month"); internationalize(prevMBtn, strs, "key.prev.month"); internationalize(nextYBtn, strs, "key.next.year"); internationalize(prevYBtn, strs, "key.prev.year"); internationalize(todayBtn, strs, "key.today"); internationalize(helpBtn, strs, "key.help"); internationalize(closeBtn, strs, "key.close"); String help = strs.get("key.calendar.help"); if (help != null && help.length() > 0) helpStr = help; String caption = strs.get("key.caption"); if (caption != null) setText(caption); } /** * Set the text for the caption of the dialog box. It is only available if the calendar is shown as a dialog. * * @param t * the message to display */ public void setCaptionText(String t) { if (calendarDlg != null) calendarDlg.setText(t); } /** * @deprecated */ public void setText(String t) { setCaptionText(t); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String) */ @Override public void setStyleName(String s) { if (calendarDlg != null) calendarDlg.setStyleName(s); else outer.setStyleName(s); monthSelectorHeader.setStyleName(s + "-MenuBar"); monthMenu.setStyleName(s + "-MenuBar"); monthSelectorHeader.addStyleName(s + "-MenuBar-horizontal"); monthMenu.addStyleName(s + "-MenuBar-vertical"); for (int i = 0; i < monthHeaders.size(); i++) { monthHeaders.get(i).setStyleName(StyleMonthLabel); monthHeaders.get(i).addStyleName(s + "-MenuBar"); monthSelectorHeader.addStyleName(s + "-MenuBar-horizontal"); } if (!s.equals(styleName)) { addStyleName(styleName); } } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#addStyleName(java.lang.String) */ @Override public void addStyleName(String s) { if (calendarDlg != null) { calendarDlg.addStyleName(s); } else { outer.addStyleName(s); } addStyleToMonthMenu(s); } private void addStyleToMonthMenu(String s) { monthSelectorHeader.addStyleName(s + "-MenuBar"); monthMenu.addStyleName(s + "-MenuBar"); monthSelectorHeader.addStyleName(s + "-MenuBar-horizontal"); monthMenu.addStyleName(s + "-MenuBar-vertical"); for (int i = 0; i < monthHeaders.size(); i++) { monthHeaders.get(i).addStyleName(s + "-MenuBar"); } } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#addStyleDependentName(java.lang.String) */ @Override public void addStyleDependentName(String s) { if (calendarDlg != null) calendarDlg.addStyleDependentName(s); else outer.addStyleDependentName(s); addStyleToMonthMenu(getStylePrimaryName() + "-" + s); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#getStyleName() */ @Override public String getStyleName() { return calendarDlg != null ? calendarDlg.getStyleName() : outer.getStyleName(); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#getStylePrimaryName() */ @Override public String getStylePrimaryName() { return calendarDlg != null ? calendarDlg.getStylePrimaryName() : outer.getStylePrimaryName(); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.UIObject#getElement() */ @Override public Element getElement() { return calendarDlg != null ? calendarDlg.getElement() : outer.getElement(); } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#getCursorDate() */ @Override public Date getCursorDate() { return simpleDatePickers.get(0).getCursorDate(); } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.Composite#onAttach() */ @Override protected void onAttach() { super.onAttach(); } ValueChangeHandler<GWTCSimpleDatePicker> onDaySelected = new ValueChangeHandler<GWTCSimpleDatePicker>() { public void onValueChange(ValueChangeEvent<GWTCSimpleDatePicker> event) { setSelectedDate(event.getValue().getSelectedDate()); } }; /** * Show the calendar container. * * If element is not null the dialog is positioned near of it, * otherwise it is centered on the viewport * */ public void show(Widget w) { if (w != null) show(DOM.getAbsoluteLeft(w.getElement()), DOM.getAbsoluteTop(w.getElement())); else center(); } /** * Show the calendar container besides the element passed as argument * */ public void showBesidesElement(Element e) { if (e != null) show(DOM.getAbsoluteLeft(e), DOM.getAbsoluteTop(e)); else center(); } /** * Show the calendar container centered in the document panel * */ public void center() { show(-1, -1); } /** * Show the calendar container, and positione it in the provided coordinates. */ public void show(int left, int top) { if (needsRedraw) refresh(); if (calendarDlg == null) { assert outer .isAttached() : "Calendar has not been attached, even though it is not configured as a popup."; outer.setVisible(true); } else { if (top >= 0 && left >= 0) { calendarDlg.setPopupPosition(left, top); calendarDlg.show(); moveIntoVisibleArea(); DOM.scrollIntoView(calendarGrid.getElement()); } else { calendarDlg.center(); } } todayBtn.setFocus(true); } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#show() */ @Override public void show() { center(); } /** * Set the zIndex value. * * @param z */ public void setZIndex(int z) { if (calendarDlg != null) { DOM.setStyleAttribute(calendarDlg.getElement(), "zIndex", String.valueOf(z)); helpDlg.setZIndex(z + 1); } } int max = 0; private void moveIntoVisibleArea() { if (calendarDlg != null) { int w = Window.getClientWidth() + Window.getScrollLeft(); int xd = calendarDlg.getAbsoluteLeft(); int wd = calendarGrid.getOffsetWidth() + 40; if ((xd + wd) > w) { xd = xd - ((xd + wd) - w); } int h = Window.getClientHeight() + Window.getScrollTop(); int yd = calendarDlg.getAbsoluteTop(); int hd = calendarDlg.getOffsetHeight() + 20; if ((yd + hd) > h) { yd = yd - ((yd + hd) - h); } calendarDlg.setPopupPosition(xd, yd); } } /** * Hide the calendar container. */ public void hide() { if (calendarDlg != null) { calendarDlg.hide(); } else outer.setVisible(false); } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#setCursorDate(java.util.Date) */ @Override public void setCursorDate(Date d) { super.setCursorDate(d); simpleDatePickers.get(0).setCursorDate(d); } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#setSelectedDate(java.util.Date) */ @Override public void setSelectedDate(Date d) { super.setSelectedDate(d); if (d == null) return; for (int i = 0; i < simpleDatePickers.size(); i++) { simpleDatePickers.get(i).setSelectedDate(d); simpleDatePickers.get(i).refresh(); } } @Override public void showWeekNumbers(boolean b) { this.showWeekNumbers = b; for (int i = 0; i < simpleDatePickers.size(); i++) { simpleDatePickers.get(i).showWeekNumbers(b); simpleDatePickers.get(i).refresh(); } } @Override public void clickOnWeekNumbers(boolean b) { this.clickOnWeekNumbers = b; for (int i = 0; i < simpleDatePickers.size(); i++) { simpleDatePickers.get(i).clickOnWeekNumbers(b); } } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#setMinimalDate(java.util.Date) */ @Override public void setMinimalDate(Date d) { super.setMinimalDate(d); for (int i = 0; i < simpleDatePickers.size(); i++) simpleDatePickers.get(i).setMinimalDate(d); } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#setMaximalDate(java.util.Date) */ @Override public void setMaximalDate(Date d) { super.setMaximalDate(d); for (int i = 0; i < simpleDatePickers.size(); i++) simpleDatePickers.get(i).setMaximalDate(d); } /* (non-Javadoc) * @see com.google.code.p.gwtchismes.client.GWTCSimpleDatePicker#getSelectedDate() */ @Override public Date getSelectedDate() { return simpleDatePickers.get(0).getSelectedDate(); } private int isMonthInRange(int incr) { while (incr != 0 && !simpleDatePickers.get(0).isVisibleMonth(incr)) incr = incr < 0 ? incr + 1 : incr - 1; return incr; } @Override public void onClick(ClickEvent event) { Widget sender = (Widget) event.getSource(); if (prevMBtn.equals(sender)) { setCursorDate(GWTCSimpleDatePicker.increaseMonth(getCursorDate(), isMonthInRange(-1 * monthStep))); } else if (nextMBtn.equals(sender)) { setCursorDate(GWTCSimpleDatePicker.increaseMonth(getCursorDate(), isMonthInRange(monthStep))); } else if (prevYBtn.equals(sender)) { setCursorDate(GWTCSimpleDatePicker.increaseMonth(getCursorDate(), isMonthInRange(-12))); } else if (nextYBtn.equals(sender)) { setCursorDate(GWTCSimpleDatePicker.increaseMonth(getCursorDate(), isMonthInRange(12))); } else if (todayBtn.equals(sender)) { setCursorDate(new Date()); } else if (helpBtn.equals(sender)) { helpDlg.alert(helpStr.replaceAll("\\n", "<br/>")); } else if (closeBtn.equals(sender)) { hide(); } else { super.onClick(event); } refresh(); } @Override public HandlerRegistration addValueChangeHandler(final ValueChangeHandler<GWTCSimpleDatePicker> handler) { for (int i = 0; i < simpleDatePickers.size(); i++) { simpleDatePickers.get(i).addValueChangeHandler(handler); } return new HandlerRegistration() { public void removeHandler() { for (int i = 0; i < simpleDatePickers.size(); i++) { simpleDatePickers.get(i).removeValueChangeHandler(handler); } } }; } private Button createButton(int buttonsType, String text, ClickHandler clickHandler) { Button b; if (buttonsType == CONFIG_DEFAULT) b = new GWTCButton(); else b = new GWTCButton(GWTCButton.BUTTON_TYPE_0, ""); if (buttonsType == CONFIG_FLAT_BUTTONS) b.addStyleDependentName("flat"); if (clickHandler != null) b.addClickHandler(clickHandler); b.setText(text); return b; } class MenuCommand implements Command { Date date; public MenuCommand(Date d) { date = d; } public void execute() { setCursorDate(date); refresh(); } } }