1 /*****************************************************************************
2 * Copyright (c) 2007, 2008, 2010 Intel Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alvaro Sanchex-Leon - Udpated for TMF
13 * $Id: TimeScaleCtrl.java,v 1.5 2008/06/16 21:04:49 jkubasta Exp $
14 *****************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
;
18 import java
.text
.SimpleDateFormat
;
19 import java
.util
.Calendar
;
20 import java
.util
.Date
;
21 import java
.util
.GregorianCalendar
;
22 import java
.util
.TimeZone
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.Messages
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.Utils
.Resolution
;
26 import org
.eclipse
.swt
.SWT
;
27 import org
.eclipse
.swt
.events
.MouseEvent
;
28 import org
.eclipse
.swt
.events
.MouseListener
;
29 import org
.eclipse
.swt
.events
.MouseMoveListener
;
30 import org
.eclipse
.swt
.events
.PaintEvent
;
31 import org
.eclipse
.swt
.graphics
.GC
;
32 import org
.eclipse
.swt
.graphics
.Point
;
33 import org
.eclipse
.swt
.graphics
.Rectangle
;
34 import org
.eclipse
.swt
.widgets
.Composite
;
36 public class TimeScaleCtrl
extends TraceCtrl
implements MouseListener
,
39 public TimeScaleCtrl(Composite parent
, TraceColorScheme colors
) {
40 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.NO_FOCUS
41 | SWT
.DOUBLE_BUFFERED
);
42 addMouseListener(this);
43 addMouseMoveListener(this);
46 private static final long SEC_IN_NS
= 1000000000;
47 private static final long MIN_IN_NS
= 60 * SEC_IN_NS
;
48 private static final long HOUR_IN_NS
= 60 * MIN_IN_NS
;
49 private static final long DAY_IN_NS
= 24 * HOUR_IN_NS
;
50 private static final long MONTH_IN_NS
= 31 * DAY_IN_NS
; // upper limit
51 private static final long YEAR_IN_NS
= 366 * DAY_IN_NS
; // upper limit
53 private static final double LOG10_1
= Math
.log10(1);
54 private static final double LOG10_2
= Math
.log10(2);
55 private static final double LOG10_3
= Math
.log10(3);
56 private static final double LOG10_5
= Math
.log10(5);
58 private static final Calendar GREGORIAN_CALENDAR
= GregorianCalendar
.getInstance(TimeZone
.getTimeZone("GMT"));
60 private ITimeDataProvider _timeProvider
;
61 private int _dragState
= 0;
62 private int _dragX0
= 0;
63 private int _dragX
= 0;
64 private long _time0bak
;
65 private long _time1bak
;
66 private boolean _isInUpdate
;
67 private Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
70 public void setTimeProvider(ITimeDataProvider timeProvider
) {
71 _timeProvider
= timeProvider
;
74 private long _timeDelta
;
77 public Point
computeSize(int wHint
, int hHint
, boolean changed
) {
78 return super.computeSize(wHint
, _height
, changed
);
81 public void setHeight(int height
) {
82 this._height
= height
;
85 private void calcTimeDelta(int width
, double pixelsPerNanoSec
) {
86 double minDelta
= (double) ((pixelsPerNanoSec
== 0) ? YEAR_IN_NS
: width
/ pixelsPerNanoSec
);
88 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
89 if (minDelta
> 6 * MONTH_IN_NS
) {
91 } else if (minDelta
> 3 * MONTH_IN_NS
) {
92 unit
= 6 * MONTH_IN_NS
;
93 } else if (minDelta
> 10 * DAY_IN_NS
) {
95 } else if (minDelta
> 12 * HOUR_IN_NS
) {
97 } else if (minDelta
> 3 * HOUR_IN_NS
) {
98 unit
= 6 * HOUR_IN_NS
;
99 } else if (minDelta
> 30 * MIN_IN_NS
) {
101 } else if (minDelta
> 10 * MIN_IN_NS
) {
102 unit
= 15 * MIN_IN_NS
;
103 } else if (minDelta
> 30 * SEC_IN_NS
) {
105 } else if (minDelta
> 20 * SEC_IN_NS
) {
106 unit
= 30 * SEC_IN_NS
;
109 double log
= Math
.log10((double) minDelta
/ unit
);
110 long pow10
= (long) log
;
111 double remainder
= log
- pow10
;
112 if (remainder
< LOG10_1
) {
113 _timeDelta
= (long) Math
.pow(10, pow10
) * unit
;
114 } else if (remainder
< LOG10_2
) {
115 _timeDelta
= 2 * (long) Math
.pow(10, pow10
) * unit
;
116 } else if (remainder
< LOG10_3
&& unit
>= HOUR_IN_NS
&& unit
< YEAR_IN_NS
) {
117 _timeDelta
= 3 * (long) Math
.pow(10, pow10
) * unit
;
118 } else if (remainder
< LOG10_5
) {
119 _timeDelta
= 5 * (long) Math
.pow(10, pow10
) * unit
;
121 _timeDelta
= 10 * (long) Math
.pow(10, pow10
) * unit
;
125 private static TimeDraw TIMEDRAW_NANOSEC
= new TimeDrawNanosec();
126 private static TimeDraw TIMEDRAW_MICROSEC
= new TimeDrawMicrosec();
127 private static TimeDraw TIMEDRAW_MILLISEC
= new TimeDrawMillisec();
128 private static TimeDraw TIMEDRAW_SEC
= new TimeDrawSec();
129 private static TimeDraw TIMEDRAW_ABS_NANOSEC
= new TimeDrawAbsNanoSec();
130 private static TimeDraw TIMEDRAW_ABS_MICROSEC
= new TimeDrawAbsMicroSec();
131 private static TimeDraw TIMEDRAW_ABS_MILLISEC
= new TimeDrawAbsMillisec();
132 private static TimeDraw TIMEDRAW_ABS_SEC
= new TimeDrawAbsSec();
133 private static TimeDraw TIMEDRAW_ABS_MIN
= new TimeDrawAbsMin();
134 private static TimeDraw TIMEDRAW_ABS_HRS
= new TimeDrawAbsHrs();
135 private static TimeDraw TIMEDRAW_ABS_DAY
= new TimeDrawAbsDay();
136 private static TimeDraw TIMEDRAW_ABS_MONTH
= new TimeDrawAbsMonth();
137 private static TimeDraw TIMEDRAW_ABS_YEAR
= new TimeDrawAbsYear();
139 TimeDraw
getTimeDraw(long timeDelta
) {
141 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
142 if (timeDelta
>= YEAR_IN_NS
)
143 timeDraw
= TIMEDRAW_ABS_YEAR
;
144 else if (timeDelta
>= MONTH_IN_NS
)
145 timeDraw
= TIMEDRAW_ABS_MONTH
;
146 else if (timeDelta
>= DAY_IN_NS
)
147 timeDraw
= TIMEDRAW_ABS_DAY
;
148 else if (timeDelta
>= HOUR_IN_NS
)
149 timeDraw
= TIMEDRAW_ABS_HRS
;
150 else if (timeDelta
>= MIN_IN_NS
)
151 timeDraw
= TIMEDRAW_ABS_MIN
;
152 else if (timeDelta
>= SEC_IN_NS
)
153 timeDraw
= TIMEDRAW_ABS_SEC
;
154 else if (timeDelta
>= 1000000)
155 timeDraw
= TIMEDRAW_ABS_MILLISEC
;
156 else if (timeDelta
>= 1000)
157 timeDraw
= TIMEDRAW_ABS_MICROSEC
;
159 timeDraw
= TIMEDRAW_ABS_NANOSEC
;
162 if (timeDelta
>= 1000000000)
163 timeDraw
= TIMEDRAW_SEC
;
164 else if (timeDelta
>= 1000000)
165 timeDraw
= TIMEDRAW_MILLISEC
;
166 else if (timeDelta
>= 1000)
167 timeDraw
= TIMEDRAW_MICROSEC
;
169 timeDraw
= TIMEDRAW_NANOSEC
;
174 void paint(Rectangle rect
, PaintEvent e
) {
176 if (_isInUpdate
|| null == _timeProvider
)
180 gc
.fillRectangle(rect
);
182 if (null == _timeProvider
) {
186 long time0
= _timeProvider
.getTime0();
187 long time1
= _timeProvider
.getTime1();
188 long selectedTime
= _timeProvider
.getSelectedTime();
189 int leftSpace
= _timeProvider
.getNameSpace();
190 int timeSpace
= _timeProvider
.getTimeSpace();
192 gc
.setBackground(_colors
.getColor(TraceColorScheme
.TOOL_BACKGROUND
));
193 gc
.setForeground(_colors
.getColor(TraceColorScheme
.TOOL_FOREGROUND
));
194 Utils
.init(_rect0
, rect
);
196 // draw top left area
197 _rect0
.width
= leftSpace
;
200 if (_rect0
.width
> 0) {
201 Utils
.drawText(gc
, Messages
._Timescale
+ ":", _rect0
, true);
203 int messageWidth
= gc
.stringExtent(Messages
._Timescale
+ ":").x
+ 4;
204 Rectangle absHeaderRect
= new Rectangle(_rect0
.x
+ messageWidth
, _rect0
.y
, _rect0
.width
- messageWidth
, _rect0
.height
);
208 // prepare and draw right rect of the timescale
209 _rect0
.x
+= leftSpace
;
210 _rect0
.width
= rect
.width
- leftSpace
;
212 // draw bottom border and erase all other area
213 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.x
+ rect
.width
- 1,
214 rect
.y
+ rect
.height
- 1);
216 gc
.fillRectangle(_rect0
);
218 if (time1
<= time0
|| timeSpace
< 2) {
222 int numDigits
= calculateDigits(time0
, time1
);
224 int labelWidth
= gc
.getCharWidth('0') * numDigits
;
225 double pixelsPerNanoSec
= (timeSpace
<= RIGHT_MARGIN
) ?
0 :
226 (double) (timeSpace
- RIGHT_MARGIN
) / (time1
- time0
);
227 calcTimeDelta(labelWidth
, pixelsPerNanoSec
);
229 TimeDraw timeDraw
= getTimeDraw(_timeDelta
);
231 // draw zoom rectangle
232 if (3 == _dragState
&& null != _timeProvider
) {
233 if (_dragX0
< _dragX
) {
234 gc
.drawRectangle(leftSpace
+ _dragX0
, rect
.y
, _dragX
- _dragX0
- 1, rect
.height
- 8);
235 } else if (_dragX0
> _dragX
) {
236 gc
.drawRectangle(leftSpace
+ _dragX
, rect
.y
, _dragX0
- _dragX
- 1, rect
.height
- 8);
240 if (_rect0
.isEmpty())
243 // draw selected time
244 int x
= _rect0
.x
+ (int) ((double)(selectedTime
- time0
) * pixelsPerNanoSec
);
245 if (x
>= _rect0
.x
&& x
< _rect0
.x
+ _rect0
.width
) {
246 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
247 gc
.drawLine(x
, _rect0
.y
+ _rect0
.height
- 6, x
, _rect0
.y
250 .setForeground(_colors
251 .getColor(TraceColorScheme
.TOOL_FOREGROUND
));
254 // draw time scale ticks
256 _rect0
.height
= rect
.height
- 4;
257 _rect0
.width
= labelWidth
;
260 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
261 time
= floorToCalendar(time0
, _timeDelta
);
263 time
= (long) (Math
.ceil((double) time0
/ _timeDelta
) * _timeDelta
);
266 // long t = (long) (time * 1000000000);
267 int y
= _rect0
.y
+ _rect0
.height
;
269 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
270 timeDraw
.drawAbsHeader(gc
, time
, absHeaderRect
);
274 x
= rect
.x
+ leftSpace
+ (int) (Math
.floor((time
- time0
) * pixelsPerNanoSec
));
275 if (x
>= rect
.x
+ leftSpace
+ rect
.width
- _rect0
.width
) {
278 if (x
>= rect
.x
+ leftSpace
) {
279 gc
.drawLine(x
, y
, x
, y
+ 4);
281 if (x
+ _rect0
.width
<= rect
.x
+ rect
.width
)
282 timeDraw
.draw(gc
, time
, _rect0
);
284 if (pixelsPerNanoSec
== 0 || time
> Long
.MAX_VALUE
- _timeDelta
) {
288 if (_timeProvider
!= null && _timeProvider
.isCalendarFormat()) {
289 if (_timeDelta
>= YEAR_IN_NS
) {
290 GREGORIAN_CALENDAR
.setTime(new Date(time
/ 1000000));
291 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, 0); // January 1st of year
292 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1);
293 time
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
294 } else if (_timeDelta
>= MONTH_IN_NS
) {
295 GREGORIAN_CALENDAR
.setTime(new Date(time
/ 1000000));
296 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1); // 1st of month
297 time
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
303 private long floorToCalendar(long time
, long timeDelta
) {
304 if (_timeDelta
>= YEAR_IN_NS
) {
305 GREGORIAN_CALENDAR
.setTime(new Date(time
/ 1000000));
306 int year
= GREGORIAN_CALENDAR
.get(Calendar
.YEAR
);
307 int yearDelta
= (int) (timeDelta
/ YEAR_IN_NS
);
308 year
= (year
/ yearDelta
) * yearDelta
;
309 GREGORIAN_CALENDAR
.set(Calendar
.YEAR
, year
);
310 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, 0); // January 1st of year
311 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1);
312 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
313 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
314 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
315 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
316 time
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
317 } else if (_timeDelta
>= MONTH_IN_NS
) {
318 GREGORIAN_CALENDAR
.setTime(new Date(time
/ 1000000));
319 int month
= GREGORIAN_CALENDAR
.get(Calendar
.MONTH
);
320 int monthDelta
= (int) (timeDelta
/ MONTH_IN_NS
);
321 month
= (month
/ monthDelta
) * monthDelta
;
322 GREGORIAN_CALENDAR
.set(Calendar
.MONTH
, month
);
323 GREGORIAN_CALENDAR
.set(Calendar
.DAY_OF_MONTH
, 1); // 1st of month
324 GREGORIAN_CALENDAR
.set(Calendar
.HOUR_OF_DAY
, 0);
325 GREGORIAN_CALENDAR
.set(Calendar
.MINUTE
, 0);
326 GREGORIAN_CALENDAR
.set(Calendar
.SECOND
, 0);
327 GREGORIAN_CALENDAR
.set(Calendar
.MILLISECOND
, 0);
328 time
= GREGORIAN_CALENDAR
.getTimeInMillis() * 1000000;
330 time
= (time
/ timeDelta
) * timeDelta
;
335 private int calculateDigits(long time0
, long time1
) {
337 long timeRange
= time1
- time0
;
339 if (_timeProvider
.isCalendarFormat()) {
340 // Calculate the number of digits to represent the minutes provided
344 if (timeRange
< 10000) {
345 // HH:11:222:333:444__
347 } else if (timeRange
< 10000000) {
352 // Calculate the number of digits to represent the minutes provided
353 long min
= (long) ((time1
* 1E-9) / 60); // to sec then to minutes
354 String strMinutes
= String
.valueOf(min
);
356 if (strMinutes
!= null) {
357 numDigits
+= strMinutes
.length();
361 if (timeRange
< 10000) {
364 } else if (timeRange
< 10000000) {
370 // Trace.debug("timeRange: " + timeRange + " numDigits: " + numDigits);
375 public void mouseDown(MouseEvent e
) {
376 if (_dragState
== 0 && null != _timeProvider
) {
380 } else if (3 == e
.button
) {
383 int x
= e
.x
- _timeProvider
.getNameSpace();
386 } else if (x
> getSize().x
- _timeProvider
.getNameSpace()) {
387 x
= getSize().x
- _timeProvider
.getNameSpace();
389 _dragX
= _dragX0
= x
;
390 _time0bak
= _timeProvider
.getTime0();
391 _time1bak
= _timeProvider
.getTime1();
396 public void mouseUp(MouseEvent e
) {
397 if (e
.button
== 1 && _dragState
== 1) {
401 // Notify time provider to check the need for listener notification
402 if (_dragX
!= _dragX0
) {
403 _timeProvider
.setStartFinishTimeNotify(_timeProvider
.getTime0(), _timeProvider
.getTime1());
405 } else if (e
.button
== 3 && _dragState
== 3 && null != _timeProvider
) {
407 if (_dragX0
== _dragX
) {
410 int timeSpace
= _timeProvider
.getTimeSpace();
411 int leftSpace
= _timeProvider
.getNameSpace();
412 int x
= e
.x
- leftSpace
;
415 if (_dragX0
> _dragX
) { // drag right to left
419 long time0
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ timeSpace
));
420 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX
/ timeSpace
));
422 _timeProvider
.setStartFinishTimeNotify(time0
, time1
);
423 _time0bak
= _timeProvider
.getTime0();
424 _time1bak
= _timeProvider
.getTime1();
430 public void mouseMove(MouseEvent e
) {
431 if (_dragX0
< 0 || _dragState
== 0) {
434 Point size
= getSize();
435 int leftSpace
= _timeProvider
.getNameSpace();
436 int timeSpace
= _timeProvider
.getTimeSpace();
437 int x
= e
.x
- leftSpace
;
438 if (1 == _dragState
&& null != _timeProvider
) {
439 if (x
> 0 && size
.x
> leftSpace
&& _dragX
!= x
) {
441 long time1
= _time0bak
+ (long) ((_time1bak
- _time0bak
) * ((double) _dragX0
/ _dragX
));
442 _timeProvider
.setStartFinishTime(_time0bak
, time1
);
444 } else if (3 == _dragState
&& null != _timeProvider
) {
447 } else if (x
> timeSpace
) {
457 public void mouseDoubleClick(MouseEvent e
) {
458 if (null != _timeProvider
) {
459 _timeProvider
.resetStartFinishTime();
460 _time0bak
= _timeProvider
.getTime0();
461 _time1bak
= _timeProvider
.getTime1();
466 abstract class TimeDraw
{
467 static String S
= ":";
468 static String S0
= ":0";
469 static String S00
= ":00";
470 protected static final SimpleDateFormat stimeformat
= new SimpleDateFormat("HH:mm:ss");
471 protected static final SimpleDateFormat stimeformatheader
= new SimpleDateFormat("yyyy MMM dd");
472 protected static final SimpleDateFormat sminformat
= new SimpleDateFormat("HH:mm");
473 protected static final SimpleDateFormat sminformatheader
= new SimpleDateFormat("yyyy MMM dd");
474 protected static final SimpleDateFormat shrsformat
= new SimpleDateFormat("MMM dd HH:mm");
475 protected static final SimpleDateFormat shrsformatheader
= new SimpleDateFormat("yyyy");
476 protected static final SimpleDateFormat sdayformat
= new SimpleDateFormat("MMM dd");
477 protected static final SimpleDateFormat sdayformatheader
= new SimpleDateFormat("yyyy");
478 protected static final SimpleDateFormat smonthformat
= new SimpleDateFormat("yyyy MMM");
479 protected static final SimpleDateFormat syearformat
= new SimpleDateFormat("yyyy");
481 stimeformat
.setTimeZone(TimeZone
.getTimeZone("GMT"));
482 stimeformatheader
.setTimeZone(TimeZone
.getTimeZone("GMT"));
483 sminformat
.setTimeZone(TimeZone
.getTimeZone("GMT"));
484 sminformatheader
.setTimeZone(TimeZone
.getTimeZone("GMT"));
485 shrsformat
.setTimeZone(TimeZone
.getTimeZone("GMT"));
486 shrsformatheader
.setTimeZone(TimeZone
.getTimeZone("GMT"));
487 sdayformat
.setTimeZone(TimeZone
.getTimeZone("GMT"));
488 sdayformatheader
.setTimeZone(TimeZone
.getTimeZone("GMT"));
489 smonthformat
.setTimeZone(TimeZone
.getTimeZone("GMT"));
490 syearformat
.setTimeZone(TimeZone
.getTimeZone("GMT"));
493 static String
pad(long n
) {
502 public abstract void draw(GC gc
, long time
, Rectangle rect
);
504 public void drawAbsHeader(GC gc
, long time
, Rectangle absHeaderRect
) {
505 // Override to draw absolute time header
506 // This is for the time information not shown in the draw of each tick
509 public abstract String
hint();
512 class TimeDrawSec
extends TimeDraw
{
513 static String _hint
= "sec";
516 public void draw(GC gc
, long time
, Rectangle rect
) {
518 Utils
.drawText(gc
, time
+ "", rect
, true);
522 public String
hint() {
527 class TimeDrawMillisec
extends TimeDraw
{
528 static String _hint
= "s:ms";
531 public void draw(GC gc
, long time
, Rectangle rect
) {
533 long ms
= time
% 1000;
535 Utils
.drawText(gc
, time
+ pad(ms
), rect
, true);
539 public String
hint() {
544 class TimeDrawMicrosec
extends TimeDraw
{
545 static String _hint
= "s:ms:mcs";
548 public void draw(GC gc
, long time
, Rectangle rect
) {
550 long mcs
= time
% 1000;
552 long ms
= time
% 1000;
554 Utils
.drawText(gc
, time
+ pad(ms
) + pad(mcs
), rect
, true);
558 public String
hint() {
563 class TimeDrawNanosec
extends TimeDraw
{
564 static String _hint
= "s:ms:mcs:ns";
567 public void draw(GC gc
, long time
, Rectangle rect
) {
568 long ns
= time
% 1000;
570 long mcs
= time
% 1000;
572 long ms
= time
% 1000;
574 Utils
.drawText(gc
, time
+ pad(ms
) + pad(mcs
) + pad(ns
), rect
, true);
578 public String
hint() {
583 class TimeDrawAbsYear
extends TimeDraw
{
584 static String _hint
= "YYYY";
587 public void draw(GC gc
, long time
, Rectangle rect
) {
588 String stime
= syearformat
.format(new Date((long) (time
/ 1000000)));
589 Utils
.drawText(gc
, stime
, rect
, true);
593 public String
hint() {
598 class TimeDrawAbsMonth
extends TimeDraw
{
599 static String _hint
= "YYYY Mmm";
602 public void draw(GC gc
, long time
, Rectangle rect
) {
603 String stime
= smonthformat
.format(new Date((long) (time
/ 1000000)));
604 Utils
.drawText(gc
, stime
, rect
, true);
608 public String
hint() {
613 class TimeDrawAbsDay
extends TimeDraw
{
614 static String _hint
= "Mmm dd";
617 public void draw(GC gc
, long time
, Rectangle rect
) {
618 String stime
= sdayformat
.format(new Date((long) (time
/ 1000000)));
619 Utils
.drawText(gc
, stime
, rect
, true);
623 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
624 String header
= sdayformatheader
.format(new Date((long) (time
/ 1000000)));
625 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
626 if (headerwidth
<= rect
.width
) {
627 rect
.x
+= (rect
.width
- headerwidth
);
628 Utils
.drawText(gc
, header
, rect
, true);
633 public String
hint() {
638 class TimeDrawAbsHrs
extends TimeDraw
{
639 static String _hint
= "Mmm dd HH:mm";
642 public void draw(GC gc
, long time
, Rectangle rect
) {
643 String stime
= shrsformat
.format(new Date((long) (time
/ 1000000)));
644 Utils
.drawText(gc
, stime
, rect
, true);
648 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
649 String header
= shrsformatheader
.format(new Date((long) (time
/ 1000000)));
650 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
651 if (headerwidth
<= rect
.width
) {
652 rect
.x
+= (rect
.width
- headerwidth
);
653 Utils
.drawText(gc
, header
, rect
, true);
658 public String
hint() {
663 class TimeDrawAbsMin
extends TimeDraw
{
664 static String _hint
= "HH:mm";
667 public void draw(GC gc
, long time
, Rectangle rect
) {
668 String stime
= sminformat
.format(new Date((long) (time
/ 1000000)));
669 Utils
.drawText(gc
, stime
, rect
, true);
673 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
674 String header
= sminformatheader
.format(new Date((long) (time
/ 1000000)));
675 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
676 if (headerwidth
<= rect
.width
) {
677 rect
.x
+= (rect
.width
- headerwidth
);
678 Utils
.drawText(gc
, header
, rect
, true);
684 public String
hint() {
689 class TimeDrawAbsSec
extends TimeDraw
{
690 static String _hint
= "HH:mm:ss";
693 public void draw(GC gc
, long time
, Rectangle rect
) {
694 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
695 Utils
.drawText(gc
, stime
, rect
, true);
699 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
700 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
701 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
702 if (headerwidth
<= rect
.width
) {
703 rect
.x
+= (rect
.width
- headerwidth
);
704 Utils
.drawText(gc
, header
, rect
, true);
709 public String
hint() {
714 class TimeDrawAbsMillisec
extends TimeDraw
{
715 static String _hint
= "HH:ss:ms";
718 public void draw(GC gc
, long time
, Rectangle rect
) {
719 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
720 String ns
= Utils
.formatNs(time
, Resolution
.MILLISEC
);
722 Utils
.drawText(gc
, stime
+ " " + ns
, rect
, true);
726 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
727 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
728 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
729 if (headerwidth
<= rect
.width
) {
730 rect
.x
+= (rect
.width
- headerwidth
);
731 Utils
.drawText(gc
, header
, rect
, true);
736 public String
hint() {
741 class TimeDrawAbsMicroSec
extends TimeDraw
{
742 static String _hint
= "HH:ss:ms:mcs";
745 public void draw(GC gc
, long time
, Rectangle rect
) {
746 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
747 String micr
= Utils
.formatNs(time
, Resolution
.MICROSEC
);
748 Utils
.drawText(gc
, stime
+ " " + micr
, rect
, true);
752 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
753 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
754 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
755 if (headerwidth
<= rect
.width
) {
756 rect
.x
+= (rect
.width
- headerwidth
);
757 Utils
.drawText(gc
, header
, rect
, true);
762 public String
hint() {
767 class TimeDrawAbsNanoSec
extends TimeDraw
{
768 static String _hint
= "HH:ss:ms:mcs:ns";
771 public void draw(GC gc
, long time
, Rectangle rect
) {
772 String stime
= stimeformat
.format(new Date((long) (time
/ 1000000)));
773 String ns
= Utils
.formatNs(time
, Resolution
.NANOSEC
);
774 Utils
.drawText(gc
, stime
+ " " + ns
, rect
, true);
778 public void drawAbsHeader(GC gc
, long time
, Rectangle rect
) {
779 String header
= stimeformatheader
.format(new Date((long) (time
/ 1000000)));
780 int headerwidth
= gc
.stringExtent(header
).x
+ 4;
781 if (headerwidth
<= rect
.width
) {
782 rect
.x
+= (rect
.width
- headerwidth
);
783 Utils
.drawText(gc
, header
, rect
, true);
788 public String
hint() {