1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * William Bourque - Initial API and implementation
13 * 2010-06-10 Yuriy Vashchuk - GUI reorganisation, simplification and some
14 * related code improvements.
15 * 2010-06-20 Yuriy Vashchuk - Histograms optimisation.
16 * 2010-07-16 Yuriy Vashchuk - Histogram Canvas Heritage correction
17 *******************************************************************************/
19 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.histogram
;
21 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
22 import org
.eclipse
.linuxtools
.lttng
.event
.LttngTimestamp
;
23 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
24 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
25 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
26 import org
.eclipse
.linuxtools
.tmf
.experiment
.TmfExperiment
;
27 import org
.eclipse
.linuxtools
.tmf
.request
.ITmfDataRequest
;
28 import org
.eclipse
.linuxtools
.tmf
.request
.ITmfDataRequest
.ExecutionType
;
29 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfExperimentSelectedSignal
;
30 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfRangeSynchSignal
;
31 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalHandler
;
32 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfTimeSynchSignal
;
33 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfTrace
;
34 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfContext
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.TmfView
;
36 import org
.eclipse
.swt
.SWT
;
37 import org
.eclipse
.swt
.events
.ControlEvent
;
38 import org
.eclipse
.swt
.events
.ControlListener
;
39 import org
.eclipse
.swt
.graphics
.Font
;
40 import org
.eclipse
.swt
.graphics
.FontData
;
41 import org
.eclipse
.swt
.layout
.GridData
;
42 import org
.eclipse
.swt
.layout
.GridLayout
;
43 import org
.eclipse
.swt
.widgets
.Composite
;
44 import org
.eclipse
.swt
.widgets
.Text
;
47 * <b><u>HistogramView</u></b>
49 * View that contain an visual approach to the window that control the request.
50 * This is intended to replace the TimeFrameView
52 * This view is composed of 2 canvas, one for the whole experiment and one for the selected window in the experiment.
53 * It also contain a certain number of controls to print or change informations about the experiment.
55 public class HistogramView
extends TmfView
implements ControlListener
{
58 // Here is what's left to do in this view
60 // 1- Make sure the interval time is small enough on very big trace (bug 311930)
61 // The interval time of the content is dynamically assigned from the screen width and trace duration.
62 // However, on very big trace (more than 1 hour), we could end up with time interval that are > 1 seconds,
63 // which is not very precise.
64 // An algorithm need to be implemented to make sure we "increase" the number of interval in the content if
65 // their precision is getting too bad.
67 // 2- Make sure all control are thread safe (bug 309348)
68 // Right now, all the basic controls (i.e. Text and Label) are sensible to "Thread Access Exception" if
69 // updated from different threads; we need to carefully decide when/where to redraw them.
70 // This is a real problem since there is a lot of thread going on in this view.
71 // All basic control should be subclassed to offer "Asynchronous" functions.
73 // 3- Implement a "preferences view" for the HistogramView (bug 311935)
74 // There is a lot of adjustable preferences in the view, however there is no way to adjust them right now
75 // at run time. There should be a view of some kind of "menu" to allow the user to change them while executing.
76 // Most of the pertinent values are in HistogramConstant.java or in this file.
78 public static final String ID
= "org.eclipse.linuxtools.lttng.ui.views.histogram";
80 // "Minimum" screen width size. On smaller screen, we will apply several space saving technique
81 private static final int SCREEN_SMALL_IF_SMALLER_THAN
= 1600;
84 // 2010-06-20 Yuriy: We will use the dynamic height.
85 // Size of the "full trace" canvas
86 private static final int FULL_TRACE_CANVAS_HEIGHT = 25;
88 private static final int FULL_TRACE_BAR_WIDTH
= 1;
89 private static final double FULL_TRACE_DIFFERENCE_TO_AVERAGE
= 1.5;
91 // Size of the "Selected Window" canvas
94 private static final int SELECTED_WINDOW_CANVAS_WIDTH = 300;
95 private static final int SMALL_SELECTED_WINDOW_CANVAS_WIDTH = 200;
96 private static final int SELECTED_WINDOW_CANVAS_HEIGHT = 60;
98 private static final int SELECTED_WINDOW_BAR_WIDTH
= 1;
99 private static final double SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE
= 10.0;
101 // For the two "events" label (Max and Min number of events in the selection), we force a width
102 // This will prevent the control from moving horizontally if the number of events in the selection varies
103 private static final int NB_EVENTS_FIXED_WIDTH
= 50;
105 // The "small font" height used to display time will be "default font" minus this constant
106 private static final int SMALL_FONT_MODIFIER
= 2;
107 private static final int VERY_SMALL_FONT_MODIFIER
= 4;
110 // This need to be changed as soon the framework implement a "window"
111 // private static long DEFAULT_WINDOW_SIZE = (10L * 100 * 1000 * 1000); // 1sec
112 private static long DEFAULT_WINDOW_SIZE
= (1L * 100 * 1000 * 1000); // .1sec
114 // The last experiment received/used by the view
115 private TmfExperiment
<LttngEvent
> lastUsedExperiment
= null;
117 // Parent of the view
118 private Composite parent
= null;
120 // Request and canvas for the "full trace" part
121 private HistogramRequest dataBackgroundFullRequest
= null;
122 private static ParentHistogramCanvas fullExperimentCanvas
= null;
124 // Request and canvas for the "selected window"
125 private HistogramRequest selectedWindowRequest
= null;
126 private static ChildrenHistogramCanvas selectedWindowCanvas
= null;
128 // Content of the timeTextGroup
129 // Since the user can modify them with erroneous value,
130 // we will keep track of the value internally
131 private long currentEventTime
= 0L;
133 // *** All the UI control below
135 // NOTE : All textboxes will be READ_ONLY.
136 // So the user will be able to select/copy the value in them but not to change it
137 private Text txtExperimentStartTime
= null;
138 private Text txtExperimentStopTime
= null;
140 private Text txtWindowStartTime
= null;
141 private Text txtWindowStopTime
= null;
142 private Text txtWindowMaxNbEvents
= null;
143 private Text txtWindowMinNbEvents
= null;
145 // We move the time label to header from TimeTextGroup.java
146 // protected static final String NANOSEC_LABEL = "(sec)";
147 // private static final String WINDOW_TIMERANGE_LABEL_TEXT = "Window Timerange, " + NANOSEC_LABEL;
148 // private static final String WINDOW_CURRENT_TIME_LABEL_TEXT = "Cursor Centered on, " + NANOSEC_LABEL;
149 // private static final String EVENT_CURRENT_TIME_LABEL_TEXT = "Current Event Time, " + NANOSEC_LABEL;
150 private static final String WINDOW_TIMESPAN_LABEL_TEXT
= "Window Span (sec)";
151 private static final String WINDOW_CENTER_TIME_LABEL_TEXT
= "Window Center (sec)";
152 private static final String CURRENT_EVENT_TIME_LABEL_TEXT
= "Current Event (sec)";
153 private TimeTextGroup ntgWindowTimeSpan
= null;
154 private TimeTextGroup ntgWindowCenterTime
= null;
155 private TimeTextGroup ntgCurrentEventTime
= null;
158 * Default constructor of the view
160 public HistogramView() {
165 * Create the UI controls of this view
167 * @param parent The composite parent of this view
170 public void createPartControl(Composite newParent
) {
175 Font font
= parent
.getFont();
176 FontData tmpFontData
= font
.getFontData()[0];
179 Font smallFont
= null;
180 int nbEventWidth
= -1;
181 int selectedCanvasWidth
= -1;
182 boolean doesTimeTextGroupNeedAdjustment
= false;
184 // Calculate if we need "small screen" fixes
185 if ( parent
.getDisplay().getBounds().width
< SCREEN_SMALL_IF_SMALLER_THAN
) {
187 // A lot smaller font for timestamp
188 smallFont
= new Font(font
.getDevice(), tmpFontData
.getName(), tmpFontData
.getHeight() - VERY_SMALL_FONT_MODIFIER
, tmpFontData
.getStyle());
192 // Smaller selection window canvas
193 selectedCanvasWidth = SMALL_SELECTED_WINDOW_CANVAS_WIDTH;
195 // Smaller event number text field
196 nbEventWidth
= NB_EVENTS_FIXED_WIDTH
/2;
198 // Tell the text group to ajust
199 doesTimeTextGroupNeedAdjustment
= true;
203 // Slightly smaller font for timestamp
204 smallFont
= new Font(font
.getDevice(), tmpFontData
.getName(), tmpFontData
.getHeight() - SMALL_FONT_MODIFIER
, tmpFontData
.getStyle());
205 // Usual size for selected window and event number text field
206 nbEventWidth
= NB_EVENTS_FIXED_WIDTH
;
209 selectedCanvasWidth = SELECTED_WINDOW_CANVAS_WIDTH;
211 // No ajustement needed by the text group
212 doesTimeTextGroupNeedAdjustment
= false;
217 /////////////////////////////////////////////////////////////////////////////////////
218 // Layout for the whole view, other elements will be in a child composite of this one
220 // Composite layoutSelectionWindow
221 // Composite layoutTimesSpinner
222 // Composite layoutExperimentHistogram
223 /////////////////////////////////////////////////////////////////////////////////////
224 Composite layoutFullView
= new Composite(parent
, SWT
.FILL
);
225 GridLayout gridFullView
= new GridLayout();
226 gridFullView
.numColumns
= 2;
227 gridFullView
.horizontalSpacing
= 0;
228 gridFullView
.verticalSpacing
= 0;
229 gridFullView
.marginHeight
= 0;
230 gridFullView
.marginWidth
= 0;
231 layoutFullView
.setLayout(gridFullView
);
234 /////////////////////////////////////////////////////////////////////////////////////
235 // Layout that contain the time spinners
237 // NanosecTextGroup ntgCurrentEventTime
238 // NanosecTextGroup ntgTimeRangeWindow
239 // NanosecTextGroup ntgCurrentWindowTime
240 /////////////////////////////////////////////////////////////////////////////////////
241 Composite layoutTimeSpinners
= new Composite(layoutFullView
, SWT
.NONE
);
242 GridLayout gridTimesSpinner
= new GridLayout();
243 gridTimesSpinner
.numColumns
= 3;
244 gridTimesSpinner
.marginHeight
= 0;
245 gridTimesSpinner
.marginWidth
= 0;
246 gridTimesSpinner
.horizontalSpacing
= 5;
247 gridTimesSpinner
.verticalSpacing
= 0;
248 gridTimesSpinner
.makeColumnsEqualWidth
= true;
249 gridTimesSpinner
.marginLeft
= 5;
250 gridTimesSpinner
.marginRight
= 5;
251 layoutTimeSpinners
.setLayout(gridTimesSpinner
);
253 GridData gridDataCurrentEvent
= new GridData();
254 gridDataCurrentEvent
.horizontalAlignment
= SWT
.LEFT
;
255 gridDataCurrentEvent
.verticalAlignment
= SWT
.CENTER
;
256 ntgCurrentEventTime
= new TimeTextGroup(this, layoutTimeSpinners
, SWT
.BORDER
, SWT
.BORDER
, CURRENT_EVENT_TIME_LABEL_TEXT
, HistogramConstant
.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment
);
257 ntgCurrentEventTime
.setLayoutData(gridDataCurrentEvent
);
259 GridData gridDataTimeSpan
= new GridData();
260 gridDataTimeSpan
.horizontalAlignment
= SWT
.CENTER
;
261 gridDataTimeSpan
.verticalAlignment
= SWT
.CENTER
;
262 ntgWindowTimeSpan
= new TimeTextGroup(this, layoutTimeSpinners
, SWT
.BORDER
, SWT
.BORDER
, WINDOW_TIMESPAN_LABEL_TEXT
, HistogramConstant
.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment
);
263 ntgWindowTimeSpan
.setLayoutData(gridDataTimeSpan
);
265 GridData gridDataWindowCenter
= new GridData();
266 gridDataWindowCenter
.horizontalAlignment
= SWT
.RIGHT
;
267 gridDataWindowCenter
.verticalAlignment
= SWT
.CENTER
;
268 ntgWindowCenterTime
= new TimeTextGroup(this, layoutTimeSpinners
, SWT
.BORDER
, SWT
.BORDER
, WINDOW_CENTER_TIME_LABEL_TEXT
, HistogramConstant
.formatNanoSecondsTime(0L), doesTimeTextGroupNeedAdjustment
);
269 ntgWindowCenterTime
.setLayoutData(gridDataWindowCenter
);
272 /////////////////////////////////////////////////////////////////////////////////////
273 // Layout that contain the SelectionWindow
275 // Label txtWindowStartTime
276 // Label txtWindowStopTime
277 // Label txtWindowMaxNbEvents
278 // Label txtWindowMinNbEvents
279 // ChildrenHistogramCanvas selectedWindowCanvas
280 /////////////////////////////////////////////////////////////////////////////////////
281 Composite layoutSelectionWindow
= new Composite(layoutFullView
, SWT
.FILL
);
282 GridLayout gridSelectionWindow
= new GridLayout();
283 gridSelectionWindow
.numColumns
= 3;
284 gridSelectionWindow
.marginHeight
= 0;
285 gridSelectionWindow
.marginWidth
= 2;
286 gridSelectionWindow
.marginTop
= 5;
287 gridSelectionWindow
.horizontalSpacing
= 0;
288 gridSelectionWindow
.verticalSpacing
= 0;
289 layoutSelectionWindow
.setLayout(gridSelectionWindow
);
291 GridData gridDataSelectionWindow
= new GridData();
292 gridDataSelectionWindow
.horizontalAlignment
= SWT
.FILL
;
293 gridDataSelectionWindow
.verticalAlignment
= SWT
.FILL
;
294 layoutSelectionWindow
.setLayoutData(gridDataSelectionWindow
);
296 GridData gridDataSelectionWindowCanvas
= new GridData();
297 gridDataSelectionWindowCanvas
.horizontalSpan
= 2;
298 gridDataSelectionWindowCanvas
.verticalSpan
= 2;
299 gridDataSelectionWindowCanvas
.horizontalAlignment
= SWT
.FILL
;
300 gridDataSelectionWindowCanvas
.grabExcessHorizontalSpace
= true;
301 gridDataSelectionWindowCanvas
.verticalAlignment
= SWT
.FILL
;
304 gridDataSelectionWindowCanvas.heightHint = SELECTED_WINDOW_CANVAS_HEIGHT;
305 gridDataSelectionWindowCanvas.minimumHeight = SELECTED_WINDOW_CANVAS_HEIGHT;
307 gridDataSelectionWindowCanvas
.widthHint
= selectedCanvasWidth
;
308 gridDataSelectionWindowCanvas
.minimumWidth
= selectedCanvasWidth
;
309 selectedWindowCanvas
= new ChildrenHistogramCanvas(this, layoutSelectionWindow
, SWT
.BORDER
);
310 selectedWindowCanvas
.setLayoutData(gridDataSelectionWindowCanvas
);
312 GridData gridDataWindowMaxEvents
= new GridData();
313 gridDataWindowMaxEvents
.horizontalAlignment
= SWT
.RIGHT
;
314 gridDataWindowMaxEvents
.verticalAlignment
= SWT
.TOP
;
315 // Force a width, to avoid the control to enlarge if the number of events change
316 gridDataWindowMaxEvents
.minimumWidth
= nbEventWidth
;
317 txtWindowMaxNbEvents
= new Text(layoutSelectionWindow
, SWT
.READ_ONLY
);
318 txtWindowMaxNbEvents
.setFont(smallFont
);
319 txtWindowMaxNbEvents
.setBackground(parent
.getDisplay().getSystemColor(SWT
.COLOR_TITLE_INACTIVE_BACKGROUND
));
320 txtWindowMaxNbEvents
.setEditable(false);
321 txtWindowMaxNbEvents
.setText("0");
322 txtWindowMaxNbEvents
.setLayoutData(gridDataWindowMaxEvents
);
324 GridData gridDataWindowMinEvents
= new GridData();
325 gridDataWindowMinEvents
.horizontalAlignment
= SWT
.RIGHT
;
326 gridDataWindowMinEvents
.verticalAlignment
= SWT
.BOTTOM
;
327 // Force a width, to avoid the control to enlarge if the number of events change
328 gridDataWindowMinEvents
.minimumWidth
= nbEventWidth
;
329 txtWindowMinNbEvents
= new Text(layoutSelectionWindow
, SWT
.READ_ONLY
);
330 txtWindowMinNbEvents
.setFont(smallFont
);
331 txtWindowMinNbEvents
.setBackground(parent
.getDisplay().getSystemColor(SWT
.COLOR_TITLE_INACTIVE_BACKGROUND
));
332 txtWindowMinNbEvents
.setEditable(false);
333 txtWindowMinNbEvents
.setText("0");
334 txtWindowMinNbEvents
.setLayoutData(gridDataWindowMinEvents
);
336 GridData gridDataWindowStart
= new GridData();
337 gridDataWindowStart
.horizontalAlignment
= SWT
.LEFT
;
338 gridDataWindowStart
.verticalAlignment
= SWT
.BOTTOM
;
339 txtWindowStartTime
= new Text(layoutSelectionWindow
, SWT
.READ_ONLY
);
340 txtWindowStartTime
.setFont(smallFont
);
341 txtWindowStartTime
.setBackground(parent
.getDisplay().getSystemColor(SWT
.COLOR_TITLE_INACTIVE_BACKGROUND
));
342 txtWindowStartTime
.setEditable(false);
343 txtWindowStartTime
.setText("0.000000000");
344 txtWindowStartTime
.setLayoutData(gridDataWindowStart
);
346 GridData gridDataWindowStop
= new GridData();
347 gridDataWindowStop
.horizontalAlignment
= SWT
.RIGHT
;
348 gridDataWindowStop
.verticalAlignment
= SWT
.BOTTOM
;
349 txtWindowStopTime
= new Text(layoutSelectionWindow
, SWT
.READ_ONLY
);
350 txtWindowStopTime
.setFont(smallFont
);
351 txtWindowStopTime
.setBackground(parent
.getDisplay().getSystemColor(SWT
.COLOR_TITLE_INACTIVE_BACKGROUND
));
352 txtWindowStopTime
.setEditable(false);
353 txtWindowStopTime
.setText("0.000000000");
354 txtWindowStopTime
.setLayoutData(gridDataWindowStop
);
358 // 2010-06-10 Yuriy: NOT NEEDED AFTER GUI IMPROVEMENTS. WORK FINE WITOUT THIS HACK
360 // To align properly AND to make sure the canvas size is fixed, we NEED to make sure all "section" of the
361 // gridlayout are taken (and if possible of a fixed size).
362 // However, SWT is VERY VERY DUMB and won't consider griddata that contain no control.
363 // Since there will be missing a section, the SelectedWindowCanvas + NbEventsText will take 3 spaces, but
364 // startTimeText + stopTimeText will take only 2 (as if empty the other griddata of 1 will get ignored).
365 // StopTime will then take over the missing space; I want to align "stopTime" right on the end of canvas, so
366 // the added space to stop time would make it being aligned improperly
367 // So I NEED the empty griddata to be considered!
369 // |---------------|---------------|-----------|
370 // |SelectionCanvas SelectionCanvas|NbEventText|
371 // |SelectionCanvas SelectionCanvas|NbEventText|
372 // |---------------|---------------|-----------|
373 // |StartTime | StopTime| ??? |
374 // |---------------|---------------|-----------|
376 // So since SWT will only consider griddata with control,
377 // I need to create a totally useless control in the ??? section.
378 // That's ugly, useless and it is generally a bad practice.
381 // Other interesting fact about SWT : the way it draws (Fill/Expand control in grid) will change if
382 // the control is a Text or a Label.
383 // A Label here will be "pushed" by startTime/stopTime Text and won't fill the full space as NbEventText.
384 // A Text here will NOT be "pushed" and would give a nice visual output.
385 // (NB : No, I am NOT kidding, try it for yourself!)
387 // Soooooo I guess I will use a Text here. Way to go SWT!
388 // Downside is that disabled textbox has a slightly different color (even if you force it yourself) so if I want
389 // to make the text "invisible", I have to keep it enabled (but read only), so it can be clicked on.
391 // Label uselessControlToByPassSWTStupidBug = new Label(layoutSelectionWindow, SWT.BORDER); // WON'T align correctly!!!
392 //GridData gridDataSpacer = new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1);
393 GridData gridDataSpacer = new GridData();
394 gridDataWindowStop.horizontalAlignment = SWT.FILL;
395 gridDataWindowStop.verticalAlignment = SWT.TOP;
396 gridDataSpacer.minimumWidth = nbEventWidth;
397 Text uselessControlToByPassSWTStupidBug = new Text(layoutSelectionWindow, SWT.READ_ONLY); // WILL align correctly!!!
398 uselessControlToByPassSWTStupidBug.setEditable(false);
399 uselessControlToByPassSWTStupidBug.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
400 uselessControlToByPassSWTStupidBug.setLayoutData(gridDataSpacer);
404 /////////////////////////////////////////////////////////////////////////////////////
405 // Layout that contain the complete experiment histogram and related controls.
407 // ParentHistogramCanvas fullExperimentCanvas
408 // Text txtExperimentStartTime
409 // Text txtExperimentStopTime
410 /////////////////////////////////////////////////////////////////////////////////////
411 Composite layoutExperimentHistogram
= new Composite(layoutFullView
, SWT
.FILL
);
413 GridLayout gridExperimentHistogram
= new GridLayout();
414 gridExperimentHistogram
.numColumns
= 2;
415 gridExperimentHistogram
.marginHeight
= 0;
416 gridExperimentHistogram
.marginWidth
= 0;
417 gridExperimentHistogram
.horizontalSpacing
= 0;
418 gridExperimentHistogram
.verticalSpacing
= 0;
419 gridExperimentHistogram
.marginLeft
= 5;
420 gridExperimentHistogram
.marginRight
= 5;
421 layoutExperimentHistogram
.setLayout(gridExperimentHistogram
);
424 // 2010-06-10 Yuriy: NOT NEEDED AFTER GUI IMPROVEMENTS
425 GridData gridDataExperimentHistogram = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
426 layoutExperimentHistogram.setLayoutData(gridDataExperimentHistogram);
429 // *** Everything related to the experiment canvas is below
430 GridData gridDataExperimentCanvas
= new GridData();
431 gridDataExperimentCanvas
.horizontalSpan
= 2;
432 gridDataExperimentCanvas
.horizontalAlignment
= SWT
.FILL
;
433 gridDataExperimentCanvas
.grabExcessHorizontalSpace
= true;
434 gridDataExperimentCanvas
.verticalAlignment
= SWT
.FILL
;
435 gridDataExperimentCanvas
.grabExcessVerticalSpace
= true;
437 // 2010-06-20 Yuriy: We use the dynamic height.
438 gridDataExperimentCanvas.heightHint = FULL_TRACE_CANVAS_HEIGHT;
439 gridDataExperimentCanvas.minimumHeight = FULL_TRACE_CANVAS_HEIGHT;
441 fullExperimentCanvas
= new ParentHistogramCanvas(this, layoutExperimentHistogram
, SWT
.BORDER
);
442 fullExperimentCanvas
.setLayoutData(gridDataExperimentCanvas
);
443 layoutExperimentHistogram
.setLayoutData(gridDataExperimentCanvas
);
445 GridData gridDataExperimentStart
= new GridData();
446 gridDataExperimentStart
.horizontalAlignment
= SWT
.LEFT
;
447 gridDataExperimentStart
.verticalAlignment
= SWT
.BOTTOM
;
448 txtExperimentStartTime
= new Text(layoutExperimentHistogram
, SWT
.READ_ONLY
);
449 txtExperimentStartTime
.setFont(smallFont
);
450 txtExperimentStartTime
.setText("0.000000000");
451 txtExperimentStartTime
.setBackground(parent
.getDisplay().getSystemColor(SWT
.COLOR_TITLE_INACTIVE_BACKGROUND
));
452 txtExperimentStartTime
.setEditable(false);
453 txtExperimentStartTime
.setLayoutData(gridDataExperimentStart
);
455 GridData gridDataExperimentStop
= new GridData();
456 gridDataExperimentStop
.horizontalAlignment
= SWT
.RIGHT
;
457 gridDataExperimentStop
.verticalAlignment
= SWT
.BOTTOM
;
458 txtExperimentStopTime
= new Text(layoutExperimentHistogram
, SWT
.READ_ONLY
);
459 txtExperimentStopTime
.setFont(smallFont
);
460 txtExperimentStopTime
.setText("0.000000000");
461 txtExperimentStopTime
.setBackground(parent
.getDisplay().getSystemColor(SWT
.COLOR_TITLE_INACTIVE_BACKGROUND
));
462 txtExperimentStopTime
.setEditable(false);
463 txtExperimentStopTime
.setLayoutData(gridDataExperimentStop
);
467 // This is mainly used because of a because in the "experimentSelected()" notification, we shouldn't need this
469 * Method called when the view receive the focus.<p>
470 * If ExperimentSelected didn't send us a request yet, get the current Experiment and fire requests
472 @SuppressWarnings("unchecked")
474 public void setFocus() {
475 // WARNING : This does not seem to be thread safe
476 TmfExperiment
<LttngEvent
> tmpExperiment
= (TmfExperiment
<LttngEvent
>)TmfExperiment
.getCurrentExperiment();
478 if ( (dataBackgroundFullRequest
== null) && (tmpExperiment
!= null) ) {
479 createCanvasAndRequests(tmpExperiment
);
482 // Call a redraw for everything
487 * Method called when the user select (double-click on) an experiment.<p>
488 * We will create the needed canvas and fire the requests.
490 * @param signal Signal received from the framework. Contain the experiment.
492 @SuppressWarnings("unchecked")
494 public void experimentSelected(TmfExperimentSelectedSignal
<LttngEvent
> signal
) {
495 TmfExperiment
<LttngEvent
> tmpExperiment
= (TmfExperiment
<LttngEvent
>)signal
.getExperiment();
496 createCanvasAndRequests(tmpExperiment
);
501 // Not sure what this should do since I don't know when it will be called
502 // Let's do the same thing as experimentSelected for now
505 * Method called when an experiment is updated (??).<p>
506 * ...for now, do nothing, as udating an experiment running in the background might cause crash
508 * @param signal Signal received from the framework. Contain the experiment.
511 @SuppressWarnings("unchecked")
513 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
515 TmfExperiment<LttngEvent> tmpExperiment = (TmfExperiment<LttngEvent>)signal.getExperiment();
517 // Make sure the UI object are sane
518 resetControlsContent();
520 // Redraw the canvas right away to have something "clean" as soon as we can
521 fullExperimentCanvas.redraw();
522 selectedWindowCanvas.redraw();
524 // Recreate the request
525 createCanvasAndRequests(tmpExperiment);
530 * Method called when synchronization is active and that the user select an event.
531 * We update the current event timeTextGroup and move the selected window if needed.
533 * @param signal Signal received from the framework. Contain the event.
536 public void currentTimeUpdated(TmfTimeSynchSignal signal
) {
537 // In case we received our own signal
538 if ( (signal
!= null) && (signal
.getSource() != this) ) {
539 TmfTimestamp currentTime
= signal
.getCurrentTime();
541 // Update the current event controls
542 currentEventTime
= currentTime
.getValue();
543 updateSelectedEventTime();
545 // If the given event is outside the selection window, recenter the window
546 if ( isGivenTimestampInSelectedWindow( currentEventTime
) == false) {
547 fullExperimentCanvas
.setWindowCenterPosition( fullExperimentCanvas
.getHistogramContent().getClosestXPositionFromTimestamp(currentEventTime
) );
548 // Notify control that the window changed
549 windowChangedNotification();
550 // Send a broadcast to the framework about the window change
551 sendTmfRangeSynchSignalBroadcast();
557 public void synchToTimeRange(TmfRangeSynchSignal signal
) {
558 if ( (signal
!= null) && (signal
.getSource() != this) ) {
559 if ( lastUsedExperiment
!= null ) {
560 long currentTime
= signal
.getCurrentTime().getValue();
561 long windowStart
= signal
.getCurrentRange().getStartTime().getValue();
562 long windowEnd
= signal
.getCurrentRange().getEndTime().getValue();
563 long windowTimeWidth
= (windowEnd
- windowStart
);
565 // Recenter the window
566 fullExperimentCanvas
.setSelectedWindowSize(windowTimeWidth
);
567 fullExperimentCanvas
.setWindowCenterPosition( fullExperimentCanvas
.getHistogramContent().getClosestXPositionFromTimestamp(windowStart
+ (windowTimeWidth
/2)) );
570 // Views could send us incorrect current event value (event outside the current window)
571 // Here we make sure the value is sane, otherwise, we force it as the left border of the window
572 if ( isGivenTimestampInSelectedWindow( currentTime
) == false ) {
573 currentTime
= windowStart
;
575 currentEventTime
= currentTime
;
577 // Notify control that the window changed
578 windowChangedNotification();
580 // Make sure we redraw the change
581 fullExperimentCanvas
.redraw();
588 * Create the canvas needed and issue the requests
590 * @param newExperiment Experiment we will use for the request
592 private void createCanvasAndRequests(TmfExperiment
<LttngEvent
> newExperiment
) {
593 // Save the experiment we are about to use
594 lastUsedExperiment
= newExperiment
;
596 // // Create a copy of the trace that will be use only by the full experiment request
597 // TmfExperiment<LttngEvent> experimentCopy = newExperiment.createTraceCopy();
599 // Create the content for the full experiment.
600 // This NEED to be created first, as we use it in the selectedWindowCanvas
601 fullExperimentCanvas
.createNewHistogramContent(
602 fullExperimentCanvas
.getSize().x
,
603 FULL_TRACE_BAR_WIDTH
,
605 // 2010-06-20 Yuriy: We will use the dynamic height.
606 FULL_TRACE_CANVAS_HEIGHT
608 fullExperimentCanvas
.getSize().y
/ 2,
609 FULL_TRACE_DIFFERENCE_TO_AVERAGE
612 TmfTimeRange timeRange
= getExperimentTimeRange(newExperiment
);
614 // We will take the half of the full experiment length in case of bigger window size than the full experiment length
615 if(timeRange
.getEndTime().getValue() - timeRange
.getStartTime().getValue() > DEFAULT_WINDOW_SIZE
) {
616 fullExperimentCanvas
.createNewSelectedWindow(
617 timeRange
.getStartTime().getValue(),
621 fullExperimentCanvas
.createNewSelectedWindow(
622 timeRange
.getStartTime().getValue(),
623 (timeRange
.getEndTime().getValue() - timeRange
.getStartTime().getValue() ) / 2
627 currentEventTime
= timeRange
.getStartTime().getValue();
629 // Set the window of the fullTrace canvas visible.
630 fullExperimentCanvas
.getCurrentWindow().setSelectedWindowVisible(true);
631 fullExperimentCanvas
.getHistogramContent().resetTable(timeRange
.getStartTime().getValue(), timeRange
.getEndTime().getValue());
633 // Create the content for the selected window.
634 selectedWindowCanvas
.createNewHistogramContent(
635 selectedWindowCanvas
.getSize().x
,
636 SELECTED_WINDOW_BAR_WIDTH
,
637 selectedWindowCanvas
.getSize().y
,
638 SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE
640 selectedWindowCanvas
.getHistogramContent().resetTable(fullExperimentCanvas
.getCurrentWindow().getTimestampOfLeftPosition(), fullExperimentCanvas
.getCurrentWindow().getTimestampOfRightPosition());
642 // Make sure the UI object are sane
643 resetControlsContent();
645 // Redraw the canvas right away to have something "clean" as soon as we can
646 if ( dataBackgroundFullRequest
!= null ) {
647 fullExperimentCanvas
.redraw();
648 selectedWindowCanvas
.redraw();
650 // Nullify the (possible) old request to be sure we start we something clean
651 // Note : this is very important for the order of the request below,
652 // see "TODO" in performSelectedWindowEventsRequest
653 dataBackgroundFullRequest
= null;
654 selectedWindowRequest
= null;
656 // Perform both request.
657 // Order is important here, the small/synchronous request for the selection window should go first
658 performSelectedWindowEventsRequest(newExperiment
);
659 performAllTraceEventsRequest(newExperiment
);
662 // Before completing its indexing, the experiment doesn't know start/end time.
663 // However, LTTng individual traces have this knowledge so we should ask them
665 private TmfTimeRange
getExperimentTimeRange(TmfExperiment
<LttngEvent
> experiment
) {
666 // Before completing its indexing, the experiment doesn't know start/end time.
667 // However, LTTng individual traces have this knowledge so we should ask them
669 TmfTimestamp startTime
= TmfTimestamp
.BigCrunch
;
670 TmfTimestamp endTime
= TmfTimestamp
.BigBang
;
671 for (ITmfTrace trace
: experiment
.getTraces()) {
672 TmfContext context
= trace
.seekLocation(null);
674 TmfEvent event
= trace
.getNextEvent(context
);
675 TmfTimestamp traceStartTime
= event
.getTimestamp();
676 if (traceStartTime
.compareTo(startTime
, true) < 0)
677 startTime
= traceStartTime
;
678 TmfTimestamp traceEndTime
= trace
.getEndTime();
679 if (traceEndTime
.compareTo(endTime
, true) > 0)
680 endTime
= traceEndTime
;
682 TmfTimeRange tmpRange
= new TmfTimeRange(startTime
, endTime
);
687 * Perform a new request for the Selection window.<p>
688 * This assume the full experiment canvas has correct information about the selected window;
689 * we need the fullExperimentCanvas' HistogramContent to be created and a selection window to be set.
691 * @param experiment The experiment we will select from
693 public void performSelectedWindowEventsRequest(TmfExperiment
<LttngEvent
> experiment
) {
695 if(fullExperimentCanvas
!= null) {
696 HistogramSelectedWindow curSelectedWindow
= fullExperimentCanvas
.getCurrentWindow();
698 TmfTimeRange timeRange
= getExperimentTimeRange(experiment
);
700 // If no selection window exists, we will try to create one;
701 // however this will most likely fail as the content is probably not created either
702 if ( curSelectedWindow
== null ) {
703 // We will take the half of the full experiment length in case of bigger window size than the full experiment length
704 if(timeRange
.getEndTime().getValue() - timeRange
.getStartTime().getValue() > DEFAULT_WINDOW_SIZE
) {
705 fullExperimentCanvas
.createNewSelectedWindow(
706 timeRange
.getStartTime().getValue(),
710 fullExperimentCanvas
.createNewSelectedWindow(
711 timeRange
.getStartTime().getValue(),
712 (timeRange
.getEndTime().getValue() - timeRange
.getStartTime().getValue() ) / 2
715 curSelectedWindow
= fullExperimentCanvas
.getCurrentWindow();
718 // The request will go from the Left timestamp of the window to the Right timestamp
719 // This assume that out-of-bound value are handled by the SelectionWindow itself
720 LttngTimestamp ts1
= new LttngTimestamp( curSelectedWindow
.getTimestampOfLeftPosition() );
721 LttngTimestamp ts2
= new LttngTimestamp( curSelectedWindow
.getTimestampOfRightPosition() );
722 TmfTimeRange tmpRange
= new TmfTimeRange(ts1
, ts2
);
724 // Set a (dynamic) time interval
725 long intervalTime
= ( (ts2
.getValue() - ts1
.getValue()) / selectedWindowCanvas
.getHistogramContent().getNbElement() );
727 selectedWindowRequest
= performRequest(experiment
, selectedWindowCanvas
, tmpRange
, intervalTime
, ExecutionType
.FOREGROUND
);
728 selectedWindowCanvas
.redrawAsynchronously();
734 * Perform a new request for the full experiment.<p>
735 * NOTE : this is very long, we need to implement a way to run this in parallel (see TODO)
737 * @param experiment The experiment we will select from
739 public void performAllTraceEventsRequest(TmfExperiment
<LttngEvent
> experiment
) {
740 // Create a new time range from "start" to "end"
741 // That way, we will get "everything" in the trace
742 // LttngTimestamp ts1 = new LttngTimestamp( experiment.getStartTime() );
743 // LttngTimestamp ts2 = new LttngTimestamp( experiment.getEndTime() );
744 // TmfTimeRange tmpRange = new TmfTimeRange(ts1, ts2);
746 TmfTimeRange tmpRange
= getExperimentTimeRange(experiment
);
747 TmfTimestamp startTime
= tmpRange
.getStartTime();
748 TmfTimestamp endTime
= tmpRange
.getEndTime();
750 // Set a (dynamic) time interval
751 long intervalTime
= ( (endTime
.getValue() - startTime
.getValue()) / fullExperimentCanvas
.getHistogramContent().getNbElement() );
754 // This would enable "fixed interval" instead of dynamic one.
755 // ... we don't need it, do we?
757 // long intervalTime = ((long)(0.001 * (double)1000000000));
760 // It would be interesting if there was a way to tell the framework to run the request "in parallel" here.
761 // Mean a completetly independant copy of the Expereiment would be done and we would proceed on that.
763 dataBackgroundFullRequest
= performRequest(experiment
, fullExperimentCanvas
, tmpRange
, intervalTime
, ExecutionType
.BACKGROUND
);
766 fullExperimentCanvas
.getCurrentWindow().setWindowXPositionLeft(fullExperimentCanvas
.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas
.getCurrentWindow().getTimestampOfLeftPosition()));
767 fullExperimentCanvas
.getCurrentWindow().setWindowXPositionCenter(fullExperimentCanvas
.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas
.getCurrentWindow().getTimestampOfCenterPosition()));
768 fullExperimentCanvas
.getCurrentWindow().setWindowXPositionRight(fullExperimentCanvas
.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas
.getCurrentWindow().getTimestampOfRightPosition()));
770 fullExperimentCanvas
.redrawAsynchronously();
774 // This function is synchronized, is it a good idea?
775 // Tis is done to make sure requests arrive somewhat in order,
776 // this is especially important when request are issued from different thread.
778 * Create a new request from the given data and send it to the framework.<p>
779 * The request will be queued and processed later.
781 * @param experiment The experiment we will process the request on
782 * @param targetCanvas The canvas that will received the result
783 * @param newRange The range of the request
784 * @param newInterval The interval of time we use to store the result into the HistogramContent
786 private synchronized HistogramRequest
performRequest(TmfExperiment
<LttngEvent
> experiment
, HistogramCanvas targetCanvas
, TmfTimeRange newRange
, long newInterval
, ITmfDataRequest
.ExecutionType execType
) {
787 HistogramRequest returnedRequest
= null;
791 // We use int.MAX_VALUE because we want every events BUT we don't know the number inside the range.
792 // HOWEVER, this would cause the request to run forever (or until it reach the end of trace).
793 // Seeting an EndTime does not seems to stop the request
794 returnedRequest
= new HistogramRequest(newRange
, Integer
.MAX_VALUE
, targetCanvas
, newInterval
, execType
);
796 // Send the request to the framework : it will be queued and processed later
797 experiment
.sendRequest(returnedRequest
);
799 return returnedRequest
;
803 * Function used to warn that the selection window changed.<p>
804 * This might be called because the window moved or because its size changed.<p>
806 * We will update the different control related to the selection window.
808 public void windowChangedNotification() {
810 if ( lastUsedExperiment
!= null ) {
811 // If a request is ongoing, try to stop it
812 if (selectedWindowRequest
!= null && !selectedWindowRequest
.isCompleted()) {
813 selectedWindowRequest
.cancel();
816 if(fullExperimentCanvas
!= null) {
817 // If the current event time is outside the new window, change the current event
818 // The new current event will be the one closest to the LEFT side of the new window
819 if ( isGivenTimestampInSelectedWindow(currentEventTime
) == false ) {
820 currentEventChangeNotification( fullExperimentCanvas
.getCurrentWindow().getTimestampOfLeftPosition() );
824 // Perform a new request to read data about the new window
825 performSelectedWindowEventsRequest(lastUsedExperiment
);
830 * Function used to tell that the current event changed.<p>
831 * This might be called because the user changed the current event or
832 * because the last current event is now outside the selection window.<p>
834 * We update the related control and send a signal to notify other views of the new current event.
836 * @param newCurrentEventTime
838 public void currentEventChangeNotification(long newCurrentEventTime
) {
840 // Notify other views in the framework
841 if (currentEventTime
!= newCurrentEventTime
) {
842 currentEventTime
= newCurrentEventTime
;
844 // Update the UI control
845 updateSelectedEventTime();
849 public void sendTmfTimeSynchSignalBroadcast() {
851 // System.out.println("sendTmfTimeSynchSignalBroadcast " + System.currentTimeMillis());
853 // Send a signal to the framework
854 LttngTimestamp tmpTimestamp
= new LttngTimestamp(currentEventTime
);
855 broadcast(new TmfTimeSynchSignal(this, tmpTimestamp
));
859 * Function used to tell that the timerange (window) changed.<p>
860 * This will most likely be called if the time window is resized.
862 * We send a signal to notify other views of the new timerange.
864 public void sendTmfRangeSynchSignalBroadcast() {
866 if (TmfExperiment
.getCurrentExperiment() == null)
869 long startTime
= fullExperimentCanvas
.getCurrentWindow().getTimestampOfLeftPosition();
870 if ( startTime
< fullExperimentCanvas
.getHistogramContent().getStartTime() ) {
871 startTime
= fullExperimentCanvas
.getHistogramContent().getStartTime();
873 LttngTimestamp tmpStartTime
= new LttngTimestamp(startTime
);
875 long endTime
= fullExperimentCanvas
.getCurrentWindow().getTimestampOfRightPosition();
876 if ( endTime
> fullExperimentCanvas
.getHistogramContent().getEndTime() ) {
877 endTime
= fullExperimentCanvas
.getHistogramContent().getEndTime();
879 LttngTimestamp tmpEndTime
= new LttngTimestamp(endTime
);
881 TmfTimeRange tmpTimeRange
= new TmfTimeRange(tmpStartTime
, tmpEndTime
);
882 LttngTimestamp tmpEventTime
= new LttngTimestamp(currentEventTime
);
884 // Send a signal to the framework
885 broadcast(new TmfRangeSynchSignal(this, tmpTimeRange
, tmpEventTime
));
889 * Function that will be called when one of the time text group value is changed.<p>
890 * Since we don't (and can't unless we subclass them) know which one, we check them all.
892 public void timeTextGroupChangeNotification() {
894 if(ntgCurrentEventTime
!= null) {
895 // If the user changed the current event time, call the notification
896 long newCurrentTime
= ntgCurrentEventTime
.getValue();
897 if ( newCurrentTime
!= currentEventTime
) {
898 currentEventChangeNotification( newCurrentTime
);
899 // Send a broadcast to the framework about the window change
900 sendTmfTimeSynchSignalBroadcast();
904 if(ntgWindowCenterTime
!= null && fullExperimentCanvas
!= null) {
905 // If the user changed the selected window time, recenter the window and call the notification
906 long newSelectedWindowTime
= ntgWindowCenterTime
.getValue();
907 if ( newSelectedWindowTime
!= fullExperimentCanvas
.getCurrentWindow().getTimestampOfCenterPosition() ) {
908 fullExperimentCanvas
.setWindowCenterPosition(newSelectedWindowTime
);
909 windowChangedNotification();
910 // Send a broadcast to the framework about the window change
911 sendTmfRangeSynchSignalBroadcast();
915 if(ntgWindowTimeSpan
!= null && fullExperimentCanvas
!= null) {
916 // If the user changed the selected window size, resize the window and call the notification
917 long newSelectedWindowTimeRange
= ntgWindowTimeSpan
.getValue();
918 if ( newSelectedWindowTimeRange
!= fullExperimentCanvas
.getCurrentWindow().getWindowTimeWidth() ) {
919 fullExperimentCanvas
.resizeWindowByAbsoluteTime(newSelectedWindowTimeRange
);
920 windowChangedNotification();
921 // Send a broadcast to the framework about the window change
922 sendTmfRangeSynchSignalBroadcast();
929 * Getter for the last used experiment.<p>
930 * This might be different than the current experiment or even null.
932 * @return the last experiment we used in this view
934 public TmfExperiment
<LttngEvent
> getLastUsedExperiment() {
935 return lastUsedExperiment
;
939 * Check if a given timestamp is inside the selection window.<p>
940 * This assume fullExperimentCanvas contain a valid HistogramContent
942 * @param timestamp the timestamp to check
944 * @return if the time is inside the selection window or not
946 public boolean isGivenTimestampInSelectedWindow(long timestamp
) {
947 boolean returnedValue
= true;
949 // If the content is not set correctly, this will return weird (or even null) result
950 if ( (timestamp
< fullExperimentCanvas
.getCurrentWindow().getTimestampOfLeftPosition() ) ||
951 (timestamp
> fullExperimentCanvas
.getCurrentWindow().getTimestampOfRightPosition() ) )
953 returnedValue
= false;
956 return returnedValue
;
960 * Reset the content of all Controls.<p>
961 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
963 public void resetControlsContent() {
965 TmfExperiment
<LttngEvent
> tmpExperiment
= getLastUsedExperiment();
967 // Use the previous Start and End time, or default if they are not available
968 String startTime
= null;
969 String stopTime
= null;
970 if ( tmpExperiment
!= null ) {
971 startTime
= HistogramConstant
.formatNanoSecondsTime( tmpExperiment
.getStartTime().getValue() );
972 stopTime
= HistogramConstant
.formatNanoSecondsTime( tmpExperiment
.getEndTime().getValue() );
975 startTime
= HistogramConstant
.formatNanoSecondsTime( 0L );
976 stopTime
= HistogramConstant
.formatNanoSecondsTime( 0L );
979 txtExperimentStartTime
.setText( startTime
);
980 txtExperimentStopTime
.setText( stopTime
);
981 txtExperimentStartTime
.getParent().layout();
983 txtWindowMaxNbEvents
.setText("" + 0);
984 txtWindowMinNbEvents
.setText("" + 0);
985 txtWindowStartTime
.setText( HistogramConstant
.formatNanoSecondsTime( 0L ) );
986 txtWindowStopTime
.setText( HistogramConstant
.formatNanoSecondsTime( 0L ) );
987 txtWindowStartTime
.getParent().layout();
989 ntgWindowCenterTime
.setValue( HistogramConstant
.formatNanoSecondsTime( 0L ) );
990 ntgWindowTimeSpan
.setValue( HistogramConstant
.formatNanoSecondsTime( 0L ) );
992 // Using "startTime" here can avoid an useless TmfTimeSynchSignal here
993 // However it look ugly to have only this time
994 ntgCurrentEventTime
.setValue( HistogramConstant
.formatNanoSecondsTime( 0L ) );
998 * Update the content of the controls related to the full experiment canvas<p>
999 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
1001 public void updateFullExperimentInformation() {
1003 if(fullExperimentCanvas
!= null) {
1004 String startTime
= HistogramConstant
.formatNanoSecondsTime( fullExperimentCanvas
.getHistogramContent().getStartTime() );
1005 String stopTime
= HistogramConstant
.formatNanoSecondsTime( fullExperimentCanvas
.getHistogramContent().getEndTime() );
1007 txtExperimentStartTime
.setText( startTime
);
1008 txtExperimentStopTime
.setText( stopTime
);
1011 // Take one of the parent and call its layout to update control size
1012 // Since both control have the same parent, only one call is needed
1013 txtExperimentStartTime
.getParent().layout();
1015 // Update the selected window, just in case
1016 // This should give a better user experience and it is low cost
1017 updateSelectedWindowInformation();
1021 * Update the content of the controls related to the selection window canvas<p>
1022 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
1024 public void updateSelectedWindowInformation() {
1025 // Update the timestamp as well
1026 updateSelectedWindowTimestamp();
1028 if(selectedWindowCanvas
!= null) {
1029 txtWindowMaxNbEvents
.setText( Long
.toString(selectedWindowCanvas
.getHistogramContent().getHeighestEventCount()) );
1030 txtWindowMinNbEvents
.setText(Long
.toString(0));
1033 // Refresh the layout
1034 txtWindowMaxNbEvents
.getParent().layout();
1038 * Update the content of the controls related to the timestamp of the selection window<p>
1039 * WARNING : Calls in there are not thread safe and can't be called from different thread than "main"
1041 public void updateSelectedWindowTimestamp() {
1043 if(selectedWindowCanvas
!= null) {
1044 String startTime
= HistogramConstant
.formatNanoSecondsTime( selectedWindowCanvas
.getHistogramContent().getStartTime() );
1045 String stopTime
= HistogramConstant
.formatNanoSecondsTime( selectedWindowCanvas
.getHistogramContent().getEndTime() );
1046 txtWindowStartTime
.setText( startTime
);
1047 txtWindowStopTime
.setText( stopTime
);
1050 if(fullExperimentCanvas
!= null) {
1051 ntgWindowCenterTime
.setValue( fullExperimentCanvas
.getCurrentWindow().getTimestampOfCenterPosition() );
1052 ntgWindowTimeSpan
.setValue( fullExperimentCanvas
.getCurrentWindow().getWindowTimeWidth() );
1054 // If the current event time is outside the selection window, recenter our window
1055 if ( isGivenTimestampInSelectedWindow(ntgCurrentEventTime
.getValue()) == false ) {
1056 currentEventChangeNotification( fullExperimentCanvas
.getCurrentWindow().getTimestampOfCenterPosition() );
1060 // Take one control in each group to call to refresh the layout
1061 // Since both control have the same parent, only one call is needed
1062 txtWindowStartTime
.getParent().layout();
1063 ntgWindowCenterTime
.getParent().layout();
1067 * Update the controls related current event.<p>
1068 * The call here SHOULD be thread safe and can be call from any threads.
1070 public void updateSelectedEventTime() {
1071 ntgCurrentEventTime
.setValueAsynchronously(currentEventTime
);
1072 // sendTmfTimeSynchSignalBroadcast();
1073 // Tell the selection canvas which event is currently selected
1074 // This give a nice graphic output
1075 selectedWindowCanvas
.getHistogramContent().setSelectedEventTimeInWindow(currentEventTime
);
1076 selectedWindowCanvas
.redrawAsynchronously();
1080 * Method called when the view is moved.<p>
1082 * Just redraw everything...
1084 * @param event The control event generated by the move.
1087 public void controlMoved(ControlEvent event
) {
1092 * Method called when the view is resized.<p>
1094 * We will make sure that the size didn't change more than the content size.<p>
1095 * Otherwise we need to perform a new request for the full experiment because we are missing data).
1097 * @param event The control event generated by the resize.
1100 public void controlResized(ControlEvent event
) {
1102 // Ouch! The screen enlarged (screen resolution changed?) so far that we miss content to fill the space.
1103 if ( parent
.getDisplay().getBounds().width
> fullExperimentCanvas
.getHistogramContent().getNbElement() ) {
1104 if ( lastUsedExperiment
!= null ) {
1105 createCanvasAndRequests(lastUsedExperiment
);
1112 * Getter of FullExperimentCanvas
1114 * @return FullExperimentCanvas object
1116 public static ParentHistogramCanvas
getFullExperimentCanvas() {
1117 return fullExperimentCanvas
;
1121 * Getter of SelectedWindowCanvas
1123 * @return SelectedWindowCanvas object
1125 public static ChildrenHistogramCanvas
getSelectedWindowCanvas() {
1126 return selectedWindowCanvas
;
1131 * Getter of DEFAULT_WINDOW_SIZE
1133 * @return DEFAULT_WINDOW_SIZE value
1135 public static long getDEFAULT_WINDOW_SIZE() {
1136 return DEFAULT_WINDOW_SIZE
;
1140 * Getter for dataBackgroundFullRequest variable
1141 * @return the dataBackgroundFullRequest instance
1143 public HistogramRequest
getDataBackgroundFullRequest() {
1144 return dataBackgroundFullRequest
;
1148 * Getter for selectedWindowRequest variable
1149 * @return the selectedWindowRequest instance
1151 public HistogramRequest
getSelectedWindowRequest() {
1152 return selectedWindowRequest
;