package com.onaro.util.jfc.date; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import javax.swing.DefaultListCellRenderer; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.ListSelectionModel; import javax.swing.SpinnerDateModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import com.onaro.client.DateFormats; /** * A three way time selection component. To select time, the user may type it in an input field, use a spinner or select * from a list. *

* The current selected date can be traced using PropertyChangeEvents. */ public class TimeSelector extends JPanel { private static final long serialVersionUID = 1L; /** * Property name for the current selected time. */ public static final String PROPERTY_TIME = "selectedTime"; //$NON-NLS-1$ /** * The current time. */ private Date time; /** * A spinner allowing the user to roll the time back and forwards in steps of one minute. */ private JSpinner timeSpinner; /** * Pattern for time display. */ private String timePattern = DateFormats.getHourPattern(); /** * The list of hours the user may select from. */ private JList quickSelectionList; /** * The number of entries in the quick time selection list */ public static final int QUICK_SELECT_ENTRIES = 48; /** * The time interval in minutes between the options of the quick time selection list. */ public static final int QUICK_SELECT_INTERVAL = 30; /** * Constructs a time selector that uses the current time and is using the default time format. */ public TimeSelector() { this(new Date()); } /** * Constructs a time selector that is using the default time format. * * @param initialTime * the time selected initially */ public TimeSelector(Date initialTime) { this(initialTime, null); } /** * Constructs a time selector. * * @param initialTime * the time selected initially * @param timePattern * time display format */ public TimeSelector(Date initialTime, String timePattern) { super(new BorderLayout()); this.time = initialTime; if (timePattern != null) { this.timePattern = timePattern; } /** * Setup the minutes and hours spinner. */ timeSpinner = new JSpinner(new SpinnerDateModel(time, null, null, Calendar.MINUTE)); timeSpinner.setEditor(new JSpinner.DateEditor(timeSpinner, this.timePattern)); timeSpinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { setTime((Date) timeSpinner.getValue()); } }); add(timeSpinner, BorderLayout.NORTH); /** * Setup the quick select hours list */ initQuickSelection(); quickSelectionList.setBackground(Color.WHITE); add(new JScrollPane(quickSelectionList), BorderLayout.CENTER); } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); timeSpinner.setEnabled(enabled); quickSelectionList.setEnabled(enabled); } /** * Initializes the quick time selection list. */ private void initQuickSelection() { Calendar timeIterator = new GregorianCalendar(); timeIterator.clear(); timeIterator.set(Calendar.HOUR_OF_DAY, 0); timeIterator.set(Calendar.MINUTE, 0); Date quickSelectableTime[] = new Date[QUICK_SELECT_ENTRIES]; for (int i = 0; i < QUICK_SELECT_ENTRIES; ++i) { quickSelectableTime[i] = timeIterator.getTime(); timeIterator.add(Calendar.MINUTE, QUICK_SELECT_INTERVAL); } quickSelectionList = new JList(quickSelectableTime); quickSelectionList.setCellRenderer(new DefaultListCellRenderer() { private static final long serialVersionUID = 1L; SimpleDateFormat timeFormatter = new SimpleDateFormat(TimeSelector.this.timePattern); public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { return super.getListCellRendererComponent(list, timeFormatter.format(value), index, isSelected, cellHasFocus); } }); quickSelectionList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { setTime((Date) quickSelectionList.getSelectedValue()); } } }); quickSelectionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } /** * Sets the current selected time. * * @param newTime * the new selected time */ public void setTime(Date newTime) { if (newTime != null) { Date oldTime = time; if (!newTime.equals(oldTime)) { time = newTime; timeSpinner.setValue(newTime); Calendar newTimeCal = new GregorianCalendar(); newTimeCal.setTime(newTime); Calendar timeCal = new GregorianCalendar(); timeCal.clear(); timeCal.set(Calendar.HOUR_OF_DAY, newTimeCal.get(Calendar.HOUR_OF_DAY)); timeCal.set(Calendar.MINUTE, newTimeCal.get(Calendar.MINUTE)); Date selectTime = timeCal.getTime(); quickSelectionList.setSelectedValue(selectTime, true); if (!selectTime.equals(quickSelectionList.getSelectedValue())) { quickSelectionList.clearSelection(); } firePropertyChange(PROPERTY_TIME, oldTime, newTime); } } } /** * Gets the current selected time. * * @return the current selected time */ public Date getTime() { return time; } }