long getReturnTime(GraphObject to) { for (GraphLink lnk : out_links) { if (lnk.getType() == LinkType.RETURN) { GraphObject go = lnk.getToObject(); if (go == to) return lnk.getTime(); else { long rt = go.getReturnTime(to); if (rt != 0) return Math.min(lnk.getTime(), rt); } } } return 0; }
@Override public String getToolTipText(MouseEvent e) { BddtHistoryItem itm = getItemAtPoint(e.getX(), e.getY()); if (itm != null) { StringBuffer buf = new StringBuffer(); BumpThreadStack stk = itm.getStack(); BumpStackFrame frm = stk.getFrame(0); if (frm == null) return null; buf.append(frm.getMethod() + " at " + frm.getLineNumber()); return buf.toString(); } GraphObject go = getObjectAtPoint(e.getX(), e.getY()); if (go != null) { return go.getName(); } return null; }
/** ***************************************************************************** */ @Override public void handlePopupMenu(MouseEvent e) { JPopupMenu popup = new JPopupMenu(); Point pt = SwingUtilities.convertPoint(getContentPane().getParent(), e.getPoint(), draw_area); BddtHistoryItem itm = getItemAtPoint(pt.x, pt.y); if (itm != null) { popup.add(new GotoSourceAction(itm)); popup.add(new GotoStackAction(itm)); } else { GraphObject go = getObjectAtPoint(pt.x, pt.y); if (go != null && go.getValue() != null) { popup.add(new GotoValueAction(go)); } } popup.add(getFloatBubbleAction()); popup.show(draw_area, pt.x, pt.y); }
private void drawObject(Graphics2D g, int idx, GraphObject go) { double x0 = left_right_margin + (object_width + object_hspacing) * idx; Rectangle2D r = new Rectangle2D.Double(x0, top_bottom_margin, object_width, object_height); graph_locations.put(go, x0 + object_width / 2); g.setColor(Color.WHITE); g.fill(r); g.setColor(Color.BLACK); g.draw(r); g.setColor(Color.RED); SwingText.drawText(go.getName(), g, r); double x1 = x0 + object_width / 2; double y1 = top_bottom_margin + object_height; double y2 = time_end; Line2D tl = new Line2D.Double(x1, y1, x1, y2); g.setColor(Color.BLACK); g.draw(tl); for (GraphBlock gb : go.getBlocks()) { drawBlock(g, x1, gb); } }
@Override public int compare(GraphObject t0, GraphObject t1) { long x0 = t1.getReturnTime(t0); long x1 = t0.getReturnTime(t1); if (x0 == x1) { // either same or == 0 long d = t0.getStartTime() - t1.getStartTime(); if (d < 0) return -1; else if (d > 0) return 1; else if (t0.getName() == null) return -1; else if (t1.getName() == null) return 1; else return t0.getName().compareTo(t1.getName()); } else if (x0 == 0) return -1; else if (x1 == 0) return 1; else if (x0 < x1) return 1; else return -1; }
private void drawLinks(Graphics2D g, GraphObject go) { double x0 = graph_locations.get(go); for (GraphLink gl : go.getLinks()) { GraphObject got = gl.getToObject(); double x1 = graph_locations.get(got); double y0 = getTimeY(gl.getTime()); double x3, x4; if (x0 < x1) { x3 = x0 + active_width / 2; x4 = x1 - active_width / 2; } else { x3 = x0 - active_width / 2; x4 = x1 + active_width / 2; } Stroke sk = type_strokes.get(gl.getType()); Color c = getThreadBlockColor(gl.getThread()); g.setColor(c); g.setStroke(sk); Line2D ln = new Line2D.Double(x3, y0, x4, y0); g.draw(ln); drawArrow(g, x3, y0, x4, y0); } }
/** ***************************************************************************** */ private BddtHistoryItem getItemAtPoint(int x, int y) { if (object_width == 0) return null; double t = history_graph.getStartTime() + (y - time_start) / (time_end - time_start) * (history_graph.getEndTime() - history_graph.getStartTime() + 1); if (t < history_graph.getStartTime() || t > history_graph.getEndTime()) return null; GraphObject gobj = getObjectAtPoint(x, y); // correlate with blocks if (gobj != null) { GraphBlock gb0 = null; double dtime = 0; for (GraphBlock gb : gobj.getBlocks()) { double dt = gb.getEndTime() - gb.getStartTime(); if (t >= gb.getStartTime() && t <= gb.getEndTime()) { if (gb0 == null || dt < dtime) { gb0 = gb; dtime = dt; } } } if (gb0 != null) { BddtHistoryItem bi0 = null; dtime = 0; for (BddtHistoryItem bhi : gb0.getItems()) { double dt = t - bhi.getTime(); if (dt >= 0) { if (bi0 == null || dt < dtime) { bi0 = bhi; dtime = dt; } } } if (bi0 != null) return bi0; } } // correlate with links double delta = (history_graph.getEndTime() - history_graph.getStartTime()) / (time_end - time_start) * 3; double dtime = 0; GraphLink gl0 = null; for (int i = 0; i < history_graph.getNumObjects(); ++i) { GraphObject go = history_graph.getObject(i); double x0 = graph_locations.get(go); for (GraphLink gl : go.getLinks()) { double x1 = graph_locations.get(gl.getToObject()); if (x > x0 && x < x1) { double dt = Math.abs(t - gl.getTime()); if (gl0 == null || dt < dtime) { gl0 = gl; dtime = dt; } } } } if (gl0 != null && dtime <= delta) { return gl0.getItem(); } return null; }
void addThreadItems(Iterable<BddtHistoryItem> itms, long since) { GraphObject lastobj = null; BddtHistoryItem lastitem = null; for (BddtHistoryItem hi : itms) { GraphObject go = getObject(hi); if (since == 0 || hi.getTime() > since) { last_time = Math.max(last_time, hi.getTime()); if (start_time == 0) start_time = last_time; else start_time = Math.min(start_time, hi.getTime()); if (go == null) continue; if (lastobj == null) { // first time go.startBlock(hi); } else if (lastobj == go) { // step inside the same object go.extendBlock(hi); } else if (lastitem != null && hi.isInside(lastitem)) { // step/call into a new object go.startBlock(hi); lastobj.addLink(go, LinkType.ENTER, hi); } else if (lastitem != null && lastitem.isInside(hi)) { // return to prior object go.extendBlock(hi); // end prior block?? lastobj.addLink(go, LinkType.RETURN, hi); } else { lastobj.finish(hi); go.startBlock(hi); lastobj.addLink(go, LinkType.NEXT, hi); } } lastobj = go; lastitem = hi; } }
GotoValueAction(GraphObject go) { super("Show this value"); for_value = go.getValue(); }