001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.renderer;
042:
043: import java.io.IOException;
044: import java.util.Calendar;
045: import java.util.Date;
046: import java.util.TimeZone;
047: import java.text.DateFormat;
048: import java.text.SimpleDateFormat;
049:
050: import javax.faces.FacesException;
051: import javax.faces.component.EditableValueHolder;
052: import javax.faces.component.UIComponent;
053: import javax.faces.context.FacesContext;
054: import javax.faces.context.ResponseWriter;
055: import javax.faces.render.Renderer;
056:
057: import com.sun.rave.web.ui.component.CalendarMonth;
058: import com.sun.rave.web.ui.component.DateManager;
059: import com.sun.rave.web.ui.component.DropDown;
060: import com.sun.rave.web.ui.component.Hyperlink;
061: import com.sun.rave.web.ui.component.Icon;
062: import com.sun.rave.web.ui.component.IconHyperlink;
063: import com.sun.rave.web.ui.component.SkipHyperlink;
064: import com.sun.rave.web.ui.model.Option;
065: import com.sun.rave.web.ui.model.ScheduledEvent;
066: import com.sun.rave.web.ui.theme.Theme;
067: import com.sun.rave.web.ui.theme.ThemeImages;
068: import com.sun.rave.web.ui.theme.ThemeStyles;
069: import com.sun.rave.web.ui.util.MessageUtil;
070: import com.sun.rave.web.ui.util.RenderingUtilities;
071: import com.sun.rave.web.ui.util.ThemeUtilities;
072:
073: /**
074: * <p><strong>This class needs to be rewritten. Do not release as API.</strong></p>
075: */
076: public class CalendarMonthRenderer extends AbstractRenderer {
077:
078: private static final boolean DEBUG = false;
079: private static final String SKIP_SECTION = "skipSection"; //NOI18N
080: private static final String CURR_YEAR_ATTR = "currYear";
081: private static final String CURR_MONTH_ATTR = "currMonth";
082:
083: private void renderDayHeaderRow(CalendarMonth calendarMonth,
084: String[] styles, FacesContext context, ResponseWriter writer)
085: throws IOException {
086:
087: writer.startElement("tr", calendarMonth);
088: writer.write("\n");
089:
090: int firstDay = calendarMonth.getCalendar().getFirstDayOfWeek();
091:
092: String[] daysOfWeek = new String[8];
093: daysOfWeek[Calendar.MONDAY] = styles[10];
094: daysOfWeek[Calendar.TUESDAY] = styles[11];
095: daysOfWeek[Calendar.WEDNESDAY] = styles[12];
096: daysOfWeek[Calendar.THURSDAY] = styles[13];
097: daysOfWeek[Calendar.FRIDAY] = styles[14];
098: daysOfWeek[Calendar.SATURDAY] = styles[15];
099: daysOfWeek[Calendar.SUNDAY] = styles[16];
100:
101: String styleClass = styles[17];
102:
103: for (int i = 0; i < 7; i++) {
104: // render a table header for each day of the week
105: renderCalendarHeader(calendarMonth, writer, styleClass,
106: daysOfWeek[firstDay]);
107: writer.write("\n");
108: firstDay++;
109: if (firstDay == 8) {
110: firstDay = 1;
111: }
112: }
113: writer.endElement("tr");
114: writer.write("\n");
115: }
116:
117: /**
118: * <p>Render the calendarMonth header containing the weekday table headers.</p>
119: *
120: * @param calendarMonth The CalendarMonth component instance
121: * @param writer The current ResponseWriter
122: * @param styleClass The style class to use for the table header cell
123: * @param header The contents to write for the table header cell
124: *
125: * @exception IOException if an input/output error occurs
126: */
127: private void renderCalendarHeader(CalendarMonth calendarMonth,
128: ResponseWriter writer, String styleClass, String header)
129: throws IOException {
130: // render a column header with the given style and header text
131: writer.startElement("th", calendarMonth);
132: writer.writeAttribute("align", "center", null); //NOI18N
133: writer.writeAttribute("scope", "col", null); //NOI18N
134: writer.write("\n"); //NOI18N
135: writer.startElement("span", calendarMonth); //NOI18N
136: writer.writeAttribute("class", styleClass, null); //NOI18N
137: writer.write("\n"); //NOI18N
138: writer.writeText(header, null);
139: writer.write("\n"); //NOI18N
140: writer.endElement("span"); //NOI18N
141: writer.write("\n"); //NOI18N
142: writer.endElement("th"); //NOI18N
143: }
144:
145: private void renderDays(CalendarMonth calendarMonth, String id,
146: String[] styles, ResponseWriter writer) throws IOException {
147:
148: // now render each week in a row with each day in a td
149: Calendar monthToShow = calendarMonth.getCalendar();
150: monthToShow.set(Calendar.YEAR, calendarMonth.getCurrentYear()
151: .intValue());
152: monthToShow.set(Calendar.MONTH, calendarMonth.getCurrentMonth()
153: .intValue() - 1);
154: monthToShow.set(Calendar.DAY_OF_MONTH, 1);
155:
156: if (DEBUG)
157: log("Month to show " + monthToShow.getTime().toString());
158: // get the int constant repsenting the day of the week (i.e. SUNDAY)
159: int weekStartDay = monthToShow.getFirstDayOfWeek();
160:
161: // Get the startDate
162: Calendar startDate = (Calendar) (monthToShow.clone());
163: while (startDate.get(Calendar.DAY_OF_WEEK) != weekStartDay) {
164: startDate.add(Calendar.DATE, -1);
165: startDate.getTime();
166: }
167: if (DEBUG)
168: log("First day " + startDate.getTime().toString());
169:
170: // Get the end date
171: Calendar endDate = (Calendar) (monthToShow.clone());
172: endDate.add(Calendar.MONTH, 1);
173: endDate.getTime();
174:
175: if (endDate.get(Calendar.DAY_OF_WEEK) == weekStartDay) {
176: endDate.add(Calendar.DATE, -1);
177: endDate.getTime();
178: } else {
179: while (endDate.get(Calendar.DAY_OF_WEEK) != weekStartDay) {
180: endDate.add(Calendar.DATE, 1);
181: endDate.getTime();
182: }
183: endDate.add(Calendar.DATE, -1);
184: endDate.getTime();
185: }
186: if (DEBUG)
187: log("Last day " + endDate.getTime().toString());
188:
189: DateFormat format = calendarMonth.getDateFormat();
190:
191: String rowIdPrefix = id.concat(":row");
192: String dateLinkPrefix = id.concat(":dateLink");
193: boolean selected;
194: boolean dayInMonth;
195: int displayedMonth = monthToShow.get(Calendar.MONTH);
196: Calendar todaysDate = calendarMonth.getCalendar();
197:
198: int dateLinkId = 0;
199: int rowNum = 0;
200: while (startDate.before(endDate)) {
201: writer.startElement("tr", calendarMonth);
202: String rowId = rowIdPrefix + rowNum++;
203: writer.writeAttribute("id", rowId, null); // NOI18N
204: writer.write("\n");
205:
206: for (int i = 0; i < 7; ++i) {
207:
208: if (DEBUG)
209: log("Now rendering "
210: + startDate.getTime().toString());
211: selected = calendarMonth.isDateSelected(startDate,
212: endDate);
213:
214: dayInMonth = (startDate.get(Calendar.MONTH) == displayedMonth);
215:
216: String style = styles[19];
217:
218: if (selected) {
219: if (dayInMonth) {
220: style = styles[20];
221: } else {
222: style = styles[21];
223: }
224: } else if (dayInMonth) {
225: if (calendarMonth
226: .compareDate(startDate, todaysDate)) {
227: style = styles[22];
228: } else {
229: style = styles[18];
230: }
231: } else if (DEBUG)
232: log("Date is outside month and selected");
233:
234: renderDateLink(startDate, style, dateLinkPrefix
235: .concat(String.valueOf(dateLinkId)),
236: calendarMonth, writer);
237:
238: dateLinkId++;
239: startDate.add(Calendar.DAY_OF_YEAR, 1);
240: startDate.getTime();
241: }
242: writer.endElement("tr"); //NOI18N
243: writer.write("\n");
244: }
245: if (rowNum < 6) {
246: writer.startElement("tr", calendarMonth);
247: String rowId = rowIdPrefix + rowNum++;
248: writer.writeAttribute("id", rowId, null); // NOI18N
249: writer.writeAttribute("style", "display:none;", null); // NOI18N
250: writer.write("\n");
251:
252: for (int i = 0; i < 7; ++i) {
253: renderDateLink(startDate, styles[19], dateLinkPrefix
254: .concat(String.valueOf(dateLinkId)),
255: calendarMonth, writer);
256:
257: dateLinkId++;
258: startDate.add(Calendar.DAY_OF_YEAR, 1);
259: startDate.getTime();
260: }
261: writer.endElement("tr"); //NOI18N
262: writer.write("\n");
263: }
264: }
265:
266: private void renderDateLink(Calendar startDate, String style,
267: String id, CalendarMonth calendarMonth,
268: ResponseWriter writer) throws IOException {
269:
270: writer.startElement("td", calendarMonth);//NOI18N
271: writer.writeAttribute("align", "center", null); // NOI18N
272: writer.writeText("\n", null);//NOI18N
273:
274: int day = startDate.get(Calendar.DAY_OF_MONTH);
275:
276: // For performance reasons, don't create a hyperlink component
277: // for each date...
278: writer.startElement("a", calendarMonth); //NOI18N
279: writer.writeAttribute("class", style, null); //NOI18N
280: writer.writeAttribute("id", id, null); //NOI18N
281: String dateString = calendarMonth.getDateFormat().format(
282: startDate.getTime());
283: writer.writeAttribute("title", dateString, null);
284: StringBuffer buffer = new StringBuffer(128);
285:
286: if (calendarMonth.isPopup()) {
287: buffer.append(calendarMonth.getJavaScriptObjectName());
288: buffer.append(".dayClicked(this); return false;");
289: } else {
290: buffer.append(calendarMonth.getJavaScriptObjectName());
291: buffer.append(".setDateValue('");
292: buffer.append(dateString);
293: buffer.append("', this); return false;");
294: }
295:
296: writer.writeAttribute("onclick", buffer.toString(), null); //NOI18N
297: writer.writeAttribute("href", "#", null); //NOI18N
298: writer.write(String.valueOf(day));
299: writer.endElement("a"); //NOI18N
300: writer.write("\n"); //NOI18N
301: writer.endElement("td"); //NOI18N
302: writer.write("\n"); //NOI18N
303: }
304:
305: /**
306: * <p>Render the calendarMonth controls: the month and year menus as well as the
307: * previous and next month IconHyperlink's.</p>
308: *
309: * @param context The current FacesContext
310: * @param calendarMonth The CalendarMonth component instance
311: * @param writer The current ResponseWriter
312: * @param theme The current Theme
313: *
314: * @exception IOException if an input/output error occurs
315: */
316: private void renderCalendarControls(CalendarMonth calendarMonth,
317: String[] styles, FacesContext context, ResponseWriter writer)
318: throws IOException {
319:
320: if (DEBUG)
321: log("renderCalendarControls");
322:
323: writer.startElement("div", calendarMonth); //NOI18N
324: writer.writeAttribute("class", styles[3], null); // NOI18N
325: writer.writeText("\n", null); //NOI18N
326:
327: renderLayoutTable(writer, calendarMonth);
328: writer.writeText("\n", null); //NOI18N
329:
330: String pattern = calendarMonth.getDateFormatPattern();
331: if (pattern.indexOf("yyyy") < pattern.indexOf("MM")) { //NOI18N
332: renderYearControl(calendarMonth, styles, context, writer);
333: writer.startElement("td", calendarMonth); //NOI18N
334: writer.writeAttribute("width", "8", null); //NOI18N
335: writer.write(" "); //NOI18N
336: writer.endElement("td"); //NOI18N
337: writer.write("\n"); //NOI18N
338: renderMonthControl(calendarMonth, styles, context, writer);
339: } else {
340: renderMonthControl(calendarMonth, styles, context, writer);
341: writer.startElement("td", calendarMonth); //NOI18N
342: writer.writeAttribute("width", "8", null); //NOI18N
343: writer.write(" "); //NOI18N
344: writer.endElement("td"); //NOI18N
345: writer.write("\n"); //NOI18N
346: renderYearControl(calendarMonth, styles, context, writer);
347: }
348: writer.endElement("tr"); //NOI18N
349: writer.writeText("\n", null); //NOI18N
350: writer.endElement("table"); //NOI18N
351:
352: writer.writeText("\n", null); //NOI18N
353: writer.endElement("div"); //NOI18N
354: writer.writeText("\n", null); //NOI18N
355: }
356:
357: private void renderYearControl(CalendarMonth calendarMonth,
358: String[] styles, FacesContext context, ResponseWriter writer)
359: throws IOException {
360:
361: if (DEBUG)
362: log("renderYearControl()"); //NOI18N
363: writer.startElement("td", calendarMonth);
364: writer.write("\n");
365: DropDown yearDropDown = calendarMonth.getYearMenu();
366: yearDropDown.setToolTip(styles[8]);
367: RenderingUtilities.renderComponent(yearDropDown, context);
368: writer.write("\n");
369: writer.endElement("td");
370: writer.write("\n");
371: }
372:
373: private void renderMonthControl(CalendarMonth calendarMonth,
374: String[] styles, FacesContext context, ResponseWriter writer)
375: throws IOException {
376:
377: if (DEBUG)
378: log("renderMonthControl()"); //NOI18N
379:
380: writer.startElement("td", calendarMonth); //NOI18N
381: writer.writeAttribute("align", "left", null); //NOI18N
382: writer.write("\n"); //NOI18N
383:
384: IconHyperlink decreaseLink = calendarMonth
385: .getPreviousMonthLink();
386: decreaseLink.setAlt(styles[6]);
387: RenderingUtilities.renderComponent(decreaseLink, context);
388: writer.write("\n"); //NOI18N
389:
390: writer.endElement("td"); //NOI18N
391: writer.write("\n"); //NOI18N
392:
393: if (DEBUG)
394: log("\t rendered PreviousLink");
395:
396: writer.startElement("td", calendarMonth); //NOI18N
397: if (DEBUG)
398: log("\t rendered td");
399: writer.writeAttribute("align", "left", null); //NOI18N
400: writer.write("\n"); //NOI18N
401: if (DEBUG)
402: log("\t ended td");
403: if (DEBUG)
404: log(calendarMonth.toString());
405: DropDown monthDropDown = calendarMonth.getMonthMenu();
406: monthDropDown.setToolTip(styles[9]);
407: if (DEBUG)
408: log("Got DropDown");
409: RenderingUtilities.renderComponent(monthDropDown, context);
410: writer.write("\n"); //NOI18N
411: writer.endElement("td"); //NOI18N
412: writer.write("\n"); //NOI18N
413: if (DEBUG)
414: log("\t rendered Month Menu");
415:
416: writer.startElement("td", calendarMonth); //NOI18N
417: writer.writeAttribute("align", "left", null); //NOI18N
418: writer.write("\n"); //NOI18N
419: IconHyperlink increaseLink = calendarMonth.getNextMonthLink();
420: increaseLink.setAlt(styles[7]);
421: RenderingUtilities.renderComponent(increaseLink, context);
422: writer.write("\n"); //NOI18N
423: writer.endElement("td"); //NOI18N
424: writer.write("\n"); //NOI18N
425: if (DEBUG)
426: log("\t rendered IncreaseLink");
427: }
428:
429: /**
430: * <p>Render a layout table.</p>
431: *
432: * @param writer The current ResponseWriter
433: * @param calendarMonth The CalendarMonth component instance
434: *
435: * @exception IOException if an input/output error occurs
436: */
437: protected void renderLayoutTable(ResponseWriter writer,
438: CalendarMonth calendarMonth) throws IOException {
439: writer.startElement("table", calendarMonth);
440: writer.writeAttribute("border", "0", null); // NOI18N
441: writer.writeAttribute("cellpadding", "0", null); // NOI18N
442: writer.writeAttribute("cellspacing", "0", null); // NOI18N
443: writer.write("\n");
444: writer.startElement("tr", calendarMonth);
445: }
446:
447: private void renderCalendarFooter(CalendarMonth calendarMonth,
448: String[] styles, FacesContext context, ResponseWriter writer)
449: throws IOException {
450:
451: writer.startElement("tr", calendarMonth);
452: writer.write("\n");
453:
454: writer.startElement("td", calendarMonth);
455: writer.writeAttribute("class", styles[23], null); //NOI18N
456: writer.writeAttribute("colspan", "7", null); //NOI18N
457: writer.write("\n");
458:
459: writer.startElement("div", calendarMonth);
460: writer.writeAttribute("class", styles[24], null); //NOI18N
461: writer.write("\n");
462:
463: writer.startElement("span", calendarMonth);
464: writer.writeAttribute("class", styles[25], null); //NOI18N
465: writer.write("\n");
466:
467: DateFormat dateFormat = SimpleDateFormat.getDateInstance(
468: DateFormat.MEDIUM, context.getViewRoot().getLocale());
469: dateFormat
470: .setTimeZone((TimeZone) (calendarMonth.getTimeZone()));
471: Date today = calendarMonth.getCalendar().getTime();
472: if (DEBUG)
473: log("Today is " + today.toString());
474: writer.writeText(dateFormat.format(today), null);
475: writer.write("\n");
476: writer.endElement("span");
477: writer.write("\n");
478:
479: RenderingUtilities.renderAnchor(SKIP_SECTION, calendarMonth,
480: context);
481:
482: StringBuffer strBuffer = new StringBuffer(128);
483: strBuffer.append(calendarMonth.getJavaScriptObjectName());
484: strBuffer.append(".toggle(); return false;");
485:
486: writer.startElement("a", calendarMonth);
487: writer.writeAttribute("onclick", strBuffer.toString(), null);
488: writer.writeAttribute("class", styles[27], null);
489: writer.writeAttribute("href", "#", null);
490: // <RAVE> Remove unnecessary onBlur (fixes IE problem)
491: //strBuffer = new StringBuffer(128);
492: //strBuffer.append(calendarMonth.getJavaScriptObjectName());
493: //strBuffer.append(".setInitialFocus(); return false;");
494: //writer.writeAttribute("onblur", strBuffer.toString(), null);
495: // </RAVE>
496: writer.write(styles[28]);
497: writer.endElement("a");
498: writer.write("\n");
499:
500: writer.endElement("div");
501: writer.write("\n");
502:
503: writer.endElement("td");
504: writer.write("\n");
505:
506: writer.endElement("tr");
507: }
508:
509: /**
510: * <p>Render a spacer image.</p>
511: *
512: * @param context The current FacesContext
513: * @param calendarMonth The CalendarMonth component instance
514: * @param theme The current Theme
515: * @param height The height to use for the spaer image
516: * @param width The width to use for the spacer image
517: *
518: * @exception IOException if an input/output error occurs
519: */
520:
521: // TODO - this generates a component with no id set! Has to be fixed.
522: protected void renderSpacerImage(FacesContext context,
523: CalendarMonth calendarMonth, Theme theme, int height,
524: int width) throws IOException {
525: Icon dot = theme.getIcon(ThemeImages.DOT);
526: dot.setWidth(width);
527: dot.setHeight(height);
528: dot.setId("icon");
529: dot.setAlt("");
530:
531: RenderingUtilities.renderComponent(dot, context);
532: }
533:
534: /**
535: *
536: * @param context {@link FacesContext} for the response we are creating
537: * @param component {@link UIComponent} to be rendered
538: *
539: * @exception IOException if an input/output error occurs while rendering
540: * @exception NullPointerException if <code>context</code>
541: * or <code>component</code> is <code>null</code>
542: */
543: public void encodeEnd(FacesContext context, UIComponent component)
544: throws IOException {
545:
546: if (DEBUG)
547: log("encodeEnd()");
548:
549: if (!(component instanceof CalendarMonth)) {
550: Object[] params = { component.toString(),
551: this .getClass().getName(),
552: CalendarMonth.class.getName() };
553: String message = MessageUtil.getMessage(
554: "com.sun.rave.web.ui.resources.LogMessages", //NOI18N
555: "Renderer.component", params); //NOI18N
556: throw new FacesException(message);
557: }
558:
559: CalendarMonth calendarMonth = (CalendarMonth) component;
560: initializeChildren(calendarMonth, context);
561:
562: ResponseWriter writer = context.getResponseWriter();
563: Theme theme = ThemeUtilities.getTheme(context);
564: String[] styles = getStyles(calendarMonth, context, theme);
565:
566: //RenderingUtilities.renderComponent(calendarMonth.getDateField(), context);
567: //writer.write("\n");
568:
569: String id = calendarMonth.getClientId(context);
570: if (calendarMonth.isPopup()) {
571: renderPopupStart(calendarMonth, id, styles, context, writer);
572: } else {
573: writer.startElement("div", calendarMonth); // NOI18N
574: writer.writeAttribute("id", id, null); // NOI18N
575: writer.writeText("\n", null);
576:
577: }
578:
579: renderCalendarControls(calendarMonth, styles, context, writer);
580:
581: renderDateTable(calendarMonth, styles, id, context, writer);
582:
583: if (calendarMonth.isPopup()) {
584: renderPopupEnd(writer);
585: } else {
586: writer.endElement("div");
587: }
588: }
589:
590: private void renderPopupStart(CalendarMonth calendarMonth,
591: String id, String[] styles, FacesContext context,
592: ResponseWriter writer) throws IOException {
593:
594: writer.startElement("div", calendarMonth); // NOI18N
595: writer.writeAttribute("id", id, null); // NOI18N
596: writer.writeAttribute("class", styles[0], null); // NOI18N
597: writer.writeText("\n", null);
598:
599: writer.startElement("div", calendarMonth);
600: writer.writeAttribute("class", styles[1], null); // NOI18N
601: writer.writeText("\n", null);
602:
603: writer.startElement("div", calendarMonth);
604: writer.writeAttribute("class", styles[2], null); // NOI18N
605: writer.writeText("\n", null);
606:
607: renderLayoutTable(writer, calendarMonth);
608: writer.startElement("td", calendarMonth);
609: writer.writeAttribute("valign", "top", null); // NOI18N
610: writer.writeText("\n", null);
611:
612: }
613:
614: private void renderPopupEnd(ResponseWriter writer)
615: throws IOException {
616:
617: writer.endElement("td"); //NOI18N
618: writer.write("\n"); //NOI18N
619: writer.endElement("tr"); //NOI18N
620: writer.write("\n"); //NOI18N
621: writer.endElement("table"); //NOI18N
622: writer.write("\n"); //NOI18N
623: writer.endElement("div"); //NOI18N
624: writer.write("\n"); //NOI18N
625: writer.endElement("div"); //NOI18N
626: writer.write("\n"); //NOI18N
627: writer.endElement("div"); //NOI18N
628: writer.write("\n"); //NOI18N
629: }
630:
631: private void renderDateTable(CalendarMonth calendarMonth,
632: String[] styles, String id, FacesContext context,
633: ResponseWriter writer) throws IOException {
634:
635: RenderingUtilities.renderSkipLink(SKIP_SECTION, styles[26],
636: null, null, null, calendarMonth, context);
637:
638: writer.startElement("div", calendarMonth);
639: writer.writeAttribute("class", styles[4], null); // NOI18N
640: writer.write("\n");
641: writer.startElement("table", calendarMonth);
642: writer.writeAttribute("class", styles[5], null); // NOI18N
643: writer.writeAttribute("width", "100%", null); // NOI18N
644: writer.writeAttribute("cellspacing", "1", null); // NOI18N
645: writer.writeAttribute("cellpadding", "0", null); // NOI18N
646: writer.writeAttribute("border", "0", null); // NOI18N
647: writer.write("\n");
648:
649: renderDayHeaderRow(calendarMonth, styles, context, writer);
650:
651: renderDays(calendarMonth, id, styles, writer);
652:
653: if (calendarMonth.isPopup()) {
654: renderCalendarFooter(calendarMonth, styles, context, writer);
655: writer.write("\n");
656: }
657: // end the calendarMonth layout table
658: writer.endElement("table");
659: writer.write("\n");
660: writer.endElement("div");
661: writer.write("\n");
662: if (!calendarMonth.isPopup()) {
663: RenderingUtilities.renderAnchor(SKIP_SECTION,
664: calendarMonth, context);
665: }
666: }
667:
668: private void initializeChildren(CalendarMonth cm,
669: FacesContext context) {
670:
671: if (DEBUG)
672: log("initializeChildren()"); //NOI18N
673:
674: // This variable is used to track whether the calendar
675: // controls have to be updated based on the calculations
676: // performed in this method.
677: boolean updateCalendarControls = false;
678:
679: // Get a calendar instance with the correct timezone and locale
680: // from the CalendarMonth component. This calendar is initialized
681: // with today's date.
682: Calendar calendar = cm.getCalendar();
683:
684: // The displayDate reflects the month that will be displayed
685: // (we only use the year and month component of the date).
686: // We start by assuming that this will be the today's date
687: Date displayDate = calendar.getTime();
688:
689: // Find out what the current year and month settings are of the
690: // CalendarMonth component (this is whatever the user has
691: // selected using the menus and the buttons on the control row).
692: // Update the calendar with this data - it will be used when
693: // calculating the dates on the display.
694: // If the user hasn't made any selections yet, the values
695: // will be updated later, and will be based on today's date.
696: Integer year = cm.getCurrentYear();
697: Integer month = cm.getCurrentMonth();
698: if (year != null && month != null) {
699: if (DEBUG)
700: log("Menus have values...");
701: if (DEBUG)
702: log("Month is " + month.toString());
703: if (DEBUG)
704: log("Year is " + year.toString());
705: calendar.set(Calendar.YEAR, year.intValue());
706: // Adjust for the fact that we display the months as 1 - 12, but
707: // java.util.Calendar has them as 0 to 11.
708: calendar.set(Calendar.MONTH, month.intValue() - 1);
709: //calendar.set(Calendar.DAY_OF_MONTH, 1);
710: } else {
711: updateCalendarControls = true;
712: }
713:
714: // Calculate which years should be displayed, based on the
715: // settings of the of the CalendarMonth component
716: // We should probably store these options as an attribute,
717: // instead of calculating them every time.
718:
719: // Calculate min and max dates
720: Date minDate = null;
721: Date maxDate = null;
722:
723: UIComponent parent = cm.getParent();
724: if (parent instanceof DateManager) {
725: minDate = ((DateManager) parent).getFirstAvailableDate();
726: maxDate = ((DateManager) parent).getLastAvailableDate();
727: }
728:
729: if (DEBUG)
730: log("Min date set to " + minDate.toString());
731: if (DEBUG)
732: log("Max date set to " + maxDate.toString());
733:
734: if (DEBUG)
735: log("Date to display is " + displayDate.toString());
736: if (displayDate.before(minDate)) {
737: if (DEBUG)
738: log("date is before mindate");
739: displayDate = minDate;
740: updateCalendarControls = true;
741: }
742: if (maxDate.before(displayDate)) {
743: if (DEBUG)
744: log("date is after maxdate");
745: displayDate = maxDate;
746: updateCalendarControls = true;
747: }
748:
749: DropDown yearMenu = cm.getYearMenu();
750: DropDown monthMenu = cm.getMonthMenu();
751:
752: if (updateCalendarControls) {
753: calendar.setTime(displayDate);
754: String yearValue = String.valueOf(calendar
755: .get(Calendar.YEAR));
756: yearMenu.setSubmittedValue(new String[] { yearValue });
757: if (DEBUG)
758: log("Value of year: " + yearValue);
759:
760: String monthValue = String.valueOf(calendar
761: .get(Calendar.MONTH) + 1);
762: monthMenu.setSubmittedValue(new String[] { monthValue });
763: if (DEBUG)
764: log("Value of month: " + monthValue);
765: }
766:
767: // Calculate the years to show on the menu.
768: calendar.setTime(minDate);
769: int firstYear = calendar.get(Calendar.YEAR);
770: calendar.setTime(maxDate);
771: int lastYear = calendar.get(Calendar.YEAR);
772:
773: int numYears = lastYear - firstYear + 1;
774: Integer yearInteger = null;
775: Option[] yearOptions = new Option[numYears];
776: for (int i = 0; i < numYears; ++i) {
777: yearInteger = new Integer(firstYear + i);
778: yearOptions[i] = new Option(yearInteger, yearInteger
779: .toString());
780: }
781: yearMenu.setItems(yearOptions);
782:
783: // Set the items of the month component
784: // construct an option[] for the locale specific months
785: SimpleDateFormat formatter = (SimpleDateFormat) cm
786: .getDateFormat();
787: String[] monthNames = formatter.getDateFormatSymbols()
788: .getMonths();
789: Option[] months = new Option[12];
790:
791: calendar.set(Calendar.MONTH, Calendar.JANUARY);
792: int monthInt;
793: for (int i = 0; i < 12; i++) {
794: monthInt = calendar.get(Calendar.MONTH);
795: months[i] = new Option(new Integer(monthInt + 1),
796: monthNames[i]);
797: calendar.add(Calendar.MONTH, 1);
798: }
799: if (DEBUG)
800: log("Created the month options");
801: monthMenu.setItems(months);
802:
803: if (DEBUG)
804: log("initializeChildren() - END"); //NOI18N
805: }
806:
807: /**
808: * Override default behaviour - do nothing.
809: *
810: * @param context {@link FacesContext} for the response we are creating
811: * @param component {@link UIComponent} whose children are to be rendered
812: *
813: * @exception IOException if an input/output error occurs while rendering
814: * @exception NullPointerException if <code>context</code>
815: * or <code>component</code> is <code>null</code>
816: */
817: public void encodeChildren(FacesContext context,
818: UIComponent component) throws IOException {
819: return;
820: }
821:
822: /**
823: *Override default behaviour - do nothing.
824: *
825: *
826: * @param context {@link FacesContext} for the request we are processing
827: * @param component {@link UIComponent} to be rendered
828: *
829: * @exception IOException if an input/output error occurs while rendering
830: * @exception NullPointerException if <code>context</code>
831: * or <code>component</code> is null
832: */
833: public void encodeBegin(FacesContext context, UIComponent component)
834: throws IOException {
835: return;
836: }
837:
838: /**
839: * Returns a string representation of the object.
840: * @return a string representation of the object.
841: */
842: public String toString() {
843: return this .getClass().getName();
844: }
845:
846: /**
847: * Returns true.
848: * @return true
849: */
850: public boolean getRendersChildren() {
851: return true;
852: }
853:
854: private String[] getStyles(CalendarMonth calendarMonth,
855: FacesContext context, Theme theme) {
856: String[] styles = new String[29];
857: styles[0] = theme.getStyleClass(ThemeStyles.CALENDAR_DIV_SHOW);
858: styles[1] = theme.getStyleClass(ThemeStyles.CALENDAR_DIV_SHOW2);
859: styles[2] = theme.getStyleClass(ThemeStyles.CALENDAR_DIV);
860: styles[3] = theme
861: .getStyleClass(ThemeStyles.DATE_TIME_SELECT_DIV);
862: styles[4] = theme
863: .getStyleClass(ThemeStyles.DATE_TIME_CALENDAR_DIV);
864: styles[5] = theme
865: .getStyleClass(ThemeStyles.DATE_TIME_CALENDAR_TABLE);
866: styles[6] = theme.getMessage("CalendarMonth.goBack");
867: styles[7] = theme.getMessage("CalendarMonth.goForward");
868: styles[8] = theme.getMessage("CalendarMonth.selectYear");
869: styles[9] = theme.getMessage("CalendarMonth.selectMonth");
870: styles[10] = theme.getMessage("CalendarMonth.weekdayMon");
871: styles[11] = theme.getMessage("CalendarMonth.weekdayTue");
872: styles[12] = theme.getMessage("CalendarMonth.weekdayWed");
873: styles[13] = theme.getMessage("CalendarMonth.weekdayThu");
874: styles[14] = theme.getMessage("CalendarMonth.weekdayFri");
875: styles[15] = theme.getMessage("CalendarMonth.weekdaySat");
876: styles[16] = theme.getMessage("CalendarMonth.weekdaySun");
877: styles[17] = theme
878: .getStyleClass(ThemeStyles.DATE_TIME_DAY_HEADER);
879: styles[18] = theme.getStyleClass(ThemeStyles.DATE_TIME_LINK);
880: styles[19] = theme
881: .getStyleClass(ThemeStyles.DATE_TIME_OTHER_LINK);
882: styles[20] = theme
883: .getStyleClass(ThemeStyles.DATE_TIME_BOLD_LINK);
884: styles[21] = theme
885: .getStyleClass(ThemeStyles.DATE_TIME_OTHER_BOLD_LINK);
886: styles[22] = theme
887: .getStyleClass(ThemeStyles.DATE_TIME_TODAY_LINK);
888: styles[23] = theme.getStyleClass(ThemeStyles.CALENDAR_FOOTER);
889: styles[24] = theme
890: .getStyleClass(ThemeStyles.CALENDAR_FOOTER_DIV);
891: styles[25] = theme.getStyleClass(ThemeStyles.CALENDAR_DAY_TEXT);
892: styles[26] = theme.getStyleClass(ThemeStyles.SKIP_MEDIUM_GREY1);
893: styles[27] = theme
894: .getStyleClass(ThemeStyles.CALENDAR_CLOSE_LINK);
895: styles[28] = theme.getMessage("CalendarMonth.close");
896:
897: return styles;
898: }
899:
900: private void log(String s) {
901: System.out.println(this .getClass().getName() + "::" + s);
902: }
903:
904: public void decode(FacesContext context, UIComponent component) {
905:
906: super.decode(context, component);
907: }
908: }
|