View Javadoc

1   /*
2    *  File: EventMonitoringExample.java 
3    *  Copyright (c) 2004-2007  Peter Kliem (Peter.Kliem@jaret.de)
4    *  A commercial license is available, see http://www.jaret.de.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation; either version 2 of the License, or
9    *  (at your option) any later version.
10   *
11   *  This program is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   *  GNU General Public License for more details.
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package de.jaret.examples.timebars.eventmonitoring.swing;
21  
22  import java.awt.BorderLayout;
23  import java.awt.Component;
24  import java.awt.Point;
25  import java.awt.datatransfer.StringSelection;
26  import java.awt.dnd.DnDConstants;
27  import java.awt.dnd.DragGestureEvent;
28  import java.awt.dnd.DragGestureListener;
29  import java.awt.dnd.DragGestureRecognizer;
30  import java.awt.dnd.DragSource;
31  import java.awt.event.ActionEvent;
32  import java.awt.event.ActionListener;
33  import java.awt.event.MouseAdapter;
34  import java.awt.event.MouseEvent;
35  import java.util.List;
36  
37  import javax.swing.AbstractAction;
38  import javax.swing.Action;
39  import javax.swing.JFrame;
40  import javax.swing.JPopupMenu;
41  import javax.swing.Timer;
42  
43  import de.jaret.examples.timebars.eventmonitoring.model.CollectingTimeBarNode;
44  import de.jaret.examples.timebars.eventmonitoring.model.EventInterval;
45  import de.jaret.examples.timebars.eventmonitoring.model.EventTimeBarRow;
46  import de.jaret.examples.timebars.eventmonitoring.model.ModelCreator;
47  import de.jaret.examples.timebars.eventmonitoring.swing.renderer.EventMonitorHeaderRenderer;
48  import de.jaret.examples.timebars.eventmonitoring.swing.renderer.EventRenderer;
49  import de.jaret.util.date.Interval;
50  import de.jaret.util.date.JaretDate;
51  import de.jaret.util.ui.timebars.TimeBarMarker;
52  import de.jaret.util.ui.timebars.TimeBarMarkerImpl;
53  import de.jaret.util.ui.timebars.TimeBarViewerDelegate;
54  import de.jaret.util.ui.timebars.model.HierarchicalTimeBarModel;
55  import de.jaret.util.ui.timebars.model.HierarchicalViewStateListener;
56  import de.jaret.util.ui.timebars.model.ISelectionRectListener;
57  import de.jaret.util.ui.timebars.model.ITimeBarChangeListener;
58  import de.jaret.util.ui.timebars.model.ITimeBarViewState;
59  import de.jaret.util.ui.timebars.model.TBRect;
60  import de.jaret.util.ui.timebars.model.TimeBarModel;
61  import de.jaret.util.ui.timebars.model.TimeBarNode;
62  import de.jaret.util.ui.timebars.model.TimeBarRow;
63  import de.jaret.util.ui.timebars.strategy.IIntervalSelectionStrategy;
64  import de.jaret.util.ui.timebars.swing.TimeBarViewer;
65  import de.jaret.util.ui.timebars.swing.renderer.DefaultHierarchyRenderer;
66  import de.jaret.util.ui.timebars.swing.renderer.DefaultTitleRenderer;
67  
68  /***
69   * Example showing events (non modificable).
70   * 
71   * @author Peter Kliem
72   * @version $Id: EventMonitoringExample.java 1073 2010-11-22 21:25:33Z kliem $
73   */
74  public class EventMonitoringExample {
75      TimeBarViewer _tbv;
76      TimeBarMarkerImpl _tm;
77      
78      private final static boolean HIERARCHICAL = false;
79  
80      public static void main(String[] args) {
81          EventMonitoringExample example = new EventMonitoringExample();
82          example.run();
83      }
84  
85      public EventMonitoringExample() {
86      }
87  
88      public void run() {
89          JFrame f = new JFrame(EventMonitoringExample.class.getName());
90          f.setSize(1400, 600);
91          f.getContentPane().setLayout(new BorderLayout());
92          f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
93  
94          HierarchicalTimeBarModel hierarchicalModel = ModelCreator.createHierarchicalModel();
95          TimeBarModel flatModel = ModelCreator.createFlatModel();
96  
97          _tbv = new TimeBarViewer();
98          
99          
100         if (HIERARCHICAL) {
101             _tbv.setModel(hierarchicalModel);
102             _tbv.setHierarchyRenderer(new DefaultHierarchyRenderer());
103             _tbv.setHierarchyWidth(100);
104                  } else {
105             _tbv.setModel(flatModel);
106             _tbv.setHierarchyWidth(0);
107         }
108         _tbv.setTimeScalePosition(TimeBarViewer.TIMESCALE_POSITION_TOP);
109         _tbv.setYAxisWidth(100);
110         f.getContentPane().add(_tbv, BorderLayout.CENTER);
111 
112         // allow marker grabbing in the diagram area
113         _tbv.setMarkerDraggingInDiagramArea(true);
114 
115         // enable region selection
116         _tbv.setRegionRectEnable(true);
117         
118         // draw row grid
119         _tbv.setDrawRowGrid(true);
120         
121         // setup header renderer
122         _tbv.setHeaderRenderer(new EventMonitorHeaderRenderer());
123         
124         
125         // set a name for the viewer and setup the default title renderer
126         _tbv.setName("Monitor");
127         _tbv.setTitleRenderer(new DefaultTitleRenderer());
128         
129         
130         // selection strategy: shortest first
131         _tbv.getDelegate().setIntervalSelectionStrategy(new IIntervalSelectionStrategy() {
132             public Interval selectInterval(List<Interval> intervals) {
133                 Interval result = null; 
134                 for (Interval interval : intervals) {
135                     if (result == null || interval.getSeconds()<result.getSeconds()) {
136                         result = interval;
137                     }
138                 }
139                 return result;
140             }
141         });
142         
143         
144         if (HIERARCHICAL) {
145             // set the overlap drawing property for the nodes on the second level
146             for (TimeBarNode node : hierarchicalModel.getRootNode().getChildren()) {
147                 _tbv.getTimeBarViewState().setDrawOverlapping(node, true);
148             }
149 
150             // add a listener that toggles the collect childIntervals property of expanded/collapsed nodes
151             _tbv.getHierarchicalViewState().addHierarchicalViewstateListener(new HierarchicalViewStateListener() {
152                 public void nodeExpanded(TimeBarNode node) {
153                     if (node instanceof CollectingTimeBarNode) {
154                         CollectingTimeBarNode ctbn = (CollectingTimeBarNode) node;
155                         ctbn.setCollectChildIntervals(false);
156                     }
157                 }
158 
159                 public void nodeFolded(TimeBarNode node) {
160                     if (node instanceof CollectingTimeBarNode) {
161                         CollectingTimeBarNode ctbn = (CollectingTimeBarNode) node;
162                         ctbn.setCollectChildIntervals(true);
163                     }
164                 }
165             });
166         } else {
167             // in general draw overlapping
168             _tbv.setDrawOverlapping(true);
169             
170             // allow different row heights
171             _tbv.getTimeBarViewState().setUseVariableRowHeights(true);
172             
173             // add a double click listener for checking on the header
174             _tbv.addMouseListener(new MouseAdapter() {
175 
176                 public void mouseClicked(MouseEvent e) {
177                     if (e.getClickCount() == 2) {
178                         Point origin = e.getPoint();
179                         if (_tbv.getDelegate().getYAxisRect().contains(origin)) {
180                             TimeBarRow row = _tbv.getRowForXY(origin.x, origin.y);
181                             if (row != null) {
182                                 if (row instanceof EventTimeBarRow) {
183                                     EventTimeBarRow erow = (EventTimeBarRow) row;
184                                     if (!erow.isExpanded()) {
185                                         // expand
186                                         _tbv.getTimeBarViewState().setDrawOverlapping(row, false);
187                                         _tbv.getTimeBarViewState().setRowHeight(row, calculateRowHeight(_tbv.getDelegate(), _tbv.getTimeBarViewState(), row));
188                                         erow.setExpanded(true);
189                                     } else {
190                                         // fold
191                                         _tbv.getTimeBarViewState().setDrawOverlapping(row, true);
192                                         _tbv.getTimeBarViewState().setRowHeight(row, _tbv.getTimeBarViewState().getDefaultRowHeight());
193                                         erow.setExpanded(false);
194                                         }
195                                 }
196                             }
197                         }
198                     }
199                 }
200 
201                 /***
202                  * Calculate the optimal row height
203                  * @param delegate
204                  * @param timeBarViewState
205                  * @param row
206                  * @return
207                  */
208                 public int calculateRowHeight(TimeBarViewerDelegate delegate,
209                         ITimeBarViewState timeBarViewState, TimeBarRow row) {
210                     int maxOverlap = timeBarViewState.getDefaultRowHeight();
211                     int height = delegate.getMaxOverlapCount(row) * maxOverlap;
212                     return height;
213                 }
214 
215                 
216                 
217             });
218             
219             
220         }
221         
222         // change listener
223         _tbv.addTimeBarChangeListener(new ITimeBarChangeListener() {
224 
225             public void intervalChangeCancelled(TimeBarRow row, Interval interval) {
226                 System.out.println("CHANGE CANCELLED " + row + " " + interval);
227             }
228 
229             public void intervalChangeStarted(TimeBarRow row, Interval interval) {
230                 System.out.println("CHANGE STARTED " + row + " " + interval);
231             }
232 
233             public void intervalChanged(TimeBarRow row, Interval interval, JaretDate oldBegin, JaretDate oldEnd) {
234                 System.out.println("CHANGE DONE " + row + " " + interval);
235             }
236 
237             public void intervalIntermediateChange(TimeBarRow row, Interval interval, JaretDate oldBegin,
238                     JaretDate oldEnd) {
239                 System.out.println("CHANGE INTERMEDIATE " + row + " " + interval);
240             }
241 
242             public void markerDragStarted(TimeBarMarker marker) {
243                 System.out.println("Marker drag started "+marker);
244             }
245 
246             public void markerDragStopped(TimeBarMarker marker) {
247                 System.out.println("Marker drag stopped "+marker);
248             }
249 
250         });
251 
252         
253         
254 // sample property listener        
255 //        _tbv.addPropertyChangeListener(_tbv.PROPERTYNAME_STARTDATE, new PropertyChangeListener(){
256 //
257 //            @Override
258 //            public void propertyChange(PropertyChangeEvent evt) {
259 //                System.out.println("Start changed to "+evt.getNewValue());
260 //            }
261 //            
262 //        });
263         
264         // Do not allow any modifications - do not add an interval modificator!
265         // _tbv.addIntervalModificator(new DefaultIntervalModificator());
266 
267         // do not allow row selections
268         _tbv.getSelectionModel().setRowSelectionAllowed(false);
269 
270         // register additional renderer
271         _tbv.registerTimeBarRenderer(EventInterval.class, new EventRenderer());
272 
273         // add a marker
274         _tm = new TimeBarMarkerImpl(true, _tbv.getModel().getMinDate().copy().advanceHours(3));
275         _tm.setDescription("Timebarmarker");
276         _tbv.addMarker(_tm);
277 
278         // do not show the root node
279         _tbv.setHideRoot(true);
280 
281         // add a popup menu for EventIntervals
282         Action action = new AbstractAction("IntervalAction") {
283             public void actionPerformed(ActionEvent e) {
284                 System.out.println("run " + getValue(NAME));
285             }
286         };
287         JPopupMenu pop = new JPopupMenu("Operations");
288         pop.add(action);
289         _tbv.registerPopupMenu(EventInterval.class, pop);
290 
291         // add a popup menu for the body
292         final Action bodyaction = new AbstractAction("BodyAction") {
293             public void actionPerformed(ActionEvent e) {
294                 System.out.println("run " + getValue(NAME));
295             }
296         };
297         pop = new JPopupMenu("Operations");
298         pop.add(bodyaction);
299         pop.add(new RunMarkerAction(_tbv));
300         
301         // add the zoom action
302         pop.add(new ZoomAction(_tbv));
303         // add the rem selection action
304         pop.add(new ResetRegionSelectionAction(_tbv));
305         
306         _tbv.setBodyContextMenu(pop);
307 
308         // sample: check enablement of action in a popup
309 //        pop.addPopupMenuListener(new PopupMenuListener() {
310 //            
311 //            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
312 //                System.out.println(_tbv.getPopUpInformation().getLeft());
313 //                System.out.println(_tbv.getPopUpInformation().getRight().toDisplayString());
314 //                if (_tbv.getPopUpInformation().getRight().getHours()>9) {
315 //                    bodyaction.setEnabled(false);
316 //                } else {
317 //                    bodyaction.setEnabled(true);
318 //                }
319 //            }
320 //            
321 //            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
322 //                // TODO Auto-generated method stub
323 //                
324 //            }
325 //            
326 //            public void popupMenuCanceled(PopupMenuEvent e) {
327 //                // TODO Auto-generated method stub
328 //                
329 //            }
330 //        });
331         
332         
333         
334         // add a popup menu for the hierarchy
335         action = new AbstractAction("HierarchyAction") {
336             public void actionPerformed(ActionEvent e) {
337                 System.out.println("run " + getValue(NAME));
338             }
339         };
340         pop = new JPopupMenu("Operations");
341         pop.add(action);
342         _tbv.setHierarchyContextMenu(pop);
343 
344         // add a popup menu for the header
345         action = new AbstractAction("HeaderAction") {
346             public void actionPerformed(ActionEvent e) {
347                 System.out.println("run " + getValue(NAME));
348             }
349         };
350         pop = new JPopupMenu("Operations");
351         pop.add(action);
352         _tbv.setHeaderContextMenu(pop);
353 
354         // add a popup menu for the time scale
355         action = new AbstractAction("TimeScaleAction") {
356             public void actionPerformed(ActionEvent e) {
357                 System.out.println("run " + getValue(NAME));
358             }
359         };
360         pop = new JPopupMenu("Operations");
361         pop.add(action);
362         _tbv.setTimeScaleContextMenu(pop);
363 
364         // add a popup menu for the title area
365         action = new AbstractAction("TitleAction") {
366             public void actionPerformed(ActionEvent e) {
367                 System.out.println("run " + getValue(NAME));
368             }
369         };
370         pop = new JPopupMenu("Operations");
371         pop.add(action);
372         _tbv.setTitleContextMenu(pop);
373 
374         // add dnd support
375         DragSource dragSource = DragSource.getDefaultDragSource();
376         DragGestureListener dgl = new TimeBarViewerDragGestureListener();
377         DragGestureRecognizer dgr = dragSource.createDefaultDragGestureRecognizer(_tbv._diagram,
378                 DnDConstants.ACTION_COPY, dgl);
379 
380         // add the control panel
381         EventMonitoringControlPanel cp = new EventMonitoringControlPanel(_tbv, _tm, 100); // TODO
382         f.getContentPane().add(cp, BorderLayout.SOUTH);
383 
384         
385         
386         // make sure the marker is in a certain area when zooming
387         // relative display range the marker should be in after zooming
388         final double min = 0.3;
389         final double max = 0.7;
390         
391 //      _tbv.addPropertyChangeListener(_tbv.PROPERTYNAME_PIXELPERSECOND, new PropertyChangeListener(){
392 //                    public void propertyChange(PropertyChangeEvent evt) {
393 //                        // if not displayed set the viewer to display the marker at the min position
394 //                        if (!isInRange(_tm.getDate(), min, max)) {
395 //                            int secondsDisplayed = _tbv.getSecondsDisplayed();
396 //                            JaretDate startDate = _tm.getDate().copy().advanceSeconds(-min*secondsDisplayed);
397 //     //                       _tbv.setStartDate(startDate);
398 //                        }
399 //                    }
400 //                    
401 //                });
402         
403         
404         
405         
406         // go!
407         f.setVisible(true);
408     }
409 
410     public void setEndDate(TimeBarViewer tbv, JaretDate endDate) {
411         int secondsDisplayed = tbv.getSecondsDisplayed();
412         JaretDate startDate = endDate.copy().advanceSeconds(-secondsDisplayed);
413         tbv.setStartDate(startDate);
414     }
415 
416     
417     boolean isInRange(JaretDate date, double min, double max) {
418         int secondsDisplayed = _tbv.getSecondsDisplayed();
419         JaretDate minDate = _tbv.getStartDate().copy().advanceSeconds(min*secondsDisplayed);
420         JaretDate maxDate = _tbv.getStartDate().copy().advanceSeconds(max*secondsDisplayed);
421         return minDate.compareTo(date)>0 && maxDate.compareTo(date)<0;
422     }
423     
424     class TimeBarViewerDragGestureListener implements DragGestureListener {
425         public void dragGestureRecognized(DragGestureEvent e) {
426             Component c = e.getComponent();
427             System.out.println("component " + c);
428             System.out.println(e.getDragOrigin());
429 
430             boolean markerDragging = _tbv.getDelegate().isMarkerDraggingInProgress();
431             if (markerDragging) {
432                 return;
433             }
434 
435             List<Interval> intervals = _tbv.getDelegate().getIntervalsAt(e.getDragOrigin().x, e.getDragOrigin().y);
436             if (intervals.size() > 0) {
437                 Interval interval = intervals.get(0);
438                 e.startDrag(null, new StringSelection("Drag " + ((EventInterval) interval).getTitle()));
439                 return;
440             }
441             Point origin = e.getDragOrigin();
442             if (_tbv.getDelegate().getYAxisRect().contains(origin)) {
443                 TimeBarRow row = _tbv.getRowForXY(origin.x, origin.y);
444                 if (row != null) {
445                     e.startDrag(null, new StringSelection("Drag ROW " + row));
446                 }
447             }
448 
449         }
450     }
451     
452     
453     
454     /***
455      * Simple zoom action.
456      * @author kliem
457      * @version $Id: EventMonitoringExample.java 1073 2010-11-22 21:25:33Z kliem $
458      */
459     class ZoomAction extends AbstractAction implements ISelectionRectListener{
460         TimeBarViewer _tbv;
461         public ZoomAction(TimeBarViewer tbv) {
462             super("Zoom to selection");
463             _tbv = tbv;
464             setEnabled(false);
465             _tbv.addSelectionRectListener(this);
466         }
467         
468         
469         public void actionPerformed(ActionEvent e) {
470             if (_tbv.getRegionRect() != null) {
471                 TBRect tbrect = _tbv.getRegionRect();
472                 JaretDate startDate = tbrect.startDate;
473                 int seconds = tbrect.endDate.diffSeconds(tbrect.startDate);
474                 int pixel = _tbv.getDelegate().getDiagramRect().width;
475                 double pps = ((double) pixel) /((double)seconds);
476                 _tbv.clearRegionRect();
477                 _tbv.setPixelPerSecond(pps);
478                 _tbv.setStartDate(startDate);
479                 // TODO row scaling
480             }
481         }
482 
483 
484         public void regionRectChanged(TimeBarViewerDelegate delegate, TBRect tbrect) {
485             setEnabled(true);
486         }
487 
488 
489         public void regionRectClosed(TimeBarViewerDelegate delegate) {
490             setEnabled(false);
491         }
492 
493 
494         public void selectionRectChanged(TimeBarViewerDelegate delegate, JaretDate beginDate, JaretDate endDate,
495                 List<TimeBarRow> rows) {
496             // TODO Auto-generated method stub
497             
498         }
499 
500         public void selectionRectClosed(TimeBarViewerDelegate delegate) {
501             // TODO Auto-generated method stub
502             
503         }
504         
505     }
506     
507     class ResetRegionSelectionAction extends AbstractAction {
508         TimeBarViewer _tbv;
509         public ResetRegionSelectionAction(TimeBarViewer tbv) {
510             super("Remove selection");
511             _tbv = tbv;
512         }
513         public void actionPerformed(ActionEvent e) {
514             _tbv.clearRegionRect();
515         }
516         
517     }
518     class RunMarkerAction extends AbstractAction {
519         TimeBarViewer _tbv;
520         public RunMarkerAction(TimeBarViewer tbv) {
521             super("Run marker");
522             _tbv = tbv;
523         }
524         public void actionPerformed(ActionEvent e) {
525             _tm.setDate(_tbv.getModel().getMinDate().copy());
526             
527             final Timer timer = new Timer(40, null);
528             ActionListener al = new ActionListener() {
529 
530                 public void actionPerformed(ActionEvent e) {
531                     _tm.setDate(_tm.getDate().copy().advanceMillis(40));
532                     if (_tm.getDate().compareTo(_tbv.getModel().getMaxDate())>0) {
533                         timer.stop();
534                     }
535                 }
536                 
537             };
538         
539             timer.addActionListener(al);
540             timer.setRepeats(true);
541             timer.setDelay(40);
542             timer.start();
543         }
544         
545     }
546     
547     
548 }