/* * JCalendar.java - A bean for choosing a date Copyright (C) 2004 Kai Toedter * kai@toedter.com www.toedter.com This program 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 * of the License, or (at your option) any later version. This program is * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.freeplane.core.ui.components.calendar; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.awt.Font; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Calendar; import java.util.Date; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; /** * JCalendar is a bean for entering a date by choosing the year, month and day. * * @author Kai Toedter * @version $LastChangedRevision: 95 $ * @version $LastChangedDate: 2006-05-05 18:43:15 +0200 (Fr, 05 Mai 2006) $ */ public class JCalendar extends JPanel implements PropertyChangeListener, MouseListener { private final class JCalendarPopupMenu extends JPopupMenu { /** * */ private static final long serialVersionUID = 1L; @Override public void menuSelectionChanged(boolean isIncluded) { if (!isIncluded) { final Object source = EventQueue.getCurrentEvent().getSource(); if (source instanceof Component) { final Component c = (Component) source; isIncluded = SwingUtilities.isDescendingFrom(c, this); } } super.menuSelectionChanged(isIncluded); } } public static final String DATE_PROPERTY = "date"; /** * */ private static final long serialVersionUID = 1L; /** * Creates a JFrame with a JCalendar inside and can be used for testing. * * @param s * The command line arguments */ public static void main(final String[] s) { final JFrame frame = new JFrame("JCalendar"); final JCalendar jcalendar = new JCalendar(); frame.getContentPane().add(jcalendar); frame.pack(); frame.setVisible(true); } private Calendar calendar; private JPopupMenu calendarPopupMenu; final private JTimeChooser timeChooser; /** the day chooser */ final private JDayChooser dayChooser; private boolean initialized = false; /** the locale */ private Locale locale; /** the month chooser */ final private JMonthChooser monthChooser; final private JPanel monthYearPanel; /** the year chhoser */ final private JYearChooser yearChooser; /** * Default JCalendar constructor. */ public JCalendar() { this(null, null, true, true, true); } /** * JCalendar constructor specifying the month spinner type. * * @param monthSpinner * false, if no month spinner should be used */ public JCalendar(final boolean monthSpinner) { this(null, null, monthSpinner, true, false); } /** * JCalendar constructor which allows the initial calendar to be set. * * @param calendar * the calendar */ public JCalendar(final Calendar calendar) { this(null, null, true, true, false); setCalendar(calendar); } /** * JCalendar constructor which allows the initial date to be set. * * @param date * the date */ public JCalendar(final Date date) { this(date, null, true, true, false); } /** * JCalendar constructor specifying both the initial date and the month * spinner type. * * @param date * the date * @param monthSpinner * false, if no month spinner should be used */ public JCalendar(final Date date, final boolean monthSpinner) { this(date, null, monthSpinner, true, false); } /** * JCalendar constructor specifying both the initial date and locale. * * @param date * the date * @param locale * the new locale */ public JCalendar(final Date date, final Locale locale) { this(date, locale, true, true, false); } /** * JCalendar constructor with month spinner parameter. * * @param date * the date * @param locale * the locale * @param monthSpinner * false, if no month spinner should be used * @param weekOfYearVisible * true, if weeks of year shall be visible * @param timeVisible * true, if hours and minutes shall be visible */ public JCalendar(final Date date, final Locale locale, final boolean monthSpinner, final boolean weekOfYearVisible, final boolean timeVisible) { setName("JCalendar"); this.locale = locale; if (locale == null) { this.locale = Locale.getDefault(); } calendar = Calendar.getInstance(); setLayout(new BorderLayout()); monthYearPanel = new JPanel(); monthYearPanel.setLayout(new BorderLayout()); monthChooser = new JMonthChooser(monthSpinner); yearChooser = new JYearChooser(); monthChooser.setYearChooser(yearChooser); monthYearPanel.add(monthChooser, BorderLayout.WEST); monthYearPanel.add(yearChooser, BorderLayout.CENTER); monthYearPanel.setBorder(BorderFactory.createEmptyBorder()); dayChooser = new JDayChooser(weekOfYearVisible); dayChooser.addPropertyChangeListener(this); dayChooser.addMouseListener(this); monthChooser.setDayChooser(dayChooser); monthChooser.addPropertyChangeListener(this); yearChooser.setDayChooser(dayChooser); yearChooser.addPropertyChangeListener(this); dayChooser.setYearChooser(yearChooser); dayChooser.setMonthChooser(monthChooser); add(monthYearPanel, BorderLayout.NORTH); add(dayChooser, BorderLayout.CENTER); if(timeVisible){ timeChooser = new JTimeChooser(); add(timeChooser, BorderLayout.SOUTH); } else{ timeChooser = null; } if (date != null) { calendar.setTime(date); } initialized = true; setCalendar(calendar); } /** * JCalendar constructor allowing the initial locale to be set. * * @param locale * the new locale */ public JCalendar(final Locale locale) { this(null, locale, true, true, false); } /** * JCalendar constructor specifying both the locale and the month spinner. * * @param locale * the locale * @param monthSpinner * false, if no month spinner should be used */ public JCalendar(final Locale locale, final boolean monthSpinner) { this(null, locale, monthSpinner, true, false); } public JPopupMenu createPopupMenu() { if (calendarPopupMenu != null) { return calendarPopupMenu; } calendarPopupMenu = new JCalendarPopupMenu(); calendarPopupMenu.add(this); return calendarPopupMenu; } /** * Returns the calendar property. * * @return the value of the calendar property. */ public Calendar getCalendar() { return calendar; } /** * Returns a Date object. * * @return a date object constructed from the calendar property. */ public Date getDate() { return new Date(calendar.getTimeInMillis()); } /** * Gets the dayChooser attribute of the JCalendar object * * @return the dayChooser value */ public JDayChooser getDayChooser() { return dayChooser; } /** * Returns the color of the decoration (day names and weeks). * * @return the color of the decoration (day names and weeks). */ public Color getDecorationBackgroundColor() { return dayChooser.getDecorationBackgroundColor(); } /** * Returns the locale. * * @return the value of the locale property. * @see #setLocale */ @Override public Locale getLocale() { return locale; } /** * Gets the maximum number of characters of a day name or 0. If 0 is * returned, dateFormatSymbols.getShortWeekdays() will be used. * * @return the maximum number of characters of a day name or 0. */ public int getMaxDayCharacters() { return dayChooser.getMaxDayCharacters(); } /** * Gets the minimum selectable date. * * @return the minimum selectable date */ public Date getMaxSelectableDate() { return dayChooser.getMaxSelectableDate(); } /** * Gets the maximum selectable date. * * @return the maximum selectable date */ public Date getMinSelectableDate() { return dayChooser.getMinSelectableDate(); } /** * Gets the monthChooser attribute of the JCalendar object * * @return the monthChooser value */ public JMonthChooser getMonthChooser() { return monthChooser; } /** * Returns the Sunday foreground. * * @return Color the Sunday foreground. */ public Color getSundayForeground() { return dayChooser.getSundayForeground(); } /** * Returns the weekday foreground. * * @return Color the weekday foreground. */ public Color getWeekdayForeground() { return dayChooser.getWeekdayForeground(); } /** * Gets the yearChooser attribute of the JCalendar object * * @return the yearChooser value */ public JYearChooser getYearChooser() { return yearChooser; } /** * Gets the visibility of the decoration background. * * @return true, if the decoration background is visible. */ public boolean isDecorationBackgroundVisible() { return dayChooser.isDecorationBackgroundVisible(); } /** * Gets the visibility of the decoration border. * * @return true, if the decoration border is visible. */ public boolean isDecorationBordersVisible() { return dayChooser.isDecorationBordersVisible(); } /** * Indicates if the weeks of year are visible.. * * @return boolean true, if weeks of year are visible */ public boolean isWeekOfYearVisible() { return dayChooser.isWeekOfYearVisible(); } public void mouseClicked(final MouseEvent e) { processMouseEvent(e); } public void mouseEntered(final MouseEvent e) { processMouseEvent(e); } public void mouseExited(final MouseEvent e) { processMouseEvent(e); } public void mousePressed(final MouseEvent e) { processMouseEvent(e); } public void mouseReleased(final MouseEvent e) { processMouseEvent(e); } /** * JCalendar is a PropertyChangeListener, for its day, month and year * chooser. * * @param evt * the property change event */ public void propertyChange(final PropertyChangeEvent evt) { if (calendar != null) { if (evt.getPropertyName().equals(JDayChooser.DAY_PROPERTY)) { calendar.set(Calendar.DAY_OF_MONTH, ((Integer) evt.getNewValue()).intValue()); } else if (evt.getPropertyName().equals(JMonthChooser.MONTH_PROPERTY)) { calendar.set(Calendar.MONTH, ((Integer) evt.getNewValue()).intValue()); } else if (evt.getPropertyName().equals(JYearChooser.YEAR_PROPERTY)) { calendar.set(Calendar.YEAR, ((Integer) evt.getNewValue()).intValue()); } else if (evt.getPropertyName().equals(JCalendar.DATE_PROPERTY)) { calendar.setTime((Date) evt.getNewValue()); } } firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); } /** * Sets the background color. * * @param bg * the new background */ @Override public void setBackground(final Color bg) { super.setBackground(bg); if (dayChooser != null) { dayChooser.setBackground(bg); } } /** * Sets the calendar property. This is a bound property. * * @param c * the new calendar * @throws NullPointerException * - if c is null; * @see #getCalendar */ public void setCalendar(final Calendar c) { if (c == null) { setDate(null); } final Calendar oldCalendar = calendar; calendar = c; yearChooser.setYear(c.get(Calendar.YEAR)); monthChooser.setMonth(c.get(Calendar.MONTH)); dayChooser.setDay(c.get(Calendar.DATE)); if(timeChooser != null) timeChooser.setCalendar(calendar); firePropertyChange("calendar", oldCalendar, calendar); } /** * Sets the date. Fires the property change "date". * * @param date * the new date. * @throws NullPointerException * - if tha date is null */ public void setDate(final Date date) { final Date oldDate = calendar.getTime(); calendar.setTime(date); final int year = calendar.get(Calendar.YEAR); final int month = calendar.get(Calendar.MONTH); final int day = calendar.get(Calendar.DAY_OF_MONTH); yearChooser.setYear(year); monthChooser.setMonth(month); dayChooser.setCalendar(calendar); dayChooser.setDay(day); firePropertyChange(JCalendar.DATE_PROPERTY, oldDate, date); } /** * Sets the background of days and weeks of year buttons. * * @param decorationBackgroundColor * the background color */ public void setDecorationBackgroundColor(final Color decorationBackgroundColor) { dayChooser.setDecorationBackgroundColor(decorationBackgroundColor); } /** * Sets the decoration background visible. * * @param decorationBackgroundVisible * true, if the decoration background should be visible. */ public void setDecorationBackgroundVisible(final boolean decorationBackgroundVisible) { dayChooser.setDecorationBackgroundVisible(decorationBackgroundVisible); setLocale(locale); }; /** * Sets the decoration borders visible. * * @param decorationBordersVisible * true, if the decoration borders should be visible. */ public void setDecorationBordersVisible(final boolean decorationBordersVisible) { dayChooser.setDecorationBordersVisible(decorationBordersVisible); setLocale(locale); } /** * Enable or disable the JCalendar. * * @param enabled * the new enabled value */ @Override public void setEnabled(final boolean enabled) { super.setEnabled(enabled); if (dayChooser != null) { dayChooser.setEnabled(enabled); monthChooser.setEnabled(enabled); yearChooser.setEnabled(enabled); } } /** * Sets the font property. * * @param font * the new font */ @Override public void setFont(final Font font) { super.setFont(font); if (dayChooser != null) { dayChooser.setFont(font); monthChooser.setFont(font); yearChooser.setFont(font); } } /** * Sets the foreground color. * * @param fg * the new foreground */ @Override public void setForeground(final Color fg) { super.setForeground(fg); if (dayChooser != null) { dayChooser.setForeground(fg); monthChooser.setForeground(fg); yearChooser.setForeground(fg); } } /** * Sets the locale property. This is a bound property. * * @param l * the new locale value * @see #getLocale */ @Override public void setLocale(final Locale l) { if (!initialized) { super.setLocale(l); } else { final Locale oldLocale = locale; locale = l; dayChooser.setLocale(locale); monthChooser.setLocale(locale); firePropertyChange("locale", oldLocale, locale); } } /** * Sets the maximum number of characters per day in the day bar. Valid * values are 0-4. If set to 0, dateFormatSymbols.getShortWeekdays() will be * used, otherwise theses strings will be reduced to the maximum number of * characters. * * @param maxDayCharacters * the maximum number of characters of a day name. */ public void setMaxDayCharacters(final int maxDayCharacters) { dayChooser.setMaxDayCharacters(maxDayCharacters); } /** * Sets the maximum selectable date. * * @param max * maximum selectable date */ public void setMaxSelectableDate(final Date max) { dayChooser.setMaxSelectableDate(max); } /** * Sets the minimum selectable date. * * @param min * minimum selectable date */ public void setMinSelectableDate(final Date min) { dayChooser.setMinSelectableDate(min); } /** * Sets a valid date range for selectable dates. If max is before min, the * default range with no limitation is set. * * @param min * the minimum selectable date or null (then the minimum date is * set to 01\01\0001) * @param max * the maximum selectable date or null (then the maximum date is * set to 01\01\9999) */ public void setSelectableDateRange(final Date min, final Date max) { dayChooser.setSelectableDateRange(min, max); } /** * Sets the Sunday foreground. * * @param sundayForeground * the sundayForeground to set */ public void setSundayForeground(final Color sundayForeground) { dayChooser.setSundayForeground(sundayForeground); } /** * Sets the weekday foreground. * * @param weekdayForeground * the weekdayForeground to set */ public void setWeekdayForeground(final Color weekdayForeground) { dayChooser.setWeekdayForeground(weekdayForeground); } /** * Sets the week of year visible. * * @param weekOfYearVisible * true, if weeks of year shall be visible */ public void setWeekOfYearVisible(final boolean weekOfYearVisible) { dayChooser.setWeekOfYearVisible(weekOfYearVisible); setLocale(locale); } public boolean isTimeVisible(){ return timeChooser != null; } }