/* * Copyright 2001-2008 Geert Bevin <gbevin[remove] at uwyn dot com> * Licensed under the Apache License, Version 2.0 (the "License") * $Id: JDateSelector.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.swing; import java.awt.*; import javax.swing.*; import com.uwyn.rife.config.RifeConfig; import com.uwyn.rife.tools.Localization; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DateFormatSymbols; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; public class JDateSelector extends JComponent implements ActionListener, DaySelectionListener { private static final long serialVersionUID = -6302136916436828393L; private ArrayList<JDateSelectorListener> mJDateSelectorListeners = new ArrayList<JDateSelectorListener>(); private JPopupMenu mPopup = null; private Calendar mCalendar = null; private Font mFont = null; private SimpleDateFormat mSimpleDateFormat = null; private JComponent mParent = null; private GridBagConstraints mConstraints = null; private Insets mInsets = null; private JButton mPreviousYearButton = null; private JButton mPreviousMonthButton = null; private JButton mSelectedDateButton = null; private JButton mNextMonthButton = null; private JButton mNextYearButton = null; private JPanel mHeaderPanel = null; private JPanel mDaysPanel = null; private String[] mWeekDayNames = null; public JDateSelector() { this(Calendar.getInstance(RifeConfig.Tools.getDefaultTimeZone(), Localization.getLocale())); } public JDateSelector(Calendar calendar) { super(); mSimpleDateFormat = new SimpleDateFormat(); mSimpleDateFormat.applyPattern("dd MMMM yyyy"); setDate(calendar); } public void setFont(Font font) { super.setFont(font); mFont = font; if (null != mCalendar) { setDate(mCalendar); } } public void setWeekDayNames(String[] weekDayNames) { mWeekDayNames = weekDayNames; DateFormatSymbols symbols = mSimpleDateFormat.getDateFormatSymbols(); symbols.setShortWeekdays(mWeekDayNames); mSimpleDateFormat.setDateFormatSymbols(symbols); } public void setMonthNames(String[] monthNames) { DateFormatSymbols symbols = mSimpleDateFormat.getDateFormatSymbols(); symbols.setMonths(monthNames); mSimpleDateFormat.setDateFormatSymbols(symbols); } public void setDateFormatPattern(String pattern) { mSimpleDateFormat.applyPattern(pattern); updateLabel(); } public void setDate(Calendar calendar) { setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); mCalendar = calendar; mCalendar.setLenient(true); mConstraints = new GridBagConstraints(); mInsets = new Insets(2, 0, 2, 0); mPreviousYearButton = new JButton("<<"); if (null != mFont) mPreviousYearButton.setFont(mFont); mPreviousYearButton.addActionListener(this); mPreviousMonthButton = new JButton("<"); if (null != mFont) mPreviousMonthButton.setFont(mFont); mPreviousMonthButton.addActionListener(this); mSelectedDateButton = new JButton(""); if (null != mFont) mSelectedDateButton.setFont(mFont); mSelectedDateButton.addActionListener(this); mNextMonthButton = new JButton(">"); if (null != mFont) mNextMonthButton.setFont(mFont); mNextMonthButton.addActionListener(this); mNextYearButton = new JButton(">>"); if (null != mFont) mNextYearButton.setFont(mFont); mNextYearButton.addActionListener(this); if (null != mHeaderPanel) { remove(mHeaderPanel); } mHeaderPanel = new JPanel(); mHeaderPanel.setLayout(new GridBagLayout()); mConstraints.gridx = 0; mConstraints.gridy = 0; mConstraints.gridwidth = 1; mConstraints.gridheight = 1; mConstraints.weightx = 0; mConstraints.weighty = 0; mConstraints.anchor = GridBagConstraints.CENTER; mConstraints.fill = GridBagConstraints.BOTH; mConstraints.insets = mInsets; mHeaderPanel.add(mPreviousYearButton, mConstraints); mConstraints.gridx = 1; mHeaderPanel.add(mPreviousMonthButton, mConstraints); mConstraints.gridx = 2; mConstraints.weightx = 1; mHeaderPanel.add(mSelectedDateButton, mConstraints); mConstraints.gridx = 3; mConstraints.weightx = 0; mHeaderPanel.add(mNextMonthButton, mConstraints); mConstraints.gridx = 4; mHeaderPanel.add(mNextYearButton, mConstraints); setLayout(new BorderLayout()); add("North", mHeaderPanel); createDaysOfTheMonth(mCalendar); } public Calendar getSelectedDate() { mCalendar.set(Calendar.HOUR_OF_DAY, 0); mCalendar.set(Calendar.MINUTE, 0); mCalendar.set(Calendar.SECOND, 0); return mCalendar; } public void popup(JComponent parent) { mPopup = new JPopupMenu(); mPopup.add(this); mParent = parent; mPopup.show(mParent, 0, mParent.getHeight()); } public JComponent getParentComponent() { return mParent; } public void popdown() { if (null != mPopup) { mPopup.setVisible(false); } } public boolean isPoppedUp() { if (null == mPopup) { return false; } else { return mPopup.isVisible(); } } private void createDaysOfTheMonth(Calendar calendar) { if (null != mDaysPanel) { remove(mDaysPanel); } mDaysPanel = new JPanel(new GridLayout(7, 7)); Calendar temp_calendar = null; temp_calendar = (Calendar)calendar.clone(); int last_layout_position = 0; if (null == mWeekDayNames) { mWeekDayNames = mSimpleDateFormat.getDateFormatSymbols().getShortWeekdays(); } for (int i = 1; i < 8; i++) { JLabel label = new JLabel(mWeekDayNames[i]); if (null != mFont) label.setFont(mFont); mDaysPanel.add(label); temp_calendar.roll(Calendar.DAY_OF_WEEK, true); last_layout_position++; } temp_calendar = (Calendar)calendar.clone(); temp_calendar.set(Calendar.DAY_OF_MONTH, 1); int first_visible_day = temp_calendar.get(Calendar.DAY_OF_WEEK); temp_calendar.roll(Calendar.DATE, false); int last_day_of_month = temp_calendar.get(Calendar.DAY_OF_MONTH); temp_calendar.set(Calendar.DAY_OF_MONTH, 1); temp_calendar.roll(Calendar.MONTH, false); temp_calendar.roll(Calendar.DATE, false); temp_calendar.set(Calendar.DAY_OF_MONTH, temp_calendar.get(Calendar.DAY_OF_MONTH) - (first_visible_day - 2)); for (int i = 0; i < (first_visible_day - 1); i++) { DayButton button = new DayButton(temp_calendar.get(Calendar.DAY_OF_MONTH)+i); if (null != mFont) button.setFont(mFont); button.setEnabled(false); mDaysPanel.add(button); last_layout_position++; } temp_calendar = (Calendar)calendar.clone(); temp_calendar.set(Calendar.DAY_OF_MONTH, 1); for (int i = 0; i < last_day_of_month; i++) { DayButton button = new DayButton(temp_calendar.get(Calendar.DAY_OF_MONTH)); if (null != mFont) button.setFont(mFont); button.addDaySelectionListener(this); mDaysPanel.add(button); temp_calendar.roll(Calendar.DAY_OF_MONTH, true); last_layout_position++; } for (int i = last_layout_position; i < 49; i++) { DayButton button = new DayButton(temp_calendar.get(Calendar.DAY_OF_MONTH)); if (null != mFont) button.setFont(mFont); button.setEnabled(false); mDaysPanel.add(button); temp_calendar.roll(Calendar.DAY_OF_MONTH, true); } add("Center", mDaysPanel); revalidate(); if (null != mPopup) { mPopup.pack(); } add("Center", mDaysPanel); updateLabel(); } private void updateLabel() { mSelectedDateButton.setText(mSimpleDateFormat.format(mCalendar.getTime())); } public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if (mPreviousYearButton == source) { mCalendar.roll(Calendar.YEAR, false); createDaysOfTheMonth(mCalendar); } else if (mPreviousMonthButton == source) { mCalendar.roll(Calendar.MONTH, false); createDaysOfTheMonth(mCalendar); } else if (mNextMonthButton == source) { mCalendar.roll(Calendar.MONTH, true); createDaysOfTheMonth(mCalendar); } else if (mNextYearButton == source) { mCalendar.roll(Calendar.YEAR, true); createDaysOfTheMonth(mCalendar); } else if (mSelectedDateButton == source) { daySelected(mCalendar.get(Calendar.DAY_OF_MONTH)); } } public void daySelected(int day) { mCalendar.set(Calendar.DAY_OF_MONTH, day); updateLabel(); if (null != mPopup) { mPopup.setVisible(false); } fireDateSelected(mCalendar.getTime()); } public void addJDateSelectorListener(JDateSelectorListener jDateSelectorListeners) { mJDateSelectorListeners.add(jDateSelectorListeners); } public void removeJDateSelectorListener(JDateSelectorListener jDateSelectorListeners) { mJDateSelectorListeners.remove(jDateSelectorListeners); } private void fireDateSelected(Date date) { for (JDateSelectorListener listener : mJDateSelectorListeners) { listener.dateSelected(date); } } } class DayButton extends JButton implements ActionListener { private static final long serialVersionUID = 9212576380626603405L; private ArrayList<DaySelectionListener> mDaySelectionListeners = null; private int mDay = 0; public DayButton(int day) { super((new Integer(day)).toString()); mDaySelectionListeners = new ArrayList<DaySelectionListener>(); mDay = day; addActionListener(this); } public void actionPerformed(ActionEvent event) { if (mDaySelectionListeners.size() > 0) { for (DaySelectionListener listener : mDaySelectionListeners) { listener.daySelected(mDay); } } } public void addDaySelectionListener(DaySelectionListener daySelectionListeners) { mDaySelectionListeners.add(daySelectionListeners); } public void removeDaySelectionListener(DaySelectionListener daySelectionListeners) { mDaySelectionListeners.remove(daySelectionListeners); } } interface DaySelectionListener { public void daySelected(int day); }