001 /*
002 * $Id: BasicCalendarHeaderHandler.java 3319 2009-03-31 15:39:29Z kleopatra $
003 *
004 * Copyright 2007 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 *
021 */
022 package org.jdesktop.swingx.plaf.basic;
023
024 import java.awt.Color;
025 import java.awt.Font;
026 import java.awt.event.ActionEvent;
027 import java.beans.PropertyChangeEvent;
028 import java.beans.PropertyChangeListener;
029 import java.text.DateFormatSymbols;
030 import java.util.Calendar;
031 import java.util.Locale;
032
033 import javax.swing.AbstractButton;
034 import javax.swing.Action;
035 import javax.swing.BorderFactory;
036 import javax.swing.Box;
037 import javax.swing.BoxLayout;
038
039 import org.jdesktop.swingx.JXHyperlink;
040 import org.jdesktop.swingx.JXMonthView;
041 import org.jdesktop.swingx.JXPanel;
042 import org.jdesktop.swingx.hyperlink.AbstractHyperlinkAction;
043 import org.jdesktop.swingx.renderer.StringValue;
044 import org.jdesktop.swingx.renderer.StringValues;
045
046
047 /**
048 * Custom implementation of a CalendarHeaderHandler in preparation of a vista-style
049 * calendar. Does nothing yet.
050 *
051 * @author Jeanette Winzenburg
052 */
053 public class BasicCalendarHeaderHandler extends CalendarHeaderHandler {
054
055
056 @Override
057 public void install(JXMonthView monthView) {
058 super.install(monthView);
059 getHeaderComponent().setActions(monthView.getActionMap().get("previousMonth"),
060 monthView.getActionMap().get("nextMonth"),
061 monthView.getActionMap().get("zoomOut"));
062
063 }
064
065
066
067 @Override
068 protected void installNavigationActions() {
069 // TODO Auto-generated method stub
070 super.installNavigationActions();
071 ZoomOutAction zoomOutAction = new ZoomOutAction();
072 zoomOutAction.setTarget(monthView);
073 monthView.getActionMap().put("zoomOut", zoomOutAction);
074 }
075
076
077
078 @Override
079 public void uninstall(JXMonthView monthView) {
080 getHeaderComponent().setActions(null, null, null);
081 super.uninstall(monthView);
082 }
083
084
085 @Override
086 public BasicCalendarHeader getHeaderComponent() {
087 // TODO Auto-generated method stub
088 return (BasicCalendarHeader) super.getHeaderComponent();
089 }
090
091 @Override
092 protected BasicCalendarHeader createCalendarHeader() {
093 return new BasicCalendarHeader();
094 }
095
096 /**
097 * Quick fix for Issue #1046-swingx: header text not updated if zoomable.
098 *
099 */
100 protected static class ZoomOutAction extends AbstractHyperlinkAction<JXMonthView> {
101
102 private PropertyChangeListener linkListener;
103 // Formatters/state used by Providers.
104 /** Localized month strings used in title. */
105 private String[] monthNames;
106 private StringValue tsv ;
107
108 public ZoomOutAction() {
109 super();
110 tsv = new StringValue() {
111
112 public String getString(Object value) {
113 if (value instanceof Calendar) {
114 String month = monthNames[((Calendar) value)
115 .get(Calendar.MONTH)];
116 return month + " "
117 + ((Calendar) value).get(Calendar.YEAR);
118 }
119 return StringValues.TO_STRING.getString(value);
120 }
121
122 };
123 }
124
125 public void actionPerformed(ActionEvent e) {
126 // TODO Auto-generated method stub
127
128 }
129
130
131 /**
132 * installs a propertyChangeListener on the target and
133 * updates the visual properties from the target.
134 */
135 @Override
136 protected void installTarget() {
137 if (getTarget() != null) {
138 getTarget().addPropertyChangeListener(getTargetListener());
139 }
140 updateLocale();
141 updateFromTarget();
142 }
143
144 /**
145 *
146 */
147 private void updateLocale() {
148 Locale current = getTarget() != null ? getTarget().getLocale() : Locale.getDefault();
149 monthNames = new DateFormatSymbols(current).getMonths();
150 }
151
152 /**
153 * removes the propertyChangeListener. <p>
154 *
155 * Implementation NOTE: this does not clean-up internal state! There is
156 * no need to because updateFromTarget handles both null and not-null
157 * targets. Hmm...
158 *
159 */
160 @Override
161 protected void uninstallTarget() {
162 if (getTarget() == null) return;
163 getTarget().removePropertyChangeListener(getTargetListener());
164 }
165
166 protected void updateFromTarget() {
167 // this happens on construction with null target
168 if (tsv == null) return;
169 Calendar calendar = getTarget() != null ? getTarget().getCalendar() : null;
170 setName(tsv.getString(calendar));
171 }
172
173 private PropertyChangeListener getTargetListener() {
174 if (linkListener == null) {
175 linkListener = new PropertyChangeListener() {
176
177 public void propertyChange(PropertyChangeEvent evt) {
178 if ("firstDisplayedDay".equals(evt.getPropertyName())) {
179 updateFromTarget();
180 } else if ("locale".equals(evt.getPropertyName())) {
181 updateLocale();
182 updateFromTarget();
183 }
184 }
185
186 };
187 }
188 return linkListener;
189 }
190
191
192 }
193
194
195 /**
196 * Active header for a JXMonthView in zoomable mode.<p>
197 *
198 * PENDING JW: very much work-in-progress.
199 */
200 static class BasicCalendarHeader extends JXPanel {
201
202 protected AbstractButton prevButton;
203 protected AbstractButton nextButton;
204 protected JXHyperlink zoomOutLink;
205
206 public BasicCalendarHeader() {
207 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
208 prevButton = createNavigationButton();
209 nextButton = createNavigationButton();
210 zoomOutLink = createZoomLink();
211 add(prevButton);
212 add(Box.createHorizontalGlue());
213 add(zoomOutLink);
214 add(Box.createHorizontalGlue());
215 add(nextButton);
216 setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
217 }
218
219 /**
220 * Sets the actions for backward, forward and zoom out navigation.
221 *
222 * @param prev
223 * @param next
224 * @param zoomOut
225 */
226 public void setActions(Action prev, Action next, Action zoomOut) {
227 prevButton.setAction(prev);
228 nextButton.setAction(next);
229 zoomOutLink.setAction(zoomOut);
230 }
231
232
233 /**
234 * {@inheritDoc} <p>
235 *
236 * Overridden to set the font of the zoom hyperlink.
237 */
238 @Override
239 public void setFont(Font font) {
240 super.setFont(font);
241 if (zoomOutLink != null)
242 zoomOutLink.setFont(font);
243 }
244
245 private JXHyperlink createZoomLink() {
246 JXHyperlink zoomOutLink = new JXHyperlink();
247 Color textColor = new Color(16, 66, 104);
248 zoomOutLink.setUnclickedColor(textColor);
249 zoomOutLink.setClickedColor(textColor);
250 zoomOutLink.setFocusable(false);
251 return zoomOutLink;
252 }
253
254 private AbstractButton createNavigationButton() {
255 JXHyperlink b = new JXHyperlink();
256 b.setContentAreaFilled(false);
257 b.setBorder(BorderFactory.createEmptyBorder());
258 b.setRolloverEnabled(true);
259 b.setFocusable(false);
260 return b;
261 }
262 }
263
264 }
265