Mega Code Archive

 
Categories / Java / Swing Components
 

JYearChooser is a bean for choosing a year

/*  *  JYearChooser.java  - A bean for choosing a year  *  Copyright (C) 2004 Kai Toedter  *  kai@toedter.com  *  www.toedter.com  *  *  This program 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  *  of the License, or (at your option) any later version.  *  *  This program 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 program; if not, write to the Free Software  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */ //package com.myapp.util.swing.datechooser; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseListener; import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Date; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /**  * JYearChooser is a bean for choosing a year.  *   * @author Kai Toedter  * @version 1.2  */ @SuppressWarnings("serial") public class JYearChooser extends JSpinField {     protected JDayChooser dayChooser;     protected int startYear;     protected int endYear;     /**      * Default JCalendar constructor.      */     public JYearChooser() {         Calendar calendar = Calendar.getInstance();         dayChooser = null;         setMinimum(calendar.getMinimum(Calendar.YEAR));         setMaximum(calendar.getMaximum(Calendar.YEAR));         setValue(calendar.get(Calendar.YEAR));     }     /**      * Sets the year. This is a bound property.      *       * @param y      *            the new year      *       * @see #getYear      */     public void setYear(int y) {         int oldYear = getValue();         super.setValue(y, true, false);         if (dayChooser != null) {             dayChooser.setYear(value);         }         spinner.setValue(new Integer(value));         firePropertyChange("year", oldYear, value);     }     /**      * Sets the year value.      *       * @param value      *            the year value      */     public void setValue(int value) {         setYear(value);     }     /**      * Returns the year.      *       * @return the year      */     public int getYear() {         return super.getValue();     }     /**      * Convenience method set a day chooser that might be updated directly.      *       * @param dayChooser      *            the day chooser      */     public void setDayChooser(JDayChooser dayChooser) {         this.dayChooser = dayChooser;     }     /**      * Returns "JYearChooser".      *       * @return the name value      */     public String getName() {         return "JYearChooser";     }     /**      * Returns the endy ear.      *       * @return the end year      */     public int getEndYear() {         return getMaximum();     }     /**      * Sets the end ear.      *       * @param endYear      *            the end year      */     public void setEndYear(int endYear) {         setMaximum(endYear);     }     /**      * Returns the start year.      *       * @return the start year.      */     public int getStartYear() {         return getMinimum();     }     /**      * Sets the start year.      *       * @param startYear      *            the start year      */     public void setStartYear(int startYear) {         setMinimum(startYear);     }     /**      * Creates a JFrame with a JYearChooser inside and can be used for testing.      *       * @param s      *            command line arguments      */     static public void main(String[] s) {         JFrame frame = new JFrame("JYearChooser");         frame.getContentPane().add(new JYearChooser());         frame.pack();         frame.setVisible(true);     } } /*  *  JSpinField.java  - A spin field using a JSpinner (JDK 1.4)  *  Copyright (C) 2004 Kai Toedter  *  kai@toedter.com  *  www.toedter.com  *  *  This program 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  *  of the License, or (at your option) any later version.  *  *  This program 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 program; if not, write to the Free Software  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */ //package com.myapp.util.swing.datechooser; /**  * JSpinField2 is a numeric field with 2 spin buttons to increase or decrease  * the value. It has the same interface as the "old" JSpinField but uses a  * JSpinner internally (since J2SE SDK 1.4) rather than a scrollbar for  * emulating the spin buttons.  *   * @author Kai Toedter  * @version 1.2  */ @SuppressWarnings("serial") class JSpinField extends JPanel implements ChangeListener,         CaretListener, ActionListener {     protected JSpinner spinner;     /** the text (number) field */     protected JTextField textField;     protected int min;     protected int max;     protected int value;     protected Color darkGreen;     /**      * Default JSpinField constructor.      */     public JSpinField() {         this(0, Integer.MAX_VALUE);     }     /**      * JSpinField constructor with given minimum and maximum vaues..      * @param min       * @param max       */     public JSpinField(int min, int max) {         super();         this.min = min;         if (max < min)             max = min;         this.max = max;         value = 0;         if (value < min)             value = min;         if (value > max)             value = max;         darkGreen = new Color(0, 150, 0);         setLayout(new BorderLayout());         textField = new JTextField();         textField.addCaretListener(this);         textField.addActionListener(this);         textField.setHorizontalAlignment(SwingConstants.RIGHT);         textField.setBorder(BorderFactory.createEmptyBorder());         textField.setText(Integer.toString(value));         spinner = new JSpinner();         spinner.setEditor(textField);         spinner.addChangeListener(this);         add(spinner, BorderLayout.CENTER);     }     public void adjustWidthToMaximumValue() {         JTextField testTextField = new JTextField(Integer.toString(max));         int width = testTextField.getPreferredSize().width;         int height = testTextField.getPreferredSize().height;         textField.setPreferredSize(new Dimension(width, height));         textField.revalidate();     }     /**      * Is invoked when the spinner model changes      *       * @param e      *            the ChangeEvent      */     public void stateChanged(ChangeEvent e) {         SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();         int val = model.getNumber().intValue();         setValue(val);     }     /**      * Sets the value attribute of the JSpinField object.      *       * @param newValue      *            The new value      * @param updateTextField      *            true if text field should be updated      * @param firePropertyChange bleh      */     protected void setValue(int newValue,                             boolean updateTextField,                             boolean firePropertyChange) {         int oldValue = value;         if (newValue < min) {             value = min;         } else if (newValue > max) {             value = max;         } else {             value = newValue;         }         if (updateTextField) {             textField.setText(Integer.toString(value));             textField.setForeground(Color.black);         }         if (firePropertyChange) {             firePropertyChange("value", oldValue, value);         }     }     /**      * Sets the value. This is a bound property.      *       * @param newValue      *            the new value      *       * @see #getValue      */     public void setValue(int newValue) {         setValue(newValue, true, true);         spinner.setValue(new Integer(value));     }     /**      * Returns the value.      *       * @return the value value      */     public int getValue() {         return value;     }     /**      * Sets the minimum value.      *       * @param newMinimum      *            the new minimum value      *       * @see #getMinimum      */     public void setMinimum(int newMinimum) {         min = newMinimum;     }     /**      * Returns the minimum value.      *       * @return the minimum value      */     public int getMinimum() {         return min;     }     /**      * Sets the maximum value and adjusts the preferred width.      *       * @param newMaximum      *            the new maximum value      *       * @see #getMaximum      */     public void setMaximum(int newMaximum) {         max = newMaximum;     }     /**      * Sets the horizontal alignment of the displayed value.      *       * @param alignment      *            the horizontal alignment      */     public void setHorizontalAlignment(int alignment) {         textField.setHorizontalAlignment(alignment);     }     /**      * Returns the maximum value.      *       * @return the maximum value      */     public int getMaximum() {         return max;     }     /**      * Sets the font property.      *       * @param font      *            the new font      */     public void setFont(Font font) {         if (textField != null) {             textField.setFont(font);         }     }     /**      * DOCUMENT ME!      *       * @param fg      *            DOCUMENT ME!      */     public void setForeground(Color fg) {         if (textField != null) {             textField.setForeground(fg);         }     }     /**      * After any user input, the value of the textfield is proofed. Depending on      * being an integer, the value is colored green or red.      *       * @param e      *            Description of the Parameter      */     public void caretUpdate(CaretEvent e) {         try {             int testValue = Integer.valueOf(textField.getText()).intValue();             if ((testValue >= min) && (testValue <= max)) {                 textField.setForeground(darkGreen);                 setValue(testValue, false, true);             } else {                 textField.setForeground(Color.red);             }         } catch (Exception ex) {             if (ex instanceof NumberFormatException) {                 textField.setForeground(Color.red);             }             // Ignore all other exceptions, e.g. illegal state exception         }         textField.repaint();     }     /**      * After any user input, the value of the textfield is proofed. Depending on      * being an integer, the value is colored green or red. If the textfield is      * green, the enter key is accepted and the new value is set.      *       * @param e      *            Description of the Parameter      */     public void actionPerformed(ActionEvent e) {         if (textField.getForeground().equals(darkGreen)) {             setValue(Integer.valueOf(textField.getText()).intValue());         }     }     /**      * Enable or disable the JSpinField.      *       * @param enabled      *            The new enabled value      */     public void setEnabled(boolean enabled) {         super.setEnabled(enabled);         textField.setEnabled(enabled);         spinner.setEnabled(enabled);     }     /**      * Returns the year chooser's spinner (which allow the focus to be set to      * it).      *       * @return Component the spinner or null, if the month chooser has no      *         spinner      */     public Component getSpinner() {         return spinner;     }     /**      * Returns "JSpinField".      *       * @return the name value      */     public String getName() {         return "JSpinField";     }     /**      * Creates a JFrame with a JSpinField inside and can be used for testing.      *       * @param s      *            The command line arguments      */     public static void main(String[] s) {         JFrame frame = new JFrame("JSpinField2");         frame.getContentPane().add(new JSpinField());         frame.pack();         frame.setVisible(true);     } } /**  * JCalendar is a bean for choosing a day.  *   * @author Kai Toedter  * @version 1.2.1  */ @SuppressWarnings("serial") class JDayChooser extends JPanel implements ActionListener, KeyListener,         FocusListener {     protected JButton[] days;     protected JButton[] weeks;     protected JButton selectedDay;     protected JPanel weekPanel;     protected JPanel dayPanel;     protected int day;     protected Color oldDayBackgroundColor;     protected Color selectedColor;     protected Color sundayForeground;     protected Color weekdayForeground;     protected Color decorationBackgroundColor;     protected String[] dayNames;     protected Calendar calendar;     protected Calendar today;     protected Locale locale;     protected boolean initialized;     protected boolean weekOfYearVisible;     protected boolean decorationBackgroundVisible = true;     protected boolean decorationBordersVisible;     private boolean alwaysFireDayProperty;     /**      * Default JDayChooser constructor.      */     public JDayChooser() {         this(false);     }     /**      * JDayChooser constructor.      *       * @param weekOfYearVisible      *            true, if the weeks of a year shall be shown      */     public JDayChooser(boolean weekOfYearVisible) {         setBackground(Color.blue);         this.weekOfYearVisible = weekOfYearVisible;         locale = Locale.getDefault();         days = new JButton[49];         selectedDay = null;         calendar = Calendar.getInstance(locale);         today = (Calendar) calendar.clone();         setLayout(new BorderLayout());         dayPanel = new JPanel();         dayPanel.setLayout(new GridLayout(7, 7));         sundayForeground = new Color(164, 0, 0);         weekdayForeground = new Color(0, 90, 164);         // decorationBackgroundColor = new Color(194, 211, 252);         // decorationBackgroundColor = new Color(206, 219, 246);         decorationBackgroundColor = new Color(210, 228, 238);         for (int y = 0; y < 7; y++) {             for (int x = 0; x < 7; x++) {                 int index = x + (7 * y);                 if (y == 0) {                     // Create a button that doesn't react on clicks or focus                     // changes.                     // Thanks to Thomas Schaefer for the focus hint :)                     days[index] = new JButton() {                         public void addMouseListener(MouseListener l) {                         }                         public boolean isFocusable() {                             return false;                         }                     };                     days[index]                             .setContentAreaFilled(decorationBackgroundVisible);                     days[index].setBorderPainted(decorationBordersVisible);                     days[index].setBackground(decorationBackgroundColor);                 } else {                     days[index] = new JButton("x");                     days[index].addActionListener(this);                     days[index].addKeyListener(this);                     days[index].addFocusListener(this);                 }                 days[index].setMargin(new Insets(0, 0, 0, 0));                 days[index].setFocusPainted(false);                 dayPanel.add(days[index]);             }         }         weekPanel = new JPanel();         weekPanel.setLayout(new GridLayout(7, 1));         weeks = new JButton[7];         for (int i = 0; i < 7; i++) {             weeks[i] = new JButton() {                 public void addMouseListener(MouseListener l) {                 }                 public boolean isFocusable() {                     return false;                 }             };             weeks[i].setMargin(new Insets(0, 0, 0, 0));             weeks[i].setFocusPainted(false);             weeks[i].setBackground(decorationBackgroundColor);             weeks[i].setForeground(new Color(100, 100, 100));             weeks[i].setContentAreaFilled(decorationBackgroundVisible);             weeks[i].setBorderPainted(decorationBordersVisible);             if (i != 0) {                 weeks[i].setText("0" + (i + 1));             }             weekPanel.add(weeks[i]);         }         init();         drawWeeks();         setDay(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));         add(dayPanel, BorderLayout.CENTER);         if (weekOfYearVisible) {             add(weekPanel, BorderLayout.WEST);         }         initialized = true;     }     /**      * Initilizes the locale specific names for the days of the week.      */     protected void init() {         JButton testButton = new JButton();         oldDayBackgroundColor = testButton.getBackground();         selectedColor = new Color(160, 160, 160);         Date date = calendar.getTime();         calendar = Calendar.getInstance(locale);         calendar.setTime(date);         drawDayNames();         drawDays();     }     /**      * Draws the day names of the day columnes.      */     private void drawDayNames() {         int firstDayOfWeek = calendar.getFirstDayOfWeek();         DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale);         dayNames = dateFormatSymbols.getShortWeekdays();         int dayi = firstDayOfWeek;         for (int i = 0; i < 7; i++) {             days[i].setText(dayNames[dayi]);             if (dayi == 1) {                 days[i].setForeground(sundayForeground);             } else {                 days[i].setForeground(weekdayForeground);             }             if (dayi < 7) {                 dayi++;             } else {                 dayi -= 6;             }         }     }     /**      * Initializes both day names and weeks of the year.      */     protected void initDecorations() {         for (int x = 0; x < 7; x++) {             days[x].setContentAreaFilled(decorationBackgroundVisible);             days[x].setBorderPainted(decorationBordersVisible);             weeks[x].setContentAreaFilled(decorationBackgroundVisible);             weeks[x].setBorderPainted(decorationBordersVisible);         }     }     /**      * Hides and shows the week buttons.      */     protected void drawWeeks() {         Calendar tmpCalendar = (Calendar) calendar.clone();         for (int i = 1; i < 7; i++) {             tmpCalendar.set(Calendar.DAY_OF_MONTH, (i * 7) - 6);             int week = tmpCalendar.get(Calendar.WEEK_OF_YEAR);             String buttonText = Integer.toString(week);             if (week < 10) {                 buttonText = "0" + buttonText;             }             weeks[i].setText(buttonText);             if ((i == 5) || (i == 6)) {                 weeks[i].setVisible(days[i * 7].isVisible());             }         }     }     /**      * Hides and shows the day buttons.      */     protected void drawDays() {         Calendar tmpCalendar = (Calendar) calendar.clone();         int firstDayOfWeek = tmpCalendar.getFirstDayOfWeek();         tmpCalendar.set(Calendar.DAY_OF_MONTH, 1);         int firstDay = tmpCalendar.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek;         if (firstDay < 0) {             firstDay += 7;         }         int i;         for (i = 0; i < firstDay; i++) {             days[i + 7].setVisible(false);             days[i + 7].setText("");         }         tmpCalendar.add(Calendar.MONTH, 1);         Date firstDayInNextMonth = tmpCalendar.getTime();         tmpCalendar.add(Calendar.MONTH, -1);         Date dayi = tmpCalendar.getTime();         int n = 0;         Color foregroundColor = getForeground();         while (dayi.before(firstDayInNextMonth)) {             days[i + n + 7].setText(Integer.toString(n + 1));             days[i + n + 7].setVisible(true);             if ((tmpCalendar.get(Calendar.DAY_OF_YEAR) == today                     .get(Calendar.DAY_OF_YEAR))                     && (tmpCalendar.get(Calendar.YEAR) == today                             .get(Calendar.YEAR))) {                 days[i + n + 7].setForeground(sundayForeground);             } else {                 days[i + n + 7].setForeground(foregroundColor);             }             if ((n + 1) == this.day) {                 days[i + n + 7].setBackground(selectedColor);                 selectedDay = days[i + n + 7];             } else {                 days[i + n + 7].setBackground(oldDayBackgroundColor);             }             n++;             tmpCalendar.add(Calendar.DATE, 1);             dayi = tmpCalendar.getTime();         }         for (int k = n + i + 7; k < 49; k++) {             days[k].setVisible(false);             days[k].setText("");         }     }     /**      * Returns the locale.      *       * @return the locale value      *       * @see #setLocale      */     public Locale getLocale() {         return locale;     }     /**      * Sets the locale.      *       * @param locale      *            the new locale value      *       * @see #getLocale      */     public void setLocale(Locale locale) {         if (!initialized) {             super.setLocale(locale);         } else {             this.locale = locale;             super.setLocale(locale);             init();         }     }     /**      * Sets the day. This is a bound property.      *       * @param d      *            the day      *       * @see #getDay      */     public void setDay(int d) {         if (d < 1) {             d = 1;         }         Calendar tmpCalendar = (Calendar) calendar.clone();         tmpCalendar.set(Calendar.DAY_OF_MONTH, 1);         tmpCalendar.add(Calendar.MONTH, 1);         tmpCalendar.add(Calendar.DATE, -1);         int maxDaysInMonth = tmpCalendar.get(Calendar.DATE);         if (d > maxDaysInMonth) {             d = maxDaysInMonth;         }         int oldDay = day;         day = d;         if (selectedDay != null) {             selectedDay.setBackground(oldDayBackgroundColor);             selectedDay.repaint();         }         for (int i = 7; i < 49; i++) {             if (days[i].getText().equals(Integer.toString(day))) {                 selectedDay = days[i];                 selectedDay.setBackground(selectedColor);                 break;             }         }         if (alwaysFireDayProperty) {             firePropertyChange("day", 0, day);         } else {             firePropertyChange("day", oldDay, day);         }     }     /**      * this is needed for JDateChooser.      *       * @param alwaysFire      *            true, if day property shall be fired every time a day is      *            chosen.      */     public void setAlwaysFireDayProperty(boolean alwaysFire) {         alwaysFireDayProperty = alwaysFire;     }     /**      * Returns the selected day.      *       * @return the day value      *       * @see #setDay      */     public int getDay() {         return day;     }     /**      * Sets a specific month. This is needed for correct graphical      * representation of the days.      *       * @param month      *            the new month      */     public void setMonth(int month) {         calendar.set(Calendar.MONTH, month);         // Since the day does not change,         // don't fire a day property change, even if alwaysFireDayProperty is         // true :)         boolean storedMode = alwaysFireDayProperty;         alwaysFireDayProperty = false;         setDay(day);         alwaysFireDayProperty = storedMode;         drawDays();         drawWeeks();     }     /**      * Sets a specific year. This is needed for correct graphical representation      * of the days.      *       * @param year      *            the new year      */     public void setYear(int year) {         calendar.set(Calendar.YEAR, year);         drawDays();         drawWeeks();     }     /**      * Sets a specific calendar. This is needed for correct graphical      * representation of the days.      *       * @param calendar      *            the new calendar      */     public void setCalendar(Calendar calendar) {         this.calendar = calendar;         drawDays();     }     /**      * Sets the font property.      *       * @param font      *            the new font      */     public void setFont(Font font) {         if (days != null) {             for (int i = 0; i < 49; i++) {                 days[i].setFont(font);             }         }     }     /**      * Sets the foregroundColor color.      *       * @param foreground      *            the new foregroundColor      */     public void setForeground(Color foreground) {         super.setForeground(foreground);         if (days != null) {             for (int i = 7; i < 49; i++) {                 days[i].setForeground(foreground);             }             drawDays();         }     }     /**      * Returns "JDayChooser".      *       * @return the name value      */     public String getName() {         return "JDayChooser";     }     /**      * JDayChooser is the ActionListener for all day buttons.      *       * @param e      *            the ActionEvent      */     public void actionPerformed(ActionEvent e) {         JButton button = (JButton) e.getSource();         String buttonText = button.getText();         int dayi = new Integer(buttonText).intValue();         setDay(dayi);     }     /**      * JDayChooser is the FocusListener for all day buttons. (Added by Thomas      * Schaefer)      *       * @param e      *            the FocusEvent      */     /*      * Code below commented out by Mark Brown on 24 Aug 2004. This code breaks      * the JDateChooser code by triggering the actionPerformed method on the      * next day button. This causes the date chosen to always be incremented by      * one day.      */     public void focusGained(FocusEvent e) {         // JButton button = (JButton) e.getSource();         // String buttonText = button.getText();         //         // if ((buttonText != null) && !buttonText.equals("") &&         // !e.isTemporary()) {         // actionPerformed(new ActionEvent(e.getSource(), 0, null));         // }     }     /**      * Does nothing.      *       * @param e      *            the FocusEvent      */     public void focusLost(FocusEvent e) {     }     /**      * JDayChooser is the KeyListener for all day buttons. (Added by Thomas      * Schaefer and modified by Austin Moore)      *       * @param e      *            the KeyEvent      */     public void keyPressed(KeyEvent e) {         int offset = (e.getKeyCode() == KeyEvent.VK_UP) ? (-7) : ((e                 .getKeyCode() == KeyEvent.VK_DOWN) ? (+7)                 : ((e.getKeyCode() == KeyEvent.VK_LEFT) ? (-1) : ((e                         .getKeyCode() == KeyEvent.VK_RIGHT) ? (+1) : 0)));         int newDay = getDay() + offset;         if ((newDay >= 1)                 && (newDay <= calendar.getMaximum(Calendar.DAY_OF_MONTH))) {             setDay(newDay);         }     }     /**      * Does nothing.      *       * @param e      *            the KeyEvent      */     public void keyTyped(KeyEvent e) {     }     /**      * Does nothing.      *       * @param e      *            the KeyEvent      */     public void keyReleased(KeyEvent e) {     }     /**      * Enable or disable the JDayChooser.      *       * @param enabled      *            The new enabled value      */     public void setEnabled(boolean enabled) {         super.setEnabled(enabled);         for (short i = 0; i < days.length; i++) {             if (days[i] != null) {                 days[i].setEnabled(enabled);             }         }         for (short i = 0; i < weeks.length; i++) {             if (weeks[i] != null) {                 weeks[i].setEnabled(enabled);             }         }     }     /**      * In some Countries it is often usefull to know in which week of the year a      * date is.      *       * @return boolean true, if the weeks of the year is shown      */     public boolean isWeekOfYearVisible() {         return weekOfYearVisible;     }     /**      * In some Countries it is often usefull to know in which week of the year a      * date is.      *       * @param weekOfYearVisible      *            true, if the weeks of the year shall be shown      */     public void setWeekOfYearVisible(boolean weekOfYearVisible) {         if (weekOfYearVisible == this.weekOfYearVisible) {             return;         } else if (weekOfYearVisible) {             add(weekPanel, BorderLayout.WEST);         } else {             remove(weekPanel);         }         this.weekOfYearVisible = weekOfYearVisible;         validate();         dayPanel.validate();     }     /**      * Returns the day panel.      *       * @return the day panel      */     public JPanel getDayPanel() {         return dayPanel;     }     /**      * Returns the color of the decoration (day names and weeks).      *       * @return the color of the decoration (day names and weeks).      */     public Color getDecorationBackgroundColor() {         return decorationBackgroundColor;     }     /**      * Sets the background of days and weeks of year buttons.      *       * @param decorationBackgroundColor      *            The background to set      */     public void setDecorationBackgroundColor(Color decorationBackgroundColor) {         this.decorationBackgroundColor = decorationBackgroundColor;         if (days != null) {             for (int i = 0; i < 7; i++) {                 days[i].setBackground(decorationBackgroundColor);             }         }         if (weeks != null) {             for (int i = 0; i < 7; i++) {                 weeks[i].setBackground(decorationBackgroundColor);             }         }     }     /**      * Returns the Sunday foreground.      *       * @return Color the Sunday foreground.      */     public Color getSundayForeground() {         return sundayForeground;     }     /**      * Returns the weekday foreground.      *       * @return Color the weekday foreground.      */     public Color getWeekdayForeground() {         return weekdayForeground;     }     /**      * Sets the Sunday foreground.      *       * @param sundayForeground      *            The sundayForeground to set      */     public void setSundayForeground(Color sundayForeground) {         this.sundayForeground = sundayForeground;         drawDayNames();         drawDays();     }     /**      * Sets the weekday foreground.      *       * @param weekdayForeground      *            The weekdayForeground to set      */     public void setWeekdayForeground(Color weekdayForeground) {         this.weekdayForeground = weekdayForeground;         drawDayNames();         drawDays();     }     /**      * Requests that the selected day also have the focus.      */     public void setFocus() {         if (selectedDay != null) {             this.selectedDay.requestFocus();         }     }     /**      * The decoration background is the background color of the day titles and      * the weeks of the year.      *       * @return Returns true, if the decoration background is painted.      */     public boolean isDecorationBackgroundVisible() {         return decorationBackgroundVisible;     }     /**      * The decoration background is the background color of the day titles and      * the weeks of the year.      *       * @param decorationBackgroundVisible      *            true, if the decoration background shall be painted.      */     public void setDecorationBackgroundVisible(             boolean decorationBackgroundVisible) {         this.decorationBackgroundVisible = decorationBackgroundVisible;         initDecorations();     }     /**      * The decoration border is the button border of the day titles and the      * weeks of the year.      *       * @return Returns true, if the decoration border is painted.      */     public boolean isDecorationBordersVisible() {         return decorationBordersVisible;     }     /**      * The decoration border is the button border of the day titles and the      * weeks of the year.      *       * @param decorationBordersVisible      *            true, if the decoration border shall be painted.      */     public void setDecorationBordersVisible(boolean decorationBordersVisible) {         this.decorationBordersVisible = decorationBordersVisible;         initDecorations();     }     /**      * Creates a JFrame with a JDayChooser inside and can be used for testing.      *       * @param s      *            The command line arguments      */     public static void main(String[] s) {         JFrame frame = new JFrame("JDayChooser");         frame.getContentPane().add(new JDayChooser());         frame.pack();         frame.setVisible(true);     } }