1 package tim.prune.gui.colour;
4 import java.text.DateFormat;
5 import java.util.Calendar;
6 import java.util.HashMap;
7 import java.util.TimeZone;
9 import tim.prune.config.Config;
10 import tim.prune.data.DataPoint;
11 import tim.prune.data.Timestamp;
12 import tim.prune.data.Track;
13 import tim.prune.data.TrackInfo;
16 * Point colourer giving a different colour to each date.
17 * Uses the currently selected timezone, so the results
18 * may be different when selecting a different timezone
20 public class DateColourer extends DiscretePointColourer
22 // Doesn't really matter what format is used here, as long as dates are different
23 private static final DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateInstance();
24 // Selected timezone for deciding which date a timestamp falls on
25 private TimeZone _selectedTimezone = null;
29 * @param inStartColour start colour of scale
30 * @param inEndColour end colour of scale
31 * @param inWrapLength number of unique colours before wrap
33 public DateColourer(Color inStartColour, Color inEndColour, int inWrapLength)
35 super(inStartColour, inEndColour, inWrapLength);
39 * Calculate the colours for each of the points in the given track
40 * @param inTrackInfo track info object
43 public synchronized void calculateColours(TrackInfo inTrackInfo)
45 // Note, this method needs to be synchronized because otherwise the
46 // Calendar objects in the different threads get confused and the
47 // wrong colours are generated.
49 // TODO: Move this timezone-selection into a helper for use by others?
50 // Select the current timezone
51 final String zoneId = Config.getConfigString(Config.KEY_TIMEZONE_ID);
52 if (zoneId == null || zoneId.equals("")) {
53 _selectedTimezone = TimeZone.getDefault();
56 _selectedTimezone = TimeZone.getTimeZone(zoneId);
58 // initialise the array to the right size
59 Track track = inTrackInfo == null ? null : inTrackInfo.getTrack();
60 final int numPoints = track == null ? 0 : track.getNumPoints();
62 // Make a hashmap of the already-used dates
63 HashMap<String, Integer> usedDates = new HashMap<String, Integer>(20);
64 // Also store the previous one, because they're probably consecutive
65 String prevDate = null;
68 // loop over track points
70 for (int i=0; i<numPoints; i++)
72 DataPoint p = track.getPoint(i);
73 if (p != null && !p.isWaypoint())
75 dayIndex = 0; // default index 0 will be used if no date found
76 String date = getDate(p.getTimestamp());
79 // Check if it's the previous one
80 if (prevDate != null && date.equals(prevDate)) {
85 // Look up in the hashmap to see if it's been used before
86 Integer foundIndex = usedDates.get(date);
87 if (foundIndex == null)
89 // not been used before, so add it
90 dayIndex = usedDates.size() + 1;
91 usedDates.put(date, dayIndex);
96 dayIndex = foundIndex;
98 // Remember what we've got for the next point
100 prevIndex = dayIndex;
103 // if date is null (no timestamp or invalid) then dayIndex remains 0
104 setColour(i, dayIndex);
108 // generate the colours needed
109 generateDiscreteColours(usedDates.size() + 1);
114 * Find which date (in the currently selected timezone) the given timestamp falls on
115 * @param inTimestamp timestamp
116 * @return String containing description of date, or null
118 private String getDate(Timestamp inTimestamp)
120 if (inTimestamp == null || !inTimestamp.isValid()) {
123 Calendar cal = inTimestamp.getCalendar(null);
124 // use selected time zone, not system one
125 DEFAULT_DATE_FORMAT.setTimeZone(_selectedTimezone);
126 return DEFAULT_DATE_FORMAT.format(cal.getTime());