package de.wannawork.jcalendar; /* * Copyright (c) 2003, Bodo Tasche (http://www.wannawork.de) All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in * binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ import java.applet.Applet; import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Font; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.AWTEventListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFormattedTextField; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JSpinner; import javax.swing.JSpinner.DateEditor; import javax.swing.JToolBar; import javax.swing.JWindow; import javax.swing.SpinnerDateModel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.text.BadLocationException; import javax.swing.text.DateFormatter; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.PlainDocument; /** * This Class creates a ComboBox for selecting the Date. If pressed, it shows a * Popup that contains a JCalendarPanel. * * You can add a ChangeListener to this ComboBox to receive change events. * * It is possible to change the Text on the ComboBox using the * DateFormat-Parameter. * * @author Bodo Tasche, David Freels */ public class JCalendarComboBox extends JPanel implements AncestorListener, ChangeListener, SwingConstants { public void setDateFormat(SimpleDateFormat aFormat) { _calendarPanel = null; panelDateFormat = aFormat; createGUI(); } protected class CalendarPanelComponentListener implements ComponentListener { @Override public void componentResized(ComponentEvent e) { } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentShown(ComponentEvent e) { } @Override public void componentHidden(ComponentEvent e) { if (e.getComponent() == _calendarPanel) { _changed = false; hideCalendar(); } } } private static JCalendarComboBox comboWithPopupShown = null; private static AWTEventListener awtMonitor = new AWTEventListener() { @Override public void eventDispatched(AWTEvent event) { if (event instanceof MouseEvent) { MouseEvent me = (MouseEvent) event; Component src = me.getComponent(); switch (me.getID()) { case MouseEvent.MOUSE_PRESSED: if (!isInPopup(src, me.getPoint())) { cancelPopupCalendar(); } break; case MouseEvent.MOUSE_RELEASED: if (!isInPopup(src, me.getPoint())) { cancelPopupCalendar(); } break; case MouseEvent.MOUSE_DRAGGED: if (!isInPopup(src, me.getPoint())) { cancelPopupCalendar(); } break; case MouseEvent.MOUSE_WHEEL: if (!isInPopup(src, me.getPoint())) { cancelPopupCalendar(); } break; } } } boolean isInPopup(Component src, Point aPt) { for (Component c = src; c != null; c = c instanceof JPopupMenu ? ((JPopupMenu) c).getInvoker() : c.getParent()) { if (c instanceof Applet || (c instanceof Window && !(c instanceof JCalendarPopupWindow))) { break; } else if (c instanceof JCalendarPopupWindow || c instanceof JCalendarInvokerButton) { return true; } } if (comboWithPopupShown != null && comboWithPopupShown.isCalendarShown()) { Point converted = SwingUtilities.convertPoint(src, aPt, comboWithPopupShown.getCalendarPanel()); Rectangle bounds = comboWithPopupShown.getCalendarPanel().getBounds(); bounds.setLocation(0, 0); if (converted != null && bounds.contains(converted)) { return true; } JCalendarInvokerButton lbtn = comboWithPopupShown.getDropDownButton(); bounds = lbtn.getBounds(); bounds.setLocation(0, 0); converted = SwingUtilities.convertPoint(src, aPt, lbtn); if (converted != null && bounds.contains(converted)) { return true; } } return false; } }; static { Toolkit.getDefaultToolkit().addAWTEventListener(awtMonitor, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK); } public static void cancelPopupCalendar() { if (comboWithPopupShown != null && comboWithPopupShown.isCalendarShown()) { comboWithPopupShown.hideCalendar(); assert comboWithPopupShown == null; } } private static class WindowWatchDog implements WindowListener, ComponentListener { @Override public void windowClosing(WindowEvent e) { cancelPopupCalendar(); } @Override public void windowClosed(WindowEvent e) { cancelPopupCalendar(); } @Override public void windowIconified(WindowEvent e) { cancelPopupCalendar(); } @Override public void windowDeactivated(WindowEvent e) { cancelPopupCalendar(); } @Override public void windowOpened(WindowEvent e) { cancelPopupCalendar(); } @Override public void windowDeiconified(WindowEvent e) { cancelPopupCalendar(); } @Override public void windowActivated(WindowEvent e) { cancelPopupCalendar(); } @Override public void componentResized(ComponentEvent e) { cancelPopupCalendar(); } @Override public void componentMoved(ComponentEvent e) { if (targetLocation == null || !targetLocation.equals(e.getComponent().getLocation())) { cancelPopupCalendar(); } } @Override public void componentShown(ComponentEvent e) { cancelPopupCalendar(); } @Override public void componentHidden(ComponentEvent e) { cancelPopupCalendar(); } private Point targetLocation; private void setTargetSize(Point aPt) { targetLocation = aPt; } } private WindowWatchDog calendarWatchDog = new WindowWatchDog(); /** * Creates a Calendar using the current Date and current Local settings. */ public JCalendarComboBox() { panelCal = (Calendar) Calendar.getInstance().clone(); panelLocale = Locale.getDefault(); panelDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); panelFlat = true; panelCalendarPanelDialogStyle = false; //_calendarPanel = new JCalendarPanel(); createGUI(); } /** * Creates a Calendar using the current Date and current Local settings. * * @param calendarPanelDialogStyle */ public JCalendarComboBox(boolean calendarPanelDialogStyle) { panelCal = (Calendar) Calendar.getInstance().clone(); panelLocale = Locale.getDefault(); panelDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); panelFlat = true; panelCalendarPanelDialogStyle = calendarPanelDialogStyle; //_calendarPanel = new JCalendarPanel(); createGUI(); } /** * Creates a Calendar using the cal-Date and current Locale Settings. It * doesn't use the Locale in the Calendar-Object ! * * @param cal Calendar to use */ public JCalendarComboBox(Calendar cal) { panelCal = cal; panelLocale = Locale.getDefault(); panelDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); panelFlat = true; panelCalendarPanelDialogStyle = false; //_calendarPanel = new JCalendarPanel(cal); createGUI(); } /** * Creates a Calendar using the current Date and the given Locale Settings. * * @param locale Locale to use */ public JCalendarComboBox(Locale locale) { panelCal = (Calendar) Calendar.getInstance().clone(); panelLocale = locale; panelDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); panelFlat = true; panelCalendarPanelDialogStyle = false; //_calendarPanel = new JCalendarPanel(locale); createGUI(); } /** * Creates a Calender using the given Date and Locale * * @param cal Calendar to use * @param locale Locale to use */ public JCalendarComboBox(Calendar cal, Locale locale) { panelCal = cal; panelLocale = locale; panelDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); panelFlat = true; panelCalendarPanelDialogStyle = false; _calendarPanel = new JCalendarPanel(cal, locale); createGUI(); } /** * Creates a Calender using the given Calendar, Locale and DateFormat. * * @param cal Calendar to use * @param locale Locale to use * @param dateFormat DateFormat for the ComboBox */ public JCalendarComboBox(Calendar cal, Locale locale, DateFormat dateFormat) { panelCal = cal; panelLocale = locale; panelDateFormat = dateFormat; panelFlat = true; panelCalendarPanelDialogStyle = false; //_calendarPanel = new JCalendarPanel(cal, locale, dateFormat); createGUI(); } /** * Creates a Calender using the given Calendar, Locale and DateFormat. * * @param cal Calendar to use * @param locale Locale to use * @param dateFormat DateFormat for the ComboBox * @param location Location of the Popup (LEFT, CENTER or RIGHT) */ public JCalendarComboBox(Calendar cal, Locale locale, DateFormat dateFormat, int location) { panelCal = cal; panelLocale = locale; panelDateFormat = dateFormat; panelFlat = true; panelCalendarPanelDialogStyle = false; //_calendarPanel = new JCalendarPanel(cal, locale, dateFormat); _popupLocation = location; createGUI(); } /** * Creates a Calender using the given Calendar, Locale and DateFormat. * * @param cal Calendar to use * @param locale Locale to use * @param dateFormat DateFormat for the ComboBox * @param location Location of the Popup (LEFT, CENTER or RIGHT) * @param flat Flat Buttons for next/last Month/Year */ public JCalendarComboBox(Calendar cal, Locale locale, DateFormat dateFormat, int location, boolean flat) { panelCal = cal; panelLocale = locale; panelDateFormat = dateFormat; panelFlat = flat; panelCalendarPanelDialogStyle = false; //_calendarPanel = new JCalendarPanel(cal, locale, dateFormat, flat); _popupLocation = location; createGUI(); } /** * Creates a Calender using the given Calendar, Locale and DateFormat. * * @param cal Calendar to use * @param locale Locale to use * @param dateFormat DateFormat for the ComboBox * @param location Location of the Popup (LEFT, CENTER or RIGHT) * @param flat Flat Buttons for next/last Month/Year * @param calendarPanelDialogStyle */ public JCalendarComboBox(Calendar cal, Locale locale, DateFormat dateFormat, int location, boolean flat, boolean calendarPanelDialogStyle) { panelCal = cal; panelLocale = locale; panelDateFormat = dateFormat; panelFlat = flat; panelCalendarPanelDialogStyle = calendarPanelDialogStyle; _popupLocation = location; createGUI(); } private Calendar panelCal; private Locale panelLocale; private DateFormat panelDateFormat; private boolean panelFlat; private boolean panelCalendarPanelDialogStyle; private void checkDialogGUI() { if (_calendarPanel == null) { createDialogGUI(); } } /** * Creates the GUI for drop down part */ private void createDialogGUI() { _calendarPanel = new JCalendarPanel(panelCal, panelLocale, panelDateFormat, panelFlat, panelCalendarPanelDialogStyle); _calendarPanel.setListenerModus(JCalendarPanel.FIRE_DAYCHANGES); _calendarPanel.setCalendar(_selected); _calendarPanel.addChangeListener(this); _calendarPanel.addComponentListener(new CalendarPanelComponentListener()); _calendarPanel.setBorder(BorderFactory.createLineBorder(Color.black)); } /** * Creates the GUI for the JCalendarComboBox */ private void createGUI() { _selected = (Calendar) panelCal.clone(); setLayout(new BorderLayout()); _spinner = new JSpinner(); _spinner.setModel(new NullableSpinnerDateModel()); _spinner.setFont(getFont()); SimpleDateFormat lFormat = (SimpleDateFormat) panelDateFormat; final JSpinner.DateEditor dEditor = new JSpinner.DateEditor(_spinner, lFormat.toPattern()); DateFormatter df = new OptimisticDateFormatter(lFormat); df.setAllowsInvalid(false); df.setOverwriteMode(true); dEditor.getTextField().setFormatterFactory(new DefaultFormatterFactory(df)); dEditor.getTextField().setEditable(editable); dEditor.getTextField().setDocument(new PlainDocument() { @Override public void remove(int offs, int len) throws BadLocationException { super.remove(offs, len); dEditor.getTextField().getCaret().setDot(offs); } }); _spinner.setEditor(dEditor); _spinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { Date date = (Date) _spinner.getModel().getValue(); if (date != null) { if (_selected == null) { _selected = (Calendar) Calendar.getInstance().clone(); } _selected.setTime(date); } else { _selected = null; } if (_calendarPanel != null) { _calendarPanel.setCalendar(_selected); } fireChangeEvent(); } }); ((JSpinner.DefaultEditor) _spinner.getEditor()).getTextField().addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { Date date = (Date) _spinner.getModel().getValue(); if (date != null) { if (_selected == null) { _selected = (Calendar) Calendar.getInstance().clone(); } _selected.setTime(date); } else { _selected = null; } if (_calendarPanel != null) { _calendarPanel.setCalendar(_selected); } fireChangeEvent(); } }); add(_spinner, BorderLayout.CENTER); JToolBar btns = new JToolBar(); btns.setRollover(true); btns.setFloatable(false); btns.setBorderPainted(false); btns.setBorder(null); URL url = JCalendarComboBox.class.getClassLoader().getResource("de/wannawork/jcalendar/calendar.png"); ImageIcon icon = new ImageIcon(url); _dropDownButton = new JCalendarInvokerButton(); _dropDownButton.setIcon(icon); _dropDownButton.setBorderPainted(false); _dropDownButton.setBorder(new EmptyBorder(0, 1, 0, 1)); _dropDownButton.setEnabled(editable && isEnabled()); btns.add(_dropDownButton); add(btns, BorderLayout.EAST); _dropDownButton.setFocusable(false); _dropDownButton.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (_dropDownButton.isEnabled()) { if (!isCalendarShown()) { showCalendar(); } else { hideCalendar(); } } else { cancelPopupCalendar(); } } }); } public void setBorderless(boolean aBorderless) { isBorderless = aBorderless; if (isBorderless) { _spinner.setBorder(null); } } public boolean isEditable() { return editable; } public void setEditable(boolean aEditable) { editable = aEditable; if (_spinner != null && _spinner.getEditor() instanceof JSpinner.DateEditor) { JSpinner.DateEditor dEditor = (JSpinner.DateEditor) _spinner.getEditor(); if (dEditor != null && dEditor.getTextField() != null) { dEditor.getTextField().setEditable(editable); } } if (_spinner != null) { _spinner.setEnabled(editable && isEnabled()); } if (_dropDownButton != null) { _dropDownButton.setEnabled(editable && isEnabled()); } } @Override public void updateUI() { super.updateUI(); if (isBorderless) { _spinner.setBorder(null); } } @Override public void setFont(Font font) { super.setFont(font); if (_spinner != null) { _spinner.setFont(font); } } @Override public void setToolTipText(String aText) { super.setToolTipText(aText); if (_spinner != null) { _spinner.setToolTipText(aText); } if (_dropDownButton != null) { _dropDownButton.setToolTipText(aText); } } @Override public void setCursor(Cursor aCursor) { super.setCursor(aCursor); if (_spinner != null) { _spinner.setCursor(aCursor); if (_spinner.getEditor() != null) { JComponent comp = _spinner.getEditor(); comp.setCursor(getCursor()); for (int i = 0; i < comp.getComponentCount(); i++) { if (comp.getComponent(i) != null) { comp.getComponent(i).setCursor(getCursor()); } } } } if (_dropDownButton != null) { _dropDownButton.setCursor(aCursor); } } @Override public void setBackground(Color bg) { super.setBackground(bg); if (_spinner != null) { _spinner.setBackground(bg); if (_spinner.getEditor() != null && _spinner.getEditor() instanceof JSpinner.DateEditor) { JSpinner.DateEditor de = (JSpinner.DateEditor) _spinner.getEditor(); if (de.getTextField() != null) { de.getTextField().setBackground(bg); } } } } @Override public void setForeground(Color fg) { super.setForeground(fg); if (_spinner != null) { _spinner.setForeground(fg); if (_spinner.getEditor() != null && _spinner.getEditor() instanceof JSpinner.DateEditor) { JSpinner.DateEditor de = (JSpinner.DateEditor) _spinner.getEditor(); if (de.getTextField() != null) { de.getTextField().setForeground(fg); } } } } /** * Creates the CalendarWindow-Popup */ private void createCalendarWindow() { createCalendarWindow(null); } private void createCalendarWindow(Window aAncestor) { if (aAncestor != null) { _calendarWindow = new JCalendarPopupWindow(aAncestor); } else { _calendarWindow = new JCalendarPopupWindow(); } JPanel contentPanel = (JPanel) _calendarWindow.getContentPane(); contentPanel.setLayout(new BorderLayout()); contentPanel.add(_calendarPanel, BorderLayout.CENTER); _calendarWindow.pack(); } /** * Returns the current seleted Date as Calendar * * @return current selected Date */ public Calendar getCalendar() { return _calendarPanel.getCalendar(); } /** * Sets the current selected Date * * @param cal Date to select */ public void setCalendar(Calendar cal) { _calendarPanel.setCalendar(cal); _spinner.getModel().setValue(cal != null ? cal.getTime() : null); } /** * Returns the JCalendarPanel that is shown in the PopUp * * @return JCalendarPanel in the PopUp */ public JCalendarPanel getCalendarPanel() { return _calendarPanel; } /** * Sets the Popup Location (Left/Right/Center) * * @param location */ public void setPopUpLocation(int location) { _popupLocation = location; } /** * Returns the Popup Location * * @return Location of the Popup */ public int getPopUpLocation() { return _popupLocation; } /** * Sets the horizontal Position of the Text in the Button * * @param value RIGHT, LEFT, CENTER, LEADING, TRAILING for horizontal * Alignment */ public void setHorizontalAlignment(int value) { ((JSpinner.DefaultEditor) _spinner.getEditor()).getTextField().setHorizontalAlignment(value); } /** * Hides the Calendar PopUp and fires a ChangeEvent if a change was made */ public void hideCalendar() { if (_calendarPanel != null) { if (_calendarWindow.isVisible()) { _calendarWindow.setVisible(false); _calendarWindow.dispose(); if (!_calendarPanel.isDialogStyle() && !_calendarPanel.getCalendar().getTime().equals(_spinner.getModel().getValue())) { _changed = true; } if (_changed) { if (_calendarPanel.getCalendar() != null) { _spinner.getModel().setValue(_calendarPanel.getCalendar().getTime()); _selected = (Calendar) _calendarPanel.getCalendar().clone(); } else { _spinner.getModel().setValue(null); _selected = null; } _changed = false; fireChangeEvent(); } if (comboWithPopupShown == this) { comboWithPopupShown = null; } } } } public boolean isCalendarShown() { return _calendarWindow != null && _calendarWindow.isVisible(); } /** * Shows the Calendar Popup */ public void showCalendar() { checkDialogGUI(); Window ancestor = (Window) this.getTopLevelAncestor(); if ((_calendarWindow == null) || (ancestor != _calendarWindow.getOwner())) { if (ancestor instanceof JDialog) { createCalendarWindow(ancestor); } else { createCalendarWindow(); } } //Update the date from the spinner model Date date = (Date) _spinner.getModel().getValue(); if (_selected != null) { _selected.setTime(date != null ? date : ((Calendar) Calendar.getInstance().clone()).getTime()); } _calendarPanel.setCalendar(_selected); Point location = getLocationOnScreen(); int x; if (_popupLocation == RIGHT) { x = (int) location.getX() + getSize().width - _calendarWindow.getSize().width; } else if (_popupLocation == CENTER) { x = (int) location.getX() + ((getSize().width - _calendarWindow.getSize().width) / 2); } else { x = (int) location.getX(); } int y = (int) location.getY() + getHeight() - 1; Rectangle screenSize = getDesktopBounds(); if (x < 0) { x = 0; } if (y < 0) { y = 0; } if (x + _calendarWindow.getWidth() > screenSize.width) { x = screenSize.width - _calendarWindow.getWidth(); } if (y + 30 + _calendarWindow.getHeight() > screenSize.height) { y = (int) location.getY() - _calendarWindow.getHeight(); } _calendarWindow.setBounds(x, y, _calendarWindow.getWidth(), _calendarWindow.getHeight()); _calendarWindow.setVisible(true); if (comboWithPopupShown != null && comboWithPopupShown != this && comboWithPopupShown.isCalendarShown()) { comboWithPopupShown.hideCalendar(); assert comboWithPopupShown == null; } comboWithPopupShown = this; Window w = SwingUtilities.getWindowAncestor(this); w.removeWindowListener(calendarWatchDog); w.removeComponentListener(calendarWatchDog); w.addWindowListener(calendarWatchDog); calendarWatchDog.setTargetSize(new Point(w.getLocation())); w.addComponentListener(calendarWatchDog); } public static void setFocusableRecursive(Component aComp, boolean aValue) { aComp.setFocusable(aValue); if (aComp instanceof JComponent) { JComponent jComp = (JComponent) aComp; for (int i = 0; i < jComp.getComponentCount(); i++) { setFocusableRecursive(jComp.getComponent(i), aValue); } } } /** * Gets the screensize. Takes into account multi-screen displays. * * @return a union of the bounds of the various screen devices present */ private Rectangle getDesktopBounds() { final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); final GraphicsDevice[] gd = ge.getScreenDevices(); final Rectangle[] screenDeviceBounds = new Rectangle[gd.length]; Rectangle desktopBounds = new Rectangle(); for (int i = 0; i < gd.length; i++) { final GraphicsConfiguration gc = gd[i].getDefaultConfiguration(); screenDeviceBounds[i] = gc.getBounds(); desktopBounds = desktopBounds.union(screenDeviceBounds[i]); } return desktopBounds; } public JCalendarInvokerButton getDropDownButton() { return _dropDownButton; } /* * (non-Javadoc) * * @see javax.swing.event.AncestorListener#ancestorAdded(javax.swing.event.AncestorEvent) */ @Override public void ancestorAdded(AncestorEvent event) { hideCalendar(); } /* * (non-Javadoc) * * @see javax.swing.event.AncestorListener#ancestorMoved(javax.swing.event.AncestorEvent) */ @Override public void ancestorMoved(AncestorEvent event) { //hideCalendar(); } /* * (non-Javadoc) * * @see javax.swing.event.AncestorListener#ancestorRemoved(javax.swing.event.AncestorEvent) */ @Override public void ancestorRemoved(AncestorEvent event) { hideCalendar(); } /** * Listens to ChangeEvents of the JCalendarPanel and rembers if something * was changed. * * If the Day was changed, the PopUp is closed. * * @param e ChangeEvent * @see * javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) */ @Override public void stateChanged(ChangeEvent e) { _changed = true; hideCalendar(); } /** * Adds a Changelistener to this JCalendarComboBox. * * It will be called everytime the ComboBox is closed and the Date was * changed * * @param listener ChangeListener */ public void addChangeListener(ChangeListener listener) { _changeListener.add(listener); } /** * Removes a ChangeListener from this JCalendarComboBox * * @param listener listener to remove */ public void removeChangeListener(ChangeListener listener) { _changeListener.remove(listener); } /** * Gets all ChangeListeners * * @return all ChangeListeners */ public ChangeListener[] getChangeListener() { return (ChangeListener[]) _changeListener.toArray(); } /** * Fires the ChangeEvent */ protected void fireChangeEvent() { if (!_fireingChangeEvent) { _fireingChangeEvent = true; ChangeEvent event = new ChangeEvent(this); for (int i = 0; i < _changeListener.size(); i++) { ((ChangeListener) _changeListener.get(i)).stateChanged(event); } _fireingChangeEvent = false; } } /** * Enables/Disables the ComboBox * * @param enabled Enabled ? */ @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); _spinner.setEnabled(enabled); _dropDownButton.setEnabled(editable && enabled); for (int i = 0; i < _spinner.getComponentCount(); i++) { _spinner.getComponent(i).setEnabled(enabled); } } /** * Gets the Popup Location * * @return location of the Popup */ public int getPopupLocation() { return _popupLocation; } /** * Sets the Location of the Popup (LEFT, CENTER or RIGHT) * * @param location Location of the PopUp */ public void setPopupLocation(int location) { _popupLocation = location; } /** * Returns the model used to hold the Date object * * @return */ public SpinnerDateModel getModel() { return (SpinnerDateModel) _spinner.getModel(); } public JFormattedTextField getEditorComponent() { if (_spinner.getEditor() instanceof JSpinner.DateEditor) { return ((JSpinner.DateEditor) _spinner.getEditor()).getTextField(); } return null; } /** * Sets the model used to hold the Date object * * @param model A SpinnerDateModel to be used by the spinner control. */ public void setSpinnerDateModel(SpinnerDateModel model) { _spinner.setModel(model); } @Override public void setOpaque(boolean aValue) { super.setOpaque(aValue); if (_spinner != null) { _spinner.setOpaque(aValue); JComponent editor = _spinner.getEditor(); if (editor != null) { editor.setOpaque(aValue); if (editor instanceof DateEditor) { if (((DateEditor) editor).getTextField() != null) { ((DateEditor) editor).getTextField().setOpaque(aValue); } } } } } /** * Where should be the Popup? */ private int _popupLocation = LEFT; protected Date _date2Hide; /** * Current selected Day */ private Calendar _selected; private boolean isBorderless; private boolean editable = true; /** * The text field that holds the date */ private JSpinner _spinner; private JCalendarInvokerButton _dropDownButton; /** * The JWindow for the Popup */ private JWindow _calendarWindow; /** * The JCalendarPanel inside the PopUp */ private JCalendarPanel _calendarPanel; /** * The list of ChangeListeners */ private ArrayList _changeListener = new ArrayList(); /** * Currently firing an ChangeEvent? */ private boolean _fireingChangeEvent = false; /** * Something changed in the JCalendarPanel ? */ private boolean _changed = false; }