/** * Created by IntelliJ IDEA. * User: martlenn * Date: 28-Jul-2009 * Time: 16:23:59 */ package com.compomics.util.gui.utils; import org.apache.log4j.Logger; /* * CVS information: * * $Revision: 1.1 $ * $Date: 2009/07/28 15:25:52 $ */ import java.awt.*; import java.awt.event.*; import java.text.SimpleDateFormat; import java.util.Calendar; import javax.swing.*; import javax.swing.border.BevelBorder; /** * This class provides a simple date chooser. * * @author Lennart Martens * @version $Id: DateChooser.java,v 1.1 2009/07/28 15:25:52 lennart Exp $ */ public class DateChooser extends JDialog { // Class specific log4j logger for DateChooser instances. static Logger logger = Logger.getLogger(DateChooser.class); private Calendar iSelectedCalendar = null; private Calendar iShownCalendar = null; private int iSelectedDayIndex = -1; private static final String iCoreTitle = "Date chooser"; private JLabel[] lblDayNames = new JLabel[] {new JLabel("Sun"), new JLabel("Mon"), new JLabel("Tue"), new JLabel("Wed"), new JLabel("Thur"), new JLabel("Fri"), new JLabel("Sat")}; private JLabel[] lblDays = new JLabel[42]; private Integer[] iDays = new Integer[42]; private JLabel lblCurrentMonthYear = new JLabel(""); private final static SimpleDateFormat iSDFCurrentMonthyear = new SimpleDateFormat("MMMM yyyy"); /** * Creates a new DataChooser object. * * @param aParent the JFrame parent */ public DateChooser(JFrame aParent) { this(aParent, null); } /** * This constructor takes the parent JFRame for this dialog, * as well as a reference parameter for the selected date. * * @param aParent the parent frame * @param aSelectedCalendar the calendar */ public DateChooser(JFrame aParent, Calendar aSelectedCalendar) { super(aParent, iCoreTitle); iSelectedCalendar = aSelectedCalendar; if(iSelectedCalendar == null) { iShownCalendar = Calendar.getInstance(); } else { iShownCalendar = (Calendar)iSelectedCalendar.clone(); } this.setModal(true); createScreen(); initDates(); } /** * This method returns a Calendar set at the selected date, * or 'null' if no date was selected. * * @return Calendar set at the selected date. */ public Calendar getSelectedDate() { Calendar result = null; if(iSelectedCalendar != null) { result = iSelectedCalendar; } return result; } /** * Sets up the basic GUI components. */ private void createScreen() { JPanel jpanDate = new JPanel(new GridLayout(7, 7)); // The day names. for (int i = 0; i < lblDayNames.length; i++) { lblDayNames[i].setHorizontalAlignment(JLabel.RIGHT); lblDayNames[i].setFont(lblDayNames[i].getFont().deriveFont(Font.BOLD)); setColour(i, lblDayNames[i]); jpanDate.add(lblDayNames[i]); } jpanDate.setMinimumSize(new Dimension(jpanDate.getPreferredSize().width, jpanDate.getPreferredSize().height)); // The day numbers. int dayCounter = 0; for (int i=0;i< lblDays.length;i++) { final int counter = i; lblDays[i] = new JLabel("", JLabel.RIGHT); lblDays[i].addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { dateClicked(counter); } public void mouseEntered(MouseEvent me) { mouseFocus(counter, true); } public void mouseExited(MouseEvent me) { mouseFocus(counter, false); } }); setColour(dayCounter, lblDays[i]); jpanDate.add(lblDays[i]); // Increment daycounter, but don't let it go above 6. dayCounter++; if(dayCounter > 6) { dayCounter = 0; } } JPanel jpanDateHolder = new JPanel(); jpanDateHolder.setLayout(new BoxLayout(jpanDateHolder, BoxLayout.X_AXIS)); jpanDateHolder.add(jpanDate); jpanDateHolder.add(Box.createHorizontalStrut(20)); JPanel jpanScrollDate = new JPanel(); jpanScrollDate.setLayout(new BoxLayout(jpanScrollDate, BoxLayout.X_AXIS)); JLabel lblPrevious = new JLabel("<< Previous"); lblPrevious.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { iShownCalendar.add(Calendar.MONTH, -1); initDates(); } }); JLabel lblNext = new JLabel("Next >>"); lblNext.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { iShownCalendar.add(Calendar.MONTH, 1); initDates(); } }); jpanScrollDate.add(lblPrevious); jpanScrollDate.add(Box.createHorizontalGlue()); jpanScrollDate.add(lblCurrentMonthYear); jpanScrollDate.add(Box.createHorizontalGlue()); jpanScrollDate.add(lblNext); JPanel jpanChooser = new JPanel(new BorderLayout()); // jpanChooser.setBorder(BorderFactory.createTitledBorder("select date")); jpanChooser.add(jpanDateHolder, BorderLayout.CENTER); jpanChooser.add(jpanScrollDate, BorderLayout.SOUTH); this.getContentPane().add(jpanChooser, BorderLayout.CENTER); // this.getContentPane().add(jpanButtons, BorderLayout.SOUTH); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { close(); } }); this.pack(); this.setSize(new Dimension(this.getSize().width+100, this.getSize().height+100)); } /** * Sets the color of the labels according to the type of day. * * @param aZeroBaseDayIndex the index of the day, zero based * @param aLabel the label used for the date */ private void setColour(int aZeroBaseDayIndex, JLabel aLabel) { switch(aZeroBaseDayIndex) { case 0: aLabel.setForeground(Color.RED); break; case 6: aLabel.setForeground(Color.BLUE); break; } } /** * Changes the text on the day label according to wether it has the mouse focus. * * @param aLblIndex * @param aHasFocus */ private void mouseFocus(int aLblIndex, boolean aHasFocus) { String nbr = (iDays[aLblIndex] == null)?"":""+iDays[aLblIndex]; if(aHasFocus) { lblDays[aLblIndex].setText("<html><u>" + nbr + "</u></html>"); } else { lblDays[aLblIndex].setText(nbr); } } /** * Initiates the dates. */ private void initDates() { iShownCalendar.set(Calendar.DATE, 1); int dayOfWeek = iShownCalendar.get(Calendar.DAY_OF_WEEK); int daysInMonth = iShownCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); int displayDay = 1; for(int i=0;i<lblDays.length;i++) { // Remove any border. lblDays[i].setBorder(BorderFactory.createEmptyBorder()); int dayNbr = i+1; if(dayNbr < dayOfWeek || displayDay > daysInMonth) { lblDays[i].setText(""); iDays[i] = null; } else { // In one case, we want a special border here - if the label is // the currently selected date! if( iSelectedCalendar != null && ( iShownCalendar.get(Calendar.YEAR) == iSelectedCalendar.get(Calendar.YEAR) && iShownCalendar.get(Calendar.MONTH) == iSelectedCalendar.get(Calendar.MONTH) && displayDay == iSelectedCalendar.get(Calendar.DAY_OF_MONTH) )) { lblDays[i].setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); } lblDays[i].setText("" + displayDay); iDays[i] = Integer.valueOf(displayDay); displayDay++; } } String currentMonthYear = iSDFCurrentMonthyear.format(iShownCalendar.getTime()); lblCurrentMonthYear.setText(currentMonthYear); this.setTitle(iCoreTitle + " (" + currentMonthYear + ")"); } /** * Creates and returns the button panel. * * @return the button panel */ private JPanel getButtonPanel() { JButton btnOK = new JButton("OK"); btnOK.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { btnOKPressed(); } }); JButton btnCancel = new JButton("Cancel"); btnCancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { btnCancelPressed(); } }); JPanel jpanButtons = new JPanel(); jpanButtons.setLayout(new BoxLayout(jpanButtons, BoxLayout.X_AXIS)); jpanButtons.add(Box.createHorizontalGlue()); jpanButtons.add(btnCancel); jpanButtons.add(Box.createHorizontalStrut(5)); jpanButtons.add(btnOK); jpanButtons.add(Box.createHorizontalStrut(15)); return jpanButtons; } /** * Called if the OK button is pressed. */ private void btnOKPressed() { if(iSelectedCalendar != null) { close(); } else { JOptionPane.showMessageDialog(this, "You have not yet selected a date!", "No date selected!", JOptionPane.WARNING_MESSAGE); } } /** * Called if the cancel button is pressed. */ private void btnCancelPressed() { iSelectedCalendar = null; close(); } /** * Called if a date is clicked. * * @param aCounter the index if the clicked day */ private void dateClicked(int aCounter) { iSelectedDayIndex = aCounter; int currentDay = iDays[iSelectedDayIndex].intValue(); if(iSelectedCalendar == null) { iSelectedCalendar = Calendar.getInstance(); } iSelectedCalendar.set(iShownCalendar.get(Calendar.YEAR), iShownCalendar.get(Calendar.MONTH), currentDay); for (int i = 0; i < lblDays.length; i++) { if(i == iSelectedDayIndex) { lblDays[i].setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); } else { lblDays[i].setBorder(BorderFactory.createEmptyBorder()); } } } /** * Closes the DataChooser. */ private void close() { DateChooser.this.setVisible(false); DateChooser.this.dispose(); } /** * Creates and opens a new DateChooser dialog. * * @param args the arguments */ public static void main(String[] args) { JFrame temp = new JFrame(); DateChooser dc = new DateChooser(temp); dc.setVisible(true); Calendar c = dc.getSelectedDate(); if(c != null) { logger.info("\n\nSelected date was: " + new SimpleDateFormat("dd-MM-yyyy").format(c.getTime()) + "\n\n"); } else { logger.info("\n\nNo date selected!\n\n"); } System.exit(0); } }