1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package de.jaret.util.ui.timebars.swing.renderer;
21
22 import java.awt.Graphics;
23 import java.awt.Rectangle;
24 import java.awt.event.MouseEvent;
25 import java.awt.geom.Rectangle2D;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import javax.swing.JComponent;
30
31 import de.jaret.util.date.Interval;
32 import de.jaret.util.date.JaretDate;
33 import de.jaret.util.date.holidayenumerator.HolidayEnumerator;
34 import de.jaret.util.date.iterator.DateIterator;
35 import de.jaret.util.date.iterator.DayIterator;
36 import de.jaret.util.date.iterator.HourIterator;
37 import de.jaret.util.date.iterator.MillisecondIterator;
38 import de.jaret.util.date.iterator.MinuteIterator;
39 import de.jaret.util.date.iterator.MonthIterator;
40 import de.jaret.util.date.iterator.SecondIterator;
41 import de.jaret.util.date.iterator.WeekIterator;
42 import de.jaret.util.date.iterator.YearIterator;
43 import de.jaret.util.swing.GraphicsHelper;
44 import de.jaret.util.ui.timebars.TimeBarViewerDelegate;
45 import de.jaret.util.ui.timebars.TimeBarViewerInterface;
46 import de.jaret.util.ui.timebars.model.PPSInterval;
47 import de.jaret.util.ui.timebars.strategy.ITickProvider;
48 import de.jaret.util.ui.timebars.swing.TimeBarViewer;
49
50
51
52
53
54
55
56 public class BoxTimeScaleRenderer implements TimeScaleRenderer, ITickProvider {
57
58 protected MyTimeScaleRenderer _renderer = new MyTimeScaleRenderer();
59
60
61 protected List<JaretDate> _majorTicks;
62
63 protected List<JaretDate> _minorTicks;
64
65
66
67
68 public JComponent getRendererComponent(TimeBarViewer tbv, boolean top) {
69 _renderer.setTimeBarViewer(tbv);
70 _renderer.setTop(top);
71 return _renderer;
72 }
73
74
75
76
77 public int getHeight() {
78 return _renderer.getPrefHeight();
79 }
80
81
82
83
84
85
86
87 @SuppressWarnings("serial")
88 class MyTimeScaleRenderer extends JComponent {
89
90 private static final int DEFAULT_NUMBER_OF_STRIPS = 3;
91
92
93 protected static final int BOXHEIGHT = 20;
94
95
96 protected static final int ADDITIONALGAP = 7;
97
98
99 protected static final int GAP = 3;
100
101
102 protected static final int SETBONUS = 5;
103
104
105 protected int _textHeight = -1;
106
107
108 protected int _numberOfStrips = DEFAULT_NUMBER_OF_STRIPS;
109
110
111 private double _lastPPS = -1;
112
113
114 protected HolidayEnumerator _holidayEnumerator;
115
116
117 protected List<DateIterator> _iterators;
118
119
120 protected List<DateIterator.Format> _formats;
121
122
123 protected List<Boolean> _enable;
124
125
126 private TimeBarViewer _tbv;
127
128 private TimeBarViewerDelegate _delegate;
129
130 boolean _top;
131
132
133
134
135 public MyTimeScaleRenderer() {
136 super();
137 initIterators();
138 }
139
140
141
142
143 private void initIterators() {
144 _iterators = new ArrayList<DateIterator>();
145 _formats = new ArrayList<DateIterator.Format>();
146 _enable = new ArrayList<Boolean>();
147
148 _iterators.add(new MillisecondIterator(100));
149 _formats.add(DateIterator.Format.LONG);
150 _enable.add(true);
151
152 _iterators.add(new MillisecondIterator(500));
153 _formats.add(DateIterator.Format.LONG);
154 _enable.add(true);
155
156 _iterators.add(new SecondIterator(1));
157 _formats.add(DateIterator.Format.LONG);
158 _enable.add(true);
159
160 _iterators.add(new SecondIterator(5));
161 _formats.add(DateIterator.Format.LONG);
162 _enable.add(true);
163
164 _iterators.add(new SecondIterator(30));
165 _formats.add(DateIterator.Format.LONG);
166 _enable.add(true);
167
168 _iterators.add(new MinuteIterator(1));
169 _formats.add(DateIterator.Format.LONG);
170 _enable.add(true);
171
172 _iterators.add(new MinuteIterator(10));
173 _formats.add(DateIterator.Format.LONG);
174 _enable.add(true);
175
176 _iterators.add(new MinuteIterator(30));
177 _formats.add(DateIterator.Format.LONG);
178 _enable.add(true);
179
180 _iterators.add(new HourIterator(3));
181 _formats.add(DateIterator.Format.LONG);
182 _enable.add(true);
183
184 _iterators.add(new HourIterator(12));
185 _formats.add(DateIterator.Format.LONG);
186 _enable.add(true);
187
188 _iterators.add(new DayIterator());
189 _formats.add(DateIterator.Format.LONG);
190 _enable.add(true);
191
192 _iterators.add(new WeekIterator());
193 _formats.add(DateIterator.Format.LONG);
194 _enable.add(true);
195
196 _iterators.add(new MonthIterator());
197 _formats.add(DateIterator.Format.LONG);
198 _enable.add(true);
199
200 _iterators.add(new YearIterator());
201 _formats.add(DateIterator.Format.LONG);
202 _enable.add(true);
203 }
204
205
206
207
208
209
210 public void setTimeBarViewer(TimeBarViewer tbv) {
211 _tbv = tbv;
212 _delegate = _tbv.getDelegate();
213 }
214
215
216
217
218
219
220 public void setTop(boolean top) {
221 _top = top;
222 }
223
224 private int xForDate(JaretDate date) {
225 int x = _tbv.xForDate(date);
226 x -= _tbv.getHierarchyWidth() + _tbv.getYAxisWidth();
227 return x;
228 }
229
230 private JaretDate dateForX(int x) {
231 return _tbv.dateForX(x + _tbv.getHierarchyWidth() + _tbv.getYAxisWidth());
232 }
233
234
235
236
237
238
239 public void setHolidayEnumerator(HolidayEnumerator he) {
240 _holidayEnumerator = he;
241 }
242
243
244
245
246 public void paintComponent(Graphics graphics) {
247
248 if (_lastPPS != _delegate.getPixelPerSecond()) {
249 checkStrips(graphics, _delegate, _delegate.getStartDate());
250 _lastPPS = _delegate.getPixelPerSecond();
251 }
252 if (_textHeight == -1) {
253 Rectangle2D rect = graphics.getFontMetrics().getStringBounds("Q", graphics);
254 _textHeight = (int) rect.getHeight();
255 }
256
257
258
259
260 _majorTicks = new ArrayList<JaretDate>();
261 _minorTicks = new ArrayList<JaretDate>();
262
263 if (!_delegate.hasVariableXScale()) {
264
265
266 drawStrips(graphics, _delegate, _top, _delegate.getStartDate().copy(), _delegate.getStartDate().copy()
267 .advanceSeconds(_delegate.getSecondsDisplayed()+1));
268 } else {
269
270 JaretDate startDate = _delegate.getStartDate().copy();
271 JaretDate endDate = _delegate.getStartDate().copy().advanceSeconds(_delegate.getSecondsDisplayed());
272 List<Interval> ppsIntervals = _delegate.getPpsRow().getIntervals(startDate, endDate);
273
274 if (ppsIntervals.size() == 0) {
275 drawStrips(graphics, _delegate, _top, _delegate.getStartDate().copy(), _delegate.getStartDate()
276 .copy().advanceSeconds(_delegate.getSecondsDisplayed()+1));
277 } else {
278 JaretDate d = startDate.copy();
279 while (d.compareTo(endDate) < 0) {
280
281 checkStrips(graphics, _delegate, d);
282 PPSInterval ppsInterval = _delegate.getPPSInterval(d);
283 JaretDate e;
284 if (ppsInterval != null) {
285 e = ppsInterval.getEnd();
286 } else {
287 PPSInterval nextInterval = _delegate.nextPPSInterval(d);
288 if (nextInterval != null) {
289 e = nextInterval.getBegin();
290 } else {
291 e = endDate;
292 }
293 }
294 drawStrips(graphics, _delegate, _top, d, e);
295 d = e;
296 }
297 _lastPPS = -1;
298 }
299 }
300 }
301
302
303
304
305
306
307
308
309
310
311 private void drawStrips(Graphics gc, TimeBarViewerDelegate delegate, boolean top, JaretDate startDate,
312 JaretDate endDate) {
313 boolean horizontal = delegate.getOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL);
314
315
316 Rectangle clipSave = gc.getClipBounds();
317
318 Rectangle drawingArea = getBounds();
319
320 if (horizontal) {
321
322 int sx = xForDate(startDate);
323 Rectangle destRect = new Rectangle(sx, drawingArea.y, xForDate(endDate) - sx, drawingArea.height);
324
325
326 int ox = drawingArea.x;
327 int basey = top ? drawingArea.y + drawingArea.height : drawingArea.y + BOXHEIGHT;
328
329 int drawn = 0;
330
331 for (int i = 0; i < _iterators.size() && drawn < _numberOfStrips; i++) {
332 DateIterator it = _iterators.get(i);
333 if (_enable.get(i)) {
334 drawn++;
335 it.reInitialize(startDate, endDate.copy().advanceMillis(it.getApproxStepMilliSeconds()));
336 while (it.hasNextDate()) {
337 JaretDate d = it.getNextDate();
338 String label = it.getLabel(d, _formats.get(i));
339
340
341 if (drawn==1) {
342 _minorTicks.add(d);
343 } else if(drawn==2) {
344 _majorTicks.add(d);
345 }
346
347 int x = xForDate(d);
348 gc.drawLine(x, basey, x, basey - BOXHEIGHT);
349 int yy = (BOXHEIGHT - _textHeight) / 2;
350 gc.drawString(label, x + GAP, basey - yy);
351 }
352 if (top) {
353 gc.drawLine(0, basey - BOXHEIGHT, drawingArea.width, basey - BOXHEIGHT);
354 } else {
355 gc.drawLine(0, basey, drawingArea.width, basey);
356 }
357 basey = basey + (top ? -BOXHEIGHT : BOXHEIGHT);
358 }
359 }
360 } else {
361
362
363 int sy = delegate.xForDate(startDate);
364 Rectangle destRect = new Rectangle(drawingArea.x, sy, drawingArea.width, delegate.xForDate(endDate)
365 - sy);
366 gc.setClip(destRect.intersection(clipSave));
367
368 int oy = drawingArea.y;
369 int basex = top ? drawingArea.x + drawingArea.width : drawingArea.x + BOXHEIGHT;
370
371 int drawn = 0;
372
373 for (int i = 0; i < _iterators.size() && drawn < _numberOfStrips; i++) {
374 DateIterator it = _iterators.get(i);
375 if (_enable.get(i)) {
376 drawn++;
377 it.reInitialize(startDate, endDate.copy().advanceMillis(it.getApproxStepMilliSeconds()));
378 while (it.hasNextDate()) {
379 JaretDate d = it.getNextDate();
380 String label = it.getLabel(d, _formats.get(i));
381
382
383 if (drawn==1) {
384 _minorTicks.add(d);
385 } else if(drawn==2) {
386 _majorTicks.add(d);
387 }
388
389 int y = xForDate(d);
390 gc.drawLine(basex, y, basex - BOXHEIGHT, y);
391 int xx = (BOXHEIGHT - _textHeight) / 2;
392 GraphicsHelper.drawStringVertical(gc, label, basex - xx - _textHeight, y + GAP);
393 }
394 if (top) {
395 gc.drawLine(basex - BOXHEIGHT, oy, basex - BOXHEIGHT, oy + drawingArea.height);
396 } else {
397 gc.drawLine(basex, oy, basex, oy + drawingArea.height);
398 }
399 basex = basex + (top ? -BOXHEIGHT : BOXHEIGHT);
400 }
401 }
402 }
403 gc.setClip(clipSave);
404 }
405
406
407
408
409
410
411
412
413 private void checkStrips(Graphics gc, TimeBarViewerDelegate delegate, JaretDate startDate) {
414 for (int i = 0; i < _iterators.size(); i++) {
415 DateIterator it = _iterators.get(i);
416 it.reInitialize(startDate, null);
417 if (it.previewNextDate() != null) {
418 JaretDate current = it.getNextDate();
419 JaretDate next = it.getNextDate();
420 int width = xForDate(next) - xForDate(current);
421 String label = it.getLabel(current, DateIterator.Format.LONG);
422 Rectangle2D rect = gc.getFontMetrics().getStringBounds(label, gc);
423 int bonus = _enable.get(i) && _formats.get(i).equals(DateIterator.Format.LONG) ? SETBONUS : 0;
424 if (width > rect.getWidth() + GAP + ADDITIONALGAP - bonus) {
425 _enable.set(i, true);
426 _formats.set(i, DateIterator.Format.LONG);
427 } else {
428 label = it.getLabel(current, DateIterator.Format.MEDIUM);
429 rect = gc.getFontMetrics().getStringBounds(label, gc);
430 bonus = _enable.get(i) && _formats.get(i).equals(DateIterator.Format.MEDIUM) ? SETBONUS : 0;
431 if (width > rect.getWidth() + GAP + ADDITIONALGAP - bonus) {
432 _enable.set(i, true);
433 _formats.set(i, DateIterator.Format.MEDIUM);
434 } else {
435 label = it.getLabel(current, DateIterator.Format.SHORT);
436 rect = gc.getFontMetrics().getStringBounds(label, gc);
437 bonus = _enable.get(i) && _formats.get(i).equals(DateIterator.Format.SHORT) ? SETBONUS : 0;
438 if (width > rect.getWidth() + GAP + ADDITIONALGAP - bonus) {
439 _enable.set(i, true);
440 _formats.set(i, DateIterator.Format.SHORT);
441 } else {
442 _enable.set(i, false);
443 }
444 }
445 }
446 } else {
447 _enable.set(i, false);
448 }
449 }
450 }
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469 public int getPrefHeight() {
470 return _numberOfStrips * BOXHEIGHT;
471 }
472
473
474
475
476
477
478 public int getNumberOfStrips() {
479 return _numberOfStrips;
480 }
481
482
483
484
485
486
487 public void setNumberOfStrips(int numberOfStrips) {
488 _numberOfStrips = numberOfStrips;
489 }
490
491
492
493
494 public String getToolTipText(MouseEvent event) {
495 if (_tbv.getTBOrientation() == TimeBarViewerInterface.Orientation.HORIZONTAL) {
496 JaretDate date = dateForX(event.getX());
497 return date.toDisplayString();
498 } else {
499 JaretDate date = dateForX(event.getY());
500 return date.toDisplayString();
501 }
502 }
503 }
504
505
506
507
508 public List<JaretDate> getMajorTicks(TimeBarViewerDelegate delegate) {
509 return _majorTicks;
510 }
511
512
513
514
515 public List<JaretDate> getMinorTicks(TimeBarViewerDelegate delegate) {
516 return _minorTicks;
517 }
518
519
520
521
522
523
524 public void setCorrectDST(boolean correctDST) {
525 for (DateIterator iterator : _renderer._iterators) {
526 iterator.setCorrectDST(correctDST);
527 }
528 }
529
530 }