001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: JDateSelector.java 3714 2007-04-08 02:57:38Z gbevin $
007: */
008: package com.uwyn.rife.swing;
009:
010: import java.awt.*;
011: import javax.swing.*;
012:
013: import com.uwyn.rife.config.RifeConfig;
014: import com.uwyn.rife.tools.Localization;
015: import java.awt.event.ActionEvent;
016: import java.awt.event.ActionListener;
017: import java.text.DateFormatSymbols;
018: import java.text.SimpleDateFormat;
019: import java.util.ArrayList;
020: import java.util.Calendar;
021: import java.util.Date;
022:
023: public class JDateSelector extends JComponent implements
024: ActionListener, DaySelectionListener {
025: private static final long serialVersionUID = -6302136916436828393L;
026:
027: private ArrayList<JDateSelectorListener> mJDateSelectorListeners = new ArrayList<JDateSelectorListener>();
028:
029: private JPopupMenu mPopup = null;
030: private Calendar mCalendar = null;
031: private Font mFont = null;
032: private SimpleDateFormat mSimpleDateFormat = null;
033: private JComponent mParent = null;
034:
035: private GridBagConstraints mConstraints = null;
036: private Insets mInsets = null;
037:
038: private JButton mPreviousYearButton = null;
039: private JButton mPreviousMonthButton = null;
040: private JButton mSelectedDateButton = null;
041: private JButton mNextMonthButton = null;
042: private JButton mNextYearButton = null;
043:
044: private JPanel mHeaderPanel = null;
045:
046: private JPanel mDaysPanel = null;
047:
048: private String[] mWeekDayNames = null;
049:
050: public JDateSelector() {
051: this (Calendar.getInstance(
052: RifeConfig.Tools.getDefaultTimeZone(), Localization
053: .getLocale()));
054: }
055:
056: public JDateSelector(Calendar calendar) {
057: super ();
058:
059: mSimpleDateFormat = new SimpleDateFormat();
060: mSimpleDateFormat.applyPattern("dd MMMM yyyy");
061:
062: setDate(calendar);
063: }
064:
065: public void setFont(Font font) {
066: super .setFont(font);
067:
068: mFont = font;
069:
070: if (null != mCalendar) {
071: setDate(mCalendar);
072: }
073: }
074:
075: public void setWeekDayNames(String[] weekDayNames) {
076: mWeekDayNames = weekDayNames;
077: DateFormatSymbols symbols = mSimpleDateFormat
078: .getDateFormatSymbols();
079: symbols.setShortWeekdays(mWeekDayNames);
080: mSimpleDateFormat.setDateFormatSymbols(symbols);
081: }
082:
083: public void setMonthNames(String[] monthNames) {
084: DateFormatSymbols symbols = mSimpleDateFormat
085: .getDateFormatSymbols();
086: symbols.setMonths(monthNames);
087: mSimpleDateFormat.setDateFormatSymbols(symbols);
088: }
089:
090: public void setDateFormatPattern(String pattern) {
091: mSimpleDateFormat.applyPattern(pattern);
092: updateLabel();
093: }
094:
095: public void setDate(Calendar calendar) {
096: setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
097:
098: mCalendar = calendar;
099: mCalendar.setLenient(true);
100:
101: mConstraints = new GridBagConstraints();
102: mInsets = new Insets(2, 0, 2, 0);
103:
104: mPreviousYearButton = new JButton("<<");
105: if (null != mFont)
106: mPreviousYearButton.setFont(mFont);
107: mPreviousYearButton.addActionListener(this );
108: mPreviousMonthButton = new JButton("<");
109: if (null != mFont)
110: mPreviousMonthButton.setFont(mFont);
111: mPreviousMonthButton.addActionListener(this );
112: mSelectedDateButton = new JButton("");
113: if (null != mFont)
114: mSelectedDateButton.setFont(mFont);
115: mSelectedDateButton.addActionListener(this );
116: mNextMonthButton = new JButton(">");
117: if (null != mFont)
118: mNextMonthButton.setFont(mFont);
119: mNextMonthButton.addActionListener(this );
120: mNextYearButton = new JButton(">>");
121: if (null != mFont)
122: mNextYearButton.setFont(mFont);
123: mNextYearButton.addActionListener(this );
124:
125: if (null != mHeaderPanel) {
126: remove(mHeaderPanel);
127: }
128: mHeaderPanel = new JPanel();
129: mHeaderPanel.setLayout(new GridBagLayout());
130:
131: mConstraints.gridx = 0;
132: mConstraints.gridy = 0;
133: mConstraints.gridwidth = 1;
134: mConstraints.gridheight = 1;
135: mConstraints.weightx = 0;
136: mConstraints.weighty = 0;
137: mConstraints.anchor = GridBagConstraints.CENTER;
138: mConstraints.fill = GridBagConstraints.BOTH;
139: mConstraints.insets = mInsets;
140: mHeaderPanel.add(mPreviousYearButton, mConstraints);
141: mConstraints.gridx = 1;
142: mHeaderPanel.add(mPreviousMonthButton, mConstraints);
143: mConstraints.gridx = 2;
144: mConstraints.weightx = 1;
145: mHeaderPanel.add(mSelectedDateButton, mConstraints);
146: mConstraints.gridx = 3;
147: mConstraints.weightx = 0;
148: mHeaderPanel.add(mNextMonthButton, mConstraints);
149: mConstraints.gridx = 4;
150: mHeaderPanel.add(mNextYearButton, mConstraints);
151:
152: setLayout(new BorderLayout());
153: add("North", mHeaderPanel);
154:
155: createDaysOfTheMonth(mCalendar);
156: }
157:
158: public Calendar getSelectedDate() {
159: mCalendar.set(Calendar.HOUR_OF_DAY, 0);
160: mCalendar.set(Calendar.MINUTE, 0);
161: mCalendar.set(Calendar.SECOND, 0);
162:
163: return mCalendar;
164: }
165:
166: public void popup(JComponent parent) {
167: mPopup = new JPopupMenu();
168: mPopup.add(this );
169: mParent = parent;
170: mPopup.show(mParent, 0, mParent.getHeight());
171: }
172:
173: public JComponent getParentComponent() {
174: return mParent;
175: }
176:
177: public void popdown() {
178: if (null != mPopup) {
179: mPopup.setVisible(false);
180: }
181: }
182:
183: public boolean isPoppedUp() {
184: if (null == mPopup) {
185: return false;
186: } else {
187: return mPopup.isVisible();
188: }
189: }
190:
191: private void createDaysOfTheMonth(Calendar calendar) {
192: if (null != mDaysPanel) {
193: remove(mDaysPanel);
194: }
195:
196: mDaysPanel = new JPanel(new GridLayout(7, 7));
197:
198: Calendar temp_calendar = null;
199:
200: temp_calendar = (Calendar) calendar.clone();
201: int last_layout_position = 0;
202: if (null == mWeekDayNames) {
203: mWeekDayNames = mSimpleDateFormat.getDateFormatSymbols()
204: .getShortWeekdays();
205: }
206: for (int i = 1; i < 8; i++) {
207: JLabel label = new JLabel(mWeekDayNames[i]);
208: if (null != mFont)
209: label.setFont(mFont);
210: mDaysPanel.add(label);
211:
212: temp_calendar.roll(Calendar.DAY_OF_WEEK, true);
213: last_layout_position++;
214: }
215:
216: temp_calendar = (Calendar) calendar.clone();
217:
218: temp_calendar.set(Calendar.DAY_OF_MONTH, 1);
219: int first_visible_day = temp_calendar.get(Calendar.DAY_OF_WEEK);
220: temp_calendar.roll(Calendar.DATE, false);
221: int last_day_of_month = temp_calendar
222: .get(Calendar.DAY_OF_MONTH);
223: temp_calendar.set(Calendar.DAY_OF_MONTH, 1);
224: temp_calendar.roll(Calendar.MONTH, false);
225: temp_calendar.roll(Calendar.DATE, false);
226: temp_calendar.set(Calendar.DAY_OF_MONTH, temp_calendar
227: .get(Calendar.DAY_OF_MONTH)
228: - (first_visible_day - 2));
229: for (int i = 0; i < (first_visible_day - 1); i++) {
230: DayButton button = new DayButton(temp_calendar
231: .get(Calendar.DAY_OF_MONTH)
232: + i);
233: if (null != mFont)
234: button.setFont(mFont);
235: button.setEnabled(false);
236: mDaysPanel.add(button);
237: last_layout_position++;
238: }
239:
240: temp_calendar = (Calendar) calendar.clone();
241: temp_calendar.set(Calendar.DAY_OF_MONTH, 1);
242: for (int i = 0; i < last_day_of_month; i++) {
243: DayButton button = new DayButton(temp_calendar
244: .get(Calendar.DAY_OF_MONTH));
245: if (null != mFont)
246: button.setFont(mFont);
247: button.addDaySelectionListener(this );
248: mDaysPanel.add(button);
249: temp_calendar.roll(Calendar.DAY_OF_MONTH, true);
250:
251: last_layout_position++;
252: }
253:
254: for (int i = last_layout_position; i < 49; i++) {
255: DayButton button = new DayButton(temp_calendar
256: .get(Calendar.DAY_OF_MONTH));
257: if (null != mFont)
258: button.setFont(mFont);
259: button.setEnabled(false);
260: mDaysPanel.add(button);
261: temp_calendar.roll(Calendar.DAY_OF_MONTH, true);
262: }
263:
264: add("Center", mDaysPanel);
265: revalidate();
266:
267: if (null != mPopup) {
268: mPopup.pack();
269: }
270: add("Center", mDaysPanel);
271: updateLabel();
272: }
273:
274: private void updateLabel() {
275: mSelectedDateButton.setText(mSimpleDateFormat.format(mCalendar
276: .getTime()));
277: }
278:
279: public void actionPerformed(ActionEvent event) {
280: Object source = event.getSource();
281:
282: if (mPreviousYearButton == source) {
283: mCalendar.roll(Calendar.YEAR, false);
284: createDaysOfTheMonth(mCalendar);
285: } else if (mPreviousMonthButton == source) {
286: mCalendar.roll(Calendar.MONTH, false);
287: createDaysOfTheMonth(mCalendar);
288: } else if (mNextMonthButton == source) {
289: mCalendar.roll(Calendar.MONTH, true);
290: createDaysOfTheMonth(mCalendar);
291: } else if (mNextYearButton == source) {
292: mCalendar.roll(Calendar.YEAR, true);
293: createDaysOfTheMonth(mCalendar);
294: } else if (mSelectedDateButton == source) {
295: daySelected(mCalendar.get(Calendar.DAY_OF_MONTH));
296: }
297: }
298:
299: public void daySelected(int day) {
300: mCalendar.set(Calendar.DAY_OF_MONTH, day);
301: updateLabel();
302: if (null != mPopup) {
303: mPopup.setVisible(false);
304: }
305: fireDateSelected(mCalendar.getTime());
306: }
307:
308: public void addJDateSelectorListener(
309: JDateSelectorListener jDateSelectorListeners) {
310: mJDateSelectorListeners.add(jDateSelectorListeners);
311: }
312:
313: public void removeJDateSelectorListener(
314: JDateSelectorListener jDateSelectorListeners) {
315: mJDateSelectorListeners.remove(jDateSelectorListeners);
316: }
317:
318: private void fireDateSelected(Date date) {
319: for (JDateSelectorListener listener : mJDateSelectorListeners) {
320: listener.dateSelected(date);
321: }
322: }
323: }
324:
325: class DayButton extends JButton implements ActionListener {
326: private static final long serialVersionUID = 9212576380626603405L;
327:
328: private ArrayList<DaySelectionListener> mDaySelectionListeners = null;
329: private int mDay = 0;
330:
331: public DayButton(int day) {
332: super ((new Integer(day)).toString());
333: mDaySelectionListeners = new ArrayList<DaySelectionListener>();
334: mDay = day;
335: addActionListener(this );
336: }
337:
338: public void actionPerformed(ActionEvent event) {
339: if (mDaySelectionListeners.size() > 0) {
340: for (DaySelectionListener listener : mDaySelectionListeners) {
341: listener.daySelected(mDay);
342: }
343: }
344: }
345:
346: public void addDaySelectionListener(
347: DaySelectionListener daySelectionListeners) {
348: mDaySelectionListeners.add(daySelectionListeners);
349: }
350:
351: public void removeDaySelectionListener(
352: DaySelectionListener daySelectionListeners) {
353: mDaySelectionListeners.remove(daySelectionListeners);
354: }
355: }
356:
357: interface DaySelectionListener {
358: public void daySelected(int day);
359: }
|