001 /* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
006 *
007 * Project Info: http://www.jfree.org/jfreechart/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it
010 * under the terms of the GNU Lesser General Public License as published by
011 * the Free Software Foundation; either version 2.1 of the License, or
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022 * USA.
023 *
024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025 * in the United States and other countries.]
026 *
027 * --------------------
028 * MonthDateFormat.java
029 * --------------------
030 * (C) Copyright 2005-2007, by Object Refinery Limited and Contributors.
031 *
032 * Original Author: David Gilbert (for Object Refinery Limited);
033 * Contributor(s): -;
034 *
035 * Changes:
036 * --------
037 * 10-May-2005 : Version 1 (DG);
038 *
039 */
040
041 package org.jfree.chart.axis;
042
043 import java.text.DateFormat;
044 import java.text.DateFormatSymbols;
045 import java.text.FieldPosition;
046 import java.text.NumberFormat;
047 import java.text.ParsePosition;
048 import java.text.SimpleDateFormat;
049 import java.util.Arrays;
050 import java.util.Calendar;
051 import java.util.Date;
052 import java.util.GregorianCalendar;
053 import java.util.Locale;
054 import java.util.TimeZone;
055
056 import org.jfree.data.time.Month;
057
058 /**
059 * A formatter that formats dates to show the initial letter(s) of the month
060 * name and, as an option, the year for the first or last month of each year.
061 */
062 public class MonthDateFormat extends DateFormat {
063
064 /** The symbols used for the months. */
065 private String[] months;
066
067 /** Flags that control which months will have the year appended. */
068 private boolean[] showYear;
069
070 /** The year formatter. */
071 private DateFormat yearFormatter;
072
073 /**
074 * Creates a new instance for the default time zone.
075 */
076 public MonthDateFormat() {
077 this(TimeZone.getDefault());
078 }
079
080 /**
081 * Creates a new instance for the specified time zone.
082 *
083 * @param zone the time zone (<code>null</code> not permitted).
084 */
085 public MonthDateFormat(TimeZone zone) {
086 this(zone, Locale.getDefault(), 1, true, false);
087 }
088
089 /**
090 * Creates a new instance for the specified time zone.
091 *
092 * @param locale the locale used to obtain the month
093 * names (<code>null</code> not permitted).
094 */
095 public MonthDateFormat(Locale locale) {
096 this(TimeZone.getDefault(), locale, 1, true, false);
097 }
098
099 /**
100 * Creates a new instance for the specified time zone.
101 *
102 * @param zone the time zone (<code>null</code> not permitted).
103 * @param chars the maximum number of characters to use from the month
104 * names (that are obtained from the date symbols of the
105 * default locale). If this value is <= 0, the entire
106 * month name is used in each case.
107 */
108 public MonthDateFormat(TimeZone zone, int chars) {
109 this(zone, Locale.getDefault(), chars, true, false);
110 }
111
112 /**
113 * Creates a new instance for the specified time zone.
114 *
115 * @param locale the locale (<code>null</code> not permitted).
116 * @param chars the maximum number of characters to use from the month
117 * names (that are obtained from the date symbols of the
118 * default locale). If this value is <= 0, the entire
119 * month name is used in each case.
120 */
121 public MonthDateFormat(Locale locale, int chars) {
122 this(TimeZone.getDefault(), locale, chars, true, false);
123 }
124
125 /**
126 * Creates a new formatter.
127 *
128 * @param zone the time zone used to extract the month and year from dates
129 * passed to this formatter (<code>null</code> not permitted).
130 * @param locale the locale used to determine the month names
131 * (<code>null</code> not permitted).
132 * @param chars the maximum number of characters to use from the month
133 * names, or zero to indicate that the entire month name
134 * should be used.
135 * @param showYearForJan a flag that controls whether or not the year is
136 * appended to the symbol for the first month of
137 * each year.
138 * @param showYearForDec a flag that controls whether or not the year is
139 * appended to the symbol for the last month of
140 * each year.
141 */
142 public MonthDateFormat(TimeZone zone, Locale locale, int chars,
143 boolean showYearForJan, boolean showYearForDec) {
144 this(zone, locale, chars, new boolean[] {showYearForJan, false, false,
145 false, false, false, false, false, false, false, false, false,
146 showYearForDec}, new SimpleDateFormat("yy"));
147 }
148
149 /**
150 * Creates a new formatter.
151 *
152 * @param zone the time zone used to extract the month and year from dates
153 * passed to this formatter (<code>null</code> not permitted).
154 * @param locale the locale used to determine the month names
155 * (<code>null</code> not permitted).
156 * @param chars the maximum number of characters to use from the month
157 * names, or zero to indicate that the entire month name
158 * should be used.
159 * @param showYear an array of flags that control whether or not the
160 * year is displayed for a particular month.
161 * @param yearFormatter the year formatter.
162 */
163 public MonthDateFormat(TimeZone zone, Locale locale, int chars,
164 boolean[] showYear, DateFormat yearFormatter) {
165 if (locale == null) {
166 throw new IllegalArgumentException("Null 'locale' argument.");
167 }
168 DateFormatSymbols dfs = new DateFormatSymbols(locale);
169 String[] monthsFromLocale = dfs.getMonths();
170 this.months = new String[12];
171 for (int i = 0; i < 12; i++) {
172 if (chars > 0) {
173 this.months[i] = monthsFromLocale[i].substring(0,
174 Math.min(chars, monthsFromLocale[i].length()));
175 }
176 else {
177 this.months[i] = monthsFromLocale[i];
178 }
179 }
180 this.calendar = new GregorianCalendar(zone);
181 this.showYear = showYear;
182 this.yearFormatter = yearFormatter;
183
184 // the following is never used, but it seems that DateFormat requires
185 // it to be non-null. It isn't well covered in the spec, refer to
186 // bug parade 5061189 for more info.
187 this.numberFormat = NumberFormat.getNumberInstance();
188 }
189
190 /**
191 * Formats the given date.
192 *
193 * @param date the date.
194 * @param toAppendTo the string buffer.
195 * @param fieldPosition the field position.
196 *
197 * @return The formatted date.
198 */
199 public StringBuffer format(Date date, StringBuffer toAppendTo,
200 FieldPosition fieldPosition) {
201 this.calendar.setTime(date);
202 int month = this.calendar.get(Calendar.MONTH);
203 toAppendTo.append(this.months[month]);
204 if (this.showYear[month]) {
205 toAppendTo.append(this.yearFormatter.format(date));
206 }
207 return toAppendTo;
208 }
209
210 /**
211 * Parses the given string (not implemented).
212 *
213 * @param source the date string.
214 * @param pos the parse position.
215 *
216 * @return <code>null</code>, as this method has not been implemented.
217 */
218 public Date parse(String source, ParsePosition pos) {
219 return null;
220 }
221
222 /**
223 * Tests this formatter for equality with an arbitrary object.
224 *
225 * @param obj the object.
226 *
227 * @return A boolean.
228 */
229 public boolean equals(Object obj) {
230 if (obj == this) {
231 return true;
232 }
233 if (!(obj instanceof MonthDateFormat)) {
234 return false;
235 }
236 if (!super.equals(obj)) {
237 return false;
238 }
239 MonthDateFormat that = (MonthDateFormat) obj;
240 if (!Arrays.equals(this.months, that.months)) {
241 return false;
242 }
243 if (!Arrays.equals(this.showYear, that.showYear)) {
244 return false;
245 }
246 if (!this.yearFormatter.equals(that.yearFormatter)) {
247 return false;
248 }
249 return true;
250 }
251
252 /**
253 * Some test code.
254 *
255 * @param args ignored.
256 */
257 public static void main(String[] args) {
258 MonthDateFormat mdf = new MonthDateFormat(Locale.UK, 2);
259 System.out.println("UK:");
260 System.out.println(mdf.format(new Month(1, 2005).getStart()));
261 System.out.println(mdf.format(new Month(2, 2005).getStart()));
262 System.out.println(mdf.format(new Month(3, 2005).getStart()));
263 System.out.println(mdf.format(new Month(4, 2005).getStart()));
264 System.out.println(mdf.format(new Month(5, 2005).getStart()));
265 System.out.println(mdf.format(new Month(6, 2005).getStart()));
266 System.out.println(mdf.format(new Month(7, 2005).getStart()));
267 System.out.println(mdf.format(new Month(8, 2005).getStart()));
268 System.out.println(mdf.format(new Month(9, 2005).getStart()));
269 System.out.println(mdf.format(new Month(10, 2005).getStart()));
270 System.out.println(mdf.format(new Month(11, 2005).getStart()));
271 System.out.println(mdf.format(new Month(12, 2005).getStart()));
272 System.out.println();
273
274 mdf = new MonthDateFormat(Locale.GERMANY, 2);
275 System.out.println("GERMANY:");
276 System.out.println(mdf.format(new Month(1, 2005).getStart()));
277 System.out.println(mdf.format(new Month(2, 2005).getStart()));
278 System.out.println(mdf.format(new Month(3, 2005).getStart()));
279 System.out.println(mdf.format(new Month(4, 2005).getStart()));
280 System.out.println(mdf.format(new Month(5, 2005).getStart()));
281 System.out.println(mdf.format(new Month(6, 2005).getStart()));
282 System.out.println(mdf.format(new Month(7, 2005).getStart()));
283 System.out.println(mdf.format(new Month(8, 2005).getStart()));
284 System.out.println(mdf.format(new Month(9, 2005).getStart()));
285 System.out.println(mdf.format(new Month(10, 2005).getStart()));
286 System.out.println(mdf.format(new Month(11, 2005).getStart()));
287 System.out.println(mdf.format(new Month(12, 2005).getStart()));
288 System.out.println();
289
290 mdf = new MonthDateFormat(Locale.FRANCE, 2);
291 System.out.println("FRANCE:");
292 System.out.println(mdf.format(new Month(1, 2005).getStart()));
293 System.out.println(mdf.format(new Month(2, 2005).getStart()));
294 System.out.println(mdf.format(new Month(3, 2005).getStart()));
295 System.out.println(mdf.format(new Month(4, 2005).getStart()));
296 System.out.println(mdf.format(new Month(5, 2005).getStart()));
297 System.out.println(mdf.format(new Month(6, 2005).getStart()));
298 System.out.println(mdf.format(new Month(7, 2005).getStart()));
299 System.out.println(mdf.format(new Month(8, 2005).getStart()));
300 System.out.println(mdf.format(new Month(9, 2005).getStart()));
301 System.out.println(mdf.format(new Month(10, 2005).getStart()));
302 System.out.println(mdf.format(new Month(11, 2005).getStart()));
303 System.out.println(mdf.format(new Month(12, 2005).getStart()));
304 System.out.println();
305
306 SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
307 sdf.setNumberFormat(null);
308 }
309 }