All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.calendar.AbstractDateSelectionModel Maven / Gradle / Ivy

The newest version!
/*
 * $Id: AbstractDateSelectionModel.java 3100 2008-10-14 22:33:10Z rah003 $
 *
 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.jdesktop.swingx.calendar;

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeSet;

import org.jdesktop.swingx.event.DateSelectionEvent;
import org.jdesktop.swingx.event.DateSelectionListener;
import org.jdesktop.swingx.event.EventListenerMap;
import org.jdesktop.swingx.event.DateSelectionEvent.EventType;

/**
 * Abstract base implementation of DateSelectionModel. Implements
 * notification, Calendar related properties and lower/upper bounds.
 * 
 * @author Jeanette Winzenburg
 */
public abstract class AbstractDateSelectionModel implements DateSelectionModel {
    public static final SortedSet EMPTY_DATES = Collections.unmodifiableSortedSet(new TreeSet());
    
    protected EventListenerMap listenerMap;
    protected boolean adjusting;
    protected Calendar calendar;
    protected Date upperBound;
    protected Date lowerBound;

    /** 
     * the locale used by the calendar. 

* NOTE: need to keep separately as a Calendar has no getter. */ protected Locale locale; /** * Instantiates a DateSelectionModel with default locale. */ public AbstractDateSelectionModel() { this(null); } /** * Instantiates a DateSelectionModel with the given locale. If the locale is * null, the Locale's default is used. * * PENDING JW: fall back to JComponent.getDefaultLocale instead? We use this * with components anyway? * * @param locale the Locale to use with this model, defaults to Locale.default() * if null. */ public AbstractDateSelectionModel(Locale locale) { this.listenerMap = new EventListenerMap(); setLocale(locale); } /** * {@inheritDoc} */ public Calendar getCalendar() { return (Calendar) calendar.clone(); } /** * {@inheritDoc} */ public int getFirstDayOfWeek() { return calendar.getFirstDayOfWeek(); } /** * {@inheritDoc} */ public void setFirstDayOfWeek(final int firstDayOfWeek) { if (firstDayOfWeek == getFirstDayOfWeek()) return; calendar.setFirstDayOfWeek(firstDayOfWeek); fireValueChanged(EventType.CALENDAR_CHANGED); } /** * {@inheritDoc} */ public int getMinimalDaysInFirstWeek() { return calendar.getMinimalDaysInFirstWeek(); } /** * {@inheritDoc} */ public void setMinimalDaysInFirstWeek(int minimalDays) { if (minimalDays == getMinimalDaysInFirstWeek()) return; calendar.setMinimalDaysInFirstWeek(minimalDays); fireValueChanged(EventType.CALENDAR_CHANGED); } /** * {@inheritDoc} */ public TimeZone getTimeZone() { return calendar.getTimeZone(); } /** * {@inheritDoc} */ public void setTimeZone(TimeZone timeZone) { if (getTimeZone().equals(timeZone)) return; TimeZone oldTimeZone = getTimeZone(); calendar.setTimeZone(timeZone); adjustDatesToTimeZone(oldTimeZone); fireValueChanged(EventType.CALENDAR_CHANGED); } /** * Adjusts all stored dates to a new time zone. * This method is called after the change had been made.

* * This implementation resets all dates to null, clears everything. * Subclasses may override to really map to the new time zone. * * @param oldTimeZone the old time zone * */ protected void adjustDatesToTimeZone(TimeZone oldTimeZone) { clearSelection(); setLowerBound(null); setUpperBound(null); setUnselectableDates(EMPTY_DATES); } /** * {@inheritDoc} */ public Locale getLocale() { return locale; } /** * {@inheritDoc} */ public void setLocale(Locale locale) { if (locale == null) { locale = Locale.getDefault(); } if (locale.equals(getLocale())) return; this.locale = locale; if (calendar != null) { calendar = Calendar.getInstance(calendar.getTimeZone(), locale); } else { calendar = Calendar.getInstance(locale); } fireValueChanged(EventType.CALENDAR_CHANGED); } //------------------- utility methods /** * Returns the start of the day of the given date in this model's calendar. * NOTE: the calendar is changed by this operation. * * @param date the Date to get the start for. * @return the Date representing the start of the day of the input date. */ protected Date startOfDay(Date date) { return CalendarUtils.startOfDay(calendar, date); } /** * Returns the end of the day of the given date in this model's calendar. * NOTE: the calendar is changed by this operation. * * @param date the Date to get the start for. * @return the Date representing the end of the day of the input date. */ protected Date endOfDay(Date date) { return CalendarUtils.endOfDay(calendar, date); } /** * Returns a boolean indicating whether the given dates are on the same day in * the coordinates of the model's calendar. * * @param selected one of the dates to check, must not be null. * @param compare the other of the dates to check, must not be null. * @return true if both dates represent the same day in this model's calendar. */ protected boolean isSameDay(Date selected, Date compare) { return startOfDay(selected).equals(startOfDay(compare)); } //------------------- bounds /** * {@inheritDoc} */ public Date getUpperBound() { return upperBound; } /** * {@inheritDoc} */ public void setUpperBound(Date upperBound) { if (upperBound != null) { upperBound = getNormalizedDate(upperBound); } if (CalendarUtils.areEqual(upperBound, getUpperBound())) return; this.upperBound = upperBound; if (this.upperBound != null && !isSelectionEmpty()) { long justAboveUpperBoundMs = this.upperBound.getTime() + 1; removeSelectionInterval(new Date(justAboveUpperBoundMs), getLastSelectionDate()); } fireValueChanged(EventType.UPPER_BOUND_CHANGED); } /** * {@inheritDoc} */ public Date getLowerBound() { return lowerBound; } /** * {@inheritDoc} */ public void setLowerBound(Date lowerBound) { if (lowerBound != null) { lowerBound = getNormalizedDate(lowerBound); } if (CalendarUtils.areEqual(lowerBound, getLowerBound())) return; this.lowerBound = lowerBound; if (this.lowerBound != null && !isSelectionEmpty()) { // Remove anything below the lower bound long justBelowLowerBoundMs = this.lowerBound.getTime() - 1; removeSelectionInterval(getFirstSelectionDate(), new Date( justBelowLowerBoundMs)); } fireValueChanged(EventType.LOWER_BOUND_CHANGED); } /** * {@inheritDoc} */ public boolean isAdjusting() { return adjusting; } /** * {@inheritDoc} */ public void setAdjusting(boolean adjusting) { if (adjusting == isAdjusting()) return; this.adjusting = adjusting; fireValueChanged(adjusting ? EventType.ADJUSTING_STARTED : EventType.ADJUSTING_STOPPED); } //----------------- notification /** * {@inheritDoc} */ public void addDateSelectionListener(DateSelectionListener l) { listenerMap.add(DateSelectionListener.class, l); } /** * {@inheritDoc} */ public void removeDateSelectionListener(DateSelectionListener l) { listenerMap.remove(DateSelectionListener.class, l); } public List getDateSelectionListeners() { return listenerMap.getListeners(DateSelectionListener.class); } protected void fireValueChanged(DateSelectionEvent.EventType eventType) { List listeners = getDateSelectionListeners(); DateSelectionEvent e = null; for (DateSelectionListener listener : listeners) { if (e == null) { e = new DateSelectionEvent(this, eventType, isAdjusting()); } listener.valueChanged(e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy