001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2008, 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-2008, 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 }