001: /*
002: * TracesCanvas.java
003: *
004: * Created on April 16, 2002, 5:40 PM
005: */
006:
007: /* This class displays the trace logged by the server
008: * Here is a description of the properties
009: *
010: * ------------------------------------------------------- ^
011: * | | |
012: * | Actor 1 Actor 2 Actor 3 | | 3
013: * | | |
014: * |------------------------------------------------------ v ^
015: * | | | | | | 4
016: * | |-------------->| | | v
017: * | | | | |
018: * | | | | |
019: * | | |-------------->| | ^
020: * | | | | | | 5
021: * | | | | | |
022: * | | |<--------------| | v
023: * | | | | |
024: * | | | | |
025: * | |<--------------| | | ^
026: * | | | | | | 6
027: * ------------------------------------------------------- v
028: * 7
029: * 1 2 <--------->
030: * <-----------> <--------------->
031: *
032: *
033: * 1 : FIRST_ACTOR_GAP
034: * 2 : HORIZONTAL_GAP
035: * 3 : ACTORS_STRIPE
036: * 4 : FIRST_ARROW_GAP
037: * 5 : VERTICAL_GAP
038: * 6 : LAST_ARROW_GAP
039: * 7 : LAST_ACTOR_GAP
040: */
041:
042: package tools.tracesviewer;
043:
044: import java.awt.*;
045: import java.awt.event.*;
046: import java.util.*;
047:
048: /**
049: *
050: * @author deruelle, chazeau
051: * @version 1.0
052: */
053: public class TracesCanvas extends Canvas implements MouseListener,
054: MouseMotionListener {
055:
056: public static int FIRST_ACTOR_GAP = 100;
057: public int HORIZONTAL_GAP = 350;
058: public static int ACTORS_STRIPE = 120;
059: public static int FIRST_ARROW_GAP = 50;
060: public static int VERTICAL_GAP = 60;
061: public static int LAST_ARROW_GAP = 30;
062: public static int LAST_ACTOR_GAP = 100;
063:
064: // This color is the color of the current selected SIP message
065: public Color SELECTED_COLOR = Color.red;
066: public Color[] ARROWS_COLOR = { Color.blue,
067: new Color(94, 151, 185), Color.green,
068: new Color(55, 223, 131), Color.orange,
069: new Color(209, 177, 69), Color.magenta,
070: new Color(187, 91, 185), Color.cyan,
071: new Color(199, 239, 39) };
072:
073: public String selectedArrowName;
074: public Arrow newArrow;
075: public Arrow oldArrow;
076:
077: public Image actorsImage;
078: public Image backgroundImage;
079:
080: public TracesSession tracesSession = null;
081: public TextArea messageContentTextArea = null;
082: public String tracesOrigin;
083:
084: public Hashtable actors = new Hashtable();
085: public Hashtable arrows = new Hashtable();
086: public Hashtable arrowsColors = new Hashtable();
087:
088: public boolean isAnimated = false;
089: public Arrow arrowTipTool = null;
090: public TracesViewer tracesViewer;
091:
092: public TracesMessage debugTracesMessage;
093:
094: public Dimension getPreferredSize() {
095: int width = FIRST_ACTOR_GAP + LAST_ACTOR_GAP + HORIZONTAL_GAP
096: * (actors.size() - 1);
097: int height = ACTORS_STRIPE + FIRST_ARROW_GAP + LAST_ARROW_GAP
098: + VERTICAL_GAP * (arrows.size() - 1);
099:
100: return new Dimension(width, height);
101: }
102:
103: public TracesCanvas(TracesSession tracesSession,
104: TextArea messageContentTextArea, String trueName,
105: TracesViewer tracesViewer) {
106: this .tracesViewer = tracesViewer;
107: backgroundImage = TracesViewer.backgroundImage;
108: actorsImage = TracesViewer.actorsImage;
109:
110: this .tracesSession = tracesSession;
111: this .messageContentTextArea = messageContentTextArea;
112:
113: refreshTracesCanvas(tracesSession, trueName);
114:
115: addMouseListener(this );
116: addMouseMotionListener(this );
117:
118: }
119:
120: // Reserved constructor for the AboutFrame
121: public TracesCanvas(TracesSession tracesSession,
122: Image backgroundImage, String trueName, int horizontalGap,
123: TracesViewer tracesViewer) {
124: this .tracesViewer = tracesViewer;
125:
126: this .backgroundImage = backgroundImage;
127: HORIZONTAL_GAP = horizontalGap;
128: actorsImage = TracesViewer.actorsImage;
129:
130: this .tracesSession = tracesSession;
131: this .messageContentTextArea = null;
132:
133: refreshTracesCanvas(tracesSession, trueName);
134:
135: addMouseListener(this );
136: addMouseMotionListener(this );
137: }
138:
139: public void refreshTracesCanvas(TracesSession tracesSession,
140: String tracesOrigin) {
141:
142: this .tracesSession = tracesSession;
143: // All of this has to called when the trace is refreshed or a new Session:
144: // The actors are the hosts
145: this .tracesOrigin = tracesOrigin;
146: constructActors();
147:
148: // All the SIP messages from the session
149: constructArrows();
150:
151: // We select the first message
152: selectMessage(FIRST_ACTOR_GAP + HORIZONTAL_GAP / 2,
153: ACTORS_STRIPE + FIRST_ARROW_GAP);
154: }
155:
156: public void drawTop(Graphics g) {
157: int widthCanvas = getSize().width;
158:
159: int heightCanvas = getSize().height;
160: // System.out.println(widthCanvas+","+heightCanvas);
161: // purple
162: g.setColor(new Color(0, 0, 125));
163: // light purple
164: //g.setColor(new Color(102,102,153));
165: // x, y, width, height
166: g.fillRect(0, 0, widthCanvas, ACTORS_STRIPE - 5);
167:
168: // Draw the String using the current Font and color
169: g.setColor(Color.white);
170: // display the label
171: Font f = g.getFont();
172: Font newFont = new Font(f.getName(), Font.BOLD | Font.ITALIC,
173: 17);
174: g.setFont(newFont);
175: // String, x,y
176: g.drawString("Trace retrieved from " + tracesOrigin, 40, 25);
177:
178: // draw a separation line:
179: g.setColor(Color.black);
180: // x,y -> x,y
181: g.drawLine(0, ACTORS_STRIPE, widthCanvas, ACTORS_STRIPE);
182:
183: // draw the actors above the separation line and their vertical line:
184: Enumeration e = actors.keys();
185: while (e.hasMoreElements()) {
186: String origin = (String) e.nextElement();
187: int positionX = ((Integer) actors.get(origin)).intValue();
188:
189: // if we have an image for the actors display it
190: // otherwise just do nothing
191: // Draw the name of the actor and its address below its icon:
192: // String, x,y
193: g.setColor(Color.white);
194: // if (origin.equals(TracesViewerLauncher.stackId) ){
195: // g.drawString(tracesOrigin,positionX - getFontMetrics(g.getFont()).stringWidth(tracesOrigin) / 2 ,
196: // ACTORS_STRIPE -30) ;
197: // }
198: // else {
199: // g.drawString("user agent",positionX - getFontMetrics(g.getFont()).stringWidth("user agent") / 2 ,
200: // ACTORS_STRIPE - 30) ;
201: // }
202: f = g.getFont();
203: newFont = new Font(f.getName(), Font.BOLD | Font.ITALIC, 14);
204: g.setFont(newFont);
205: g.drawString(origin, positionX
206: - getFontMetrics(g.getFont()).stringWidth(origin)
207: / 2, ACTORS_STRIPE - 15);
208:
209: if (actorsImage != null) {
210:
211: g.drawImage(actorsImage, positionX
212: - actorsImage.getWidth(this ) / 2,
213: ACTORS_STRIPE / 3, this );
214: } else {
215: //System.out.println("The actors icon is null!!");
216: }
217:
218: // Vertical line
219: g.setColor(Color.black);
220: g.drawLine(positionX, ACTORS_STRIPE, positionX,
221: heightCanvas);
222: }
223: }
224:
225: public void constructActors() {
226: try {
227: // We clean the table
228: actors = new Hashtable();
229: for (int i = 0; i < tracesSession.size(); i++) {
230: TracesMessage tracesMessage = (TracesMessage) tracesSession
231: .elementAt(i);
232:
233: String from = tracesMessage.getFrom().trim();
234: String to = tracesMessage.getTo().trim();
235: // System.out.println("consructorActors():"+tracesMessage.getMessageString() );
236: //System.out.println("from:"+from);
237: //System.out.println("to:"+from);
238: //System.out.println();
239:
240: //fromActorName = getActorName(from) ;
241: //to = getActorName(to) ;
242:
243: // We have to stock the actor and its position in the canvas
244: int sizeActors = actors.size();
245: if (actors.get(from) == null) {
246: actors.put(from, new Integer(sizeActors
247: * HORIZONTAL_GAP + FIRST_ACTOR_GAP));
248: }
249: sizeActors = actors.size();
250: if (actors.get(to) == null) {
251: actors.put(to, new Integer(sizeActors
252: * HORIZONTAL_GAP + FIRST_ACTOR_GAP));
253: }
254:
255: }
256: } catch (Exception e) {
257: System.out
258: .println("Error in trying to construct the actors");
259: }
260: }
261:
262: public void constructArrows() {
263: arrows = new Hashtable();
264: String from = null;
265: String to = null;
266:
267: // Assign different colors to each arrows
268: assignColors();
269: //System.out.println("Construct arrows");
270:
271: // Setup the first selected arrow:
272: selectedArrowName = "arrow1";
273: //System.out.println("tracesSession size:"+tracesSession.size());
274: for (int i = 0; i < tracesSession.size(); i++) {
275: TracesMessage tracesMessage = (TracesMessage) tracesSession
276: .elementAt(i);
277:
278: from = tracesMessage.getFrom();
279: to = tracesMessage.getTo();
280:
281: int positionXFrom = ((Integer) actors.get(from)).intValue();
282: int positionXTo = ((Integer) actors.get(to)).intValue();
283: int positionY = i * VERTICAL_GAP + ACTORS_STRIPE
284: + FIRST_ARROW_GAP;
285: boolean info = tracesMessage.getStatusInfo() != null;
286:
287: String arrowName = "arrow" + (i + 1);
288: boolean selected = false;
289:
290: // Set up the color of this arrow
291: String transactionId = tracesMessage.getTransactionId();
292:
293: Color color;
294: if (transactionId != null) {
295: color = (Color) arrowsColors.get(transactionId);
296: if (color == null)
297: color = Color.black;
298: } else
299: color = Color.black;
300:
301: if (positionXFrom == positionXTo) {
302: // This is a loop !!
303: CircleArrow circleArrow = new CircleArrow(selected,
304: arrowName, positionXFrom, positionY - 20,
305: positionY + 20, 40, true, info);
306: circleArrow.setColor(color);
307: circleArrow.setTracesMessage(tracesMessage);
308: circleArrow.setTracesCanvas(this );
309: arrows.put(arrowName, circleArrow);
310: } else {
311: // This is a straight arrow
312: //StraightArrow straightArrow=new StraightArrow(selected,arrowName,
313: //positionXFrom,positionXTo,positionY-15, positionY+15, true,info);
314:
315: StraightArrow straightArrow = new StraightArrow(
316: selected, arrowName, positionXFrom,
317: positionXTo, positionY - 31, positionY + 31,
318: true, info);
319:
320: straightArrow.setColor(color);
321: straightArrow.setTracesMessage(tracesMessage);
322: straightArrow.setTracesCanvas(this );
323: arrows.put(arrowName, straightArrow);
324: // System.out.println("color:"+ straightArrow.color);
325: // System.out.println("arrow name:"+straightArrow.arrowName);
326: // System.out.println("transactionId:"+tracesMessage.getTransactionId());
327: // System.out.println();
328:
329: }
330: }
331: // System.out.println("arrows size:"+arrows.size());
332: }
333:
334: public void assignColors() {
335: arrowsColors = new Hashtable();
336: TracesMessage tracesMessage = null;
337: int colorIndex = 0;
338:
339: for (int i = 0; i < tracesSession.size(); i++) {
340: tracesMessage = (TracesMessage) tracesSession.elementAt(i);
341: String transactionId = tracesMessage.getTransactionId();
342:
343: if (transactionId != null) {
344: Color color = (Color) arrowsColors.get(transactionId);
345: if (color == null) {
346: if (colorIndex >= 10)
347: color = Color.black;
348: else
349: color = ARROWS_COLOR[colorIndex];
350: arrowsColors.put(transactionId, color);
351: colorIndex++;
352: } else {
353: // the Color is already attribuated with this transaction id.
354: }
355: }
356: }
357: }
358:
359: public Arrow getArrow(int x, int y) {
360: //System.out.println("getArrow: x:"+x+" y:"+y);
361: Enumeration e = arrows.keys();
362: while (e.hasMoreElements()) {
363: String arrowName = (String) e.nextElement();
364: Arrow arrow = (Arrow) arrows.get(arrowName);
365: if (arrow == null)
366: return null;
367: if (arrow.isCollisionArrow(x, y))
368: return arrow;
369: }
370: return null;
371: }
372:
373: public Arrow getArrowInfo(int x, int y) {
374: //System.out.println("getArrow: x:"+x+" y:"+y);
375: Enumeration e = arrows.keys();
376: while (e.hasMoreElements()) {
377: String arrowName = (String) e.nextElement();
378: Arrow arrow = (Arrow) arrows.get(arrowName);
379: if (arrow == null)
380: return null;
381: else if (arrow.statusInfo) {
382: if (arrow.isCollisionInfo(x, y))
383: return arrow;
384: }
385: }
386: return null;
387: }
388:
389: public void selectMessage(int x, int y) {
390: // x,y: position of the cursor
391: newArrow = getArrow(x, y);
392: if (newArrow == null) {
393: // big problem
394: } else {
395: // We have to update the content:
396:
397: TracesMessage tracesMessage = newArrow.getTracesMessage();
398:
399: if (messageContentTextArea != null) {
400:
401: messageContentTextArea.setText(tracesMessage
402: .getMessageString());
403: if (tracesMessage.debugLine != null
404: && !tracesMessage.debugLine.equals("")) {
405:
406: tracesViewer.messageContentButton
407: .setText("SIP message: (debug log line: "
408: + tracesMessage.debugLine + " )");
409: }
410: }
411: debugTracesMessage = tracesMessage;
412:
413: // We have to change the color of the old message and the new one:
414: oldArrow = (Arrow) arrows.get(selectedArrowName);
415: oldArrow.selected = false;
416: newArrow.selected = true;
417: selectedArrowName = newArrow.arrowName;
418: repaint();
419: }
420: }
421:
422: public void showTipTool(int x, int y) {
423: Arrow oldArrowTipTool = arrowTipTool;
424: arrowTipTool = getArrow(x, y);
425: if (oldArrowTipTool != null) {
426: if (oldArrowTipTool.arrowName
427: .equals(arrowTipTool.arrowName)) {
428: // we do nothing because it is the same arrow
429: } else {
430: // A new arrow
431: oldArrowTipTool.displayTipTool = false;
432: arrowTipTool.displayTipTool = true;
433: repaint();
434: }
435: } else {
436: // The very first arrow selected!!!
437: arrowTipTool.displayTipTool = true;
438: repaint();
439: }
440: }
441:
442: public void unShowTipTool() {
443: if (arrowTipTool != null) {
444: arrowTipTool.displayTipTool = false;
445: repaint();
446: arrowTipTool = null;
447: }
448: }
449:
450: public void drawArrows(Graphics g) {
451: // draw the arrows and information
452: // Set up the Font
453:
454: Enumeration e = arrows.keys();
455: while (e.hasMoreElements()) {
456: String arrowName = (String) e.nextElement();
457: Arrow arrow = (Arrow) arrows.get(arrowName);
458: if (arrow.visible) {
459: //System.out.println("arrow:"+arrow.ymin);
460: arrow.draw(g);
461: }
462: }
463:
464: if (getParent() != null) {
465: getParent().doLayout();
466: getParent().validate();
467: }
468: }
469:
470: public void unvisibleAllArrows() {
471: Enumeration e = arrows.keys();
472: while (e.hasMoreElements()) {
473: String arrowName = (String) e.nextElement();
474: Arrow arrow = (Arrow) arrows.get(arrowName);
475: arrow.visible = false;
476: }
477: }
478:
479: public void unselectAllArrows() {
480: Enumeration e = arrows.keys();
481: while (e.hasMoreElements()) {
482: String arrowName = (String) e.nextElement();
483: Arrow arrow = (Arrow) arrows.get(arrowName);
484: arrow.selected = false;
485: }
486: }
487:
488: public boolean isOnArrow(int x, int y) {
489: Arrow arrow = getArrow(x, y);
490: if (arrow == null)
491: return false;
492: else
493: return true;
494: }
495:
496: public boolean isOnInfo(int x, int y) {
497: Arrow arrow = getArrowInfo(x, y);
498: if (arrow == null)
499: return false;
500: else
501: return true;
502: }
503:
504: public void displayInfo(int x, int y) {
505: Arrow arrow = getArrow(x, y);
506: arrow.displayInfo = true;
507: repaint();
508: }
509:
510: public void unDisplayInfo() {
511: //System.out.println("getArrow: x:"+x+" y:"+y);
512: Enumeration e = arrows.keys();
513: boolean repaint = false;
514: while (e.hasMoreElements()) {
515: String arrowName = (String) e.nextElement();
516: Arrow arrow = (Arrow) arrows.get(arrowName);
517: if (arrow != null)
518: if (arrow.displayInfo) {
519: arrow.displayInfo = false;
520: repaint = true;
521: }
522: }
523: repaint();
524: }
525:
526: public void setBackground(Graphics g) {
527: // if we have a background image, fill the back with it
528: // otherwise black by default
529:
530: if (backgroundImage != null
531: && backgroundImage.getWidth(this ) != -1
532: && backgroundImage.getHeight(this ) != -1) {
533: int widthImage = backgroundImage.getWidth(this );
534: int heightImage = backgroundImage.getHeight(this );
535:
536: int nbImagesX = getSize().width / widthImage + 1;
537: int nbImagesY = getSize().height / heightImage + 1;
538:
539: // we don't draw the image above the top
540:
541: for (int i = 0; i < nbImagesX; i++)
542: for (int j = 0; j < nbImagesY; j++)
543: g.drawImage(backgroundImage, i * widthImage, j
544: * heightImage + 95, this );
545: } else {
546:
547: g.setColor(Color.white);
548: g.fillRect(0, 95, getSize().width, getSize().height);
549: }
550:
551: }
552:
553: /*
554: // Without this method, the canvas is clippping!!!!!!
555: public void update(Graphics g){
556: try{
557: // Update is called only by selectMessage:
558: //System.out.println("update method called");
559:
560: setBackground(g);
561: drawTop(g);
562: drawArrows(g);
563:
564:
565: }
566: catch(Exception exception) {}
567: }*/
568:
569: public void paint(Graphics g) {
570: try {
571: // Paint is called each time:
572: // - resize of the window
573: // System.out.println();
574: // System.out.println("paint method called");
575: // We draw the title and some decorations:
576: setBackground(g);
577: drawTop(g);
578: drawArrows(g);
579: /*
580: Graphics2D g2 = (Graphics2D) g;
581:
582: // The width and height of the canvas
583: int w = getSize().width;
584: int h = getSize().height;
585: // Create an ellipse and use it as the clipping path
586: Ellipse2D e = new Ellipse2D.Float(w/4.0f,h/4.0f,
587: w/2.0f,h/2.0f);
588: g2.setClip(e);
589:
590: // Fill the canvas. Only the area within the clip is rendered
591: g2.setColor(Color.cyan);
592: g2.fillRect(0,0,w,h);
593:
594: // Change the clipping path, setting it to the intersection of
595: // the current clip and a new rectangle.
596: Rectangle r = new Rectangle(w/4+10,h/4+10,w/2-20,h/2-20);
597: g2.clip(r);
598:
599: // Fill the canvas. Only the area within the new clip
600: // is rendered
601: g2.setColor(Color.magenta);
602: g2.fillRect(0,0,w,h);
603: */
604: } catch (Exception exception) {
605: }
606: }
607:
608: public void mousePressed(MouseEvent e) {
609: // System.out.println("Mouse pressed in the canvas!!!");
610: try {
611: int x = e.getX();
612: int y = e.getY();
613:
614: if ((e.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
615: // The right button is pressed
616:
617: if (isOnArrow(x, y)) {
618:
619: //unShowTipTool();
620: arrowTipTool.displayTipTool = false;
621: arrowTipTool = null;
622: displayInfo(x, y);
623: }
624: } else {
625: // The left button is pressed:
626: if (isOnArrow(x, y)) {
627: //System.out.println("click on Arrow!!!");
628: selectMessage(x, y);
629: }
630: //if (isOnInfo(x,y)){
631: // displayInfo(x,y);
632: //}
633: }
634: } catch (Exception ex) {
635:
636: }
637: }
638:
639: public void mouseReleased(MouseEvent p1) {
640: unDisplayInfo();
641: }
642:
643: public void mouseEntered(MouseEvent p1) {
644: }
645:
646: public void mouseClicked(MouseEvent p1) {
647: }
648:
649: public void mouseExited(MouseEvent p1) {
650: }
651:
652: public void mouseDragged(MouseEvent p1) {
653: }
654:
655: public void mouseMoved(MouseEvent e) {
656: int x = e.getX();
657: int y = e.getY();
658:
659: if (isOnArrow(x, y)) {
660: showTipTool(x, y);
661: } else
662: unShowTipTool();
663: }
664:
665: }
|