@Override public void paintComponent(Graphics g) { // check if something needs to be painted at all if (ready) { sPage = startState.getPage(); myPage = sPage; ePage = endState.getPage(); } // check if anything needs to be drawn if (ready && (sPage == currPage || ePage == currPage)) { Graphics2D g2D = (Graphics2D) g; g2D.setColor(color); // draw arrow head for non-stub transitions if (currPage == ePage && !stub) { // find angle between end point and end control point int dx = (int) endCtrlPt.getX() - (int) endPt.getX(); int dy = (int) endCtrlPt.getY() - (int) endPt.getY(); double alpha = 0; if (dx == 0) { if (dy <= 0) alpha = Math.PI / 2; else alpha = 3 * Math.PI / 2; } else if (dx > 0 && dy > 0) alpha = 2 * Math.PI - Math.atan((double) dy / dx); else if (dx > 0 && dy <= 0) { if (dy == 0) alpha = 0; else alpha = -Math.atan((double) dy / (dx)); } else if (dx < 0) alpha = Math.PI - Math.atan((double) dy / dx); double adj = Math.PI / 6; int[] xP = { (int) endPt.getX(), (int) endPt.getX() + (int) (13 * Math.cos(alpha + adj)), (int) endPt.getX() + (int) (13 * Math.cos(alpha - adj)) }; int[] yP = { (int) endPt.getY(), (int) endPt.getY() - (int) (13 * Math.sin(alpha + adj)), (int) endPt.getY() - (int) (13 * Math.sin(alpha - adj)) }; g2D.drawPolygon(xP, yP, 3); g2D.fillPolygon(xP, yP, 3); } // draw stub if (currPage == sPage && stub) { g2D.drawLine( (int) startPt.getX(), (int) startPt.getY(), (int) pageS.getX(), (int) pageS.getY()); int x = (int) pageS.getX(); int y = (int) pageS.getY(); double cos = Math.cos(angle); double sin = Math.sin(angle); g2D.drawLine( x - (int) Math.round(6 * sin + 7 * cos), y - (int) Math.round(6 * cos - 7 * sin), x, y); g2D.drawLine( x, y, x + (int) Math.round(6 * sin - 7 * cos), y + (int) Math.round(6 * cos + 7 * sin)); FontMetrics fm = g2D.getFontMetrics(); int width = fm.stringWidth(endState.getName()); int height = fm.getHeight(); g2D.drawString( endState.getName(), (int) (pageS.getX() + (12 + width / 2) * Math.cos(angle) - width / 2), (int) (pageS.getY() - 12 * Math.sin(angle) + height / 3)); // draw control points if needed if (selectStatus != SelectOptions.NONE) { g2D.setColor(Color.red); g2D.fillRect((int) startPt.getX() - 3, (int) startPt.getY() - 3, 7, 7); g2D.fillRect((int) pageS.getX() - 3, (int) pageS.getY() - 3, 7, 7); g2D.setColor(color); } } // draw normal transition if (sPage == ePage && !stub) { g2D.draw(curve); // draw control points if (selectStatus != SelectOptions.NONE) { g2D.setColor(Color.red); g2D.fillRect((int) startPt.getX() - 3, (int) startPt.getY() - 3, 7, 7); g2D.fillRect((int) endPt.getX() - 3, (int) endPt.getY() - 3, 7, 7); g2D.fillRect((int) startCtrlPt.getX() - 3, (int) startCtrlPt.getY() - 3, 7, 7); g2D.fillRect((int) endCtrlPt.getX() - 3, (int) endCtrlPt.getY() - 3, 7, 7); g2D.drawLine( (int) startPt.getX(), (int) startPt.getY(), (int) startCtrlPt.getX(), (int) startCtrlPt.getY()); g2D.drawLine( (int) endPt.getX(), (int) endPt.getY(), (int) endCtrlPt.getX(), (int) endCtrlPt.getY()); g2D.setColor(color); } } // draw page connector if (sPage != ePage && !stub) { // if one start page if (sPage == currPage) { curve.setCurve( startPt.getX(), startPt.getY(), startCtrlPt.getX(), startCtrlPt.getY(), pageSC.getX(), pageSC.getY(), pageS.getX(), pageS.getY()); int x = (int) pageS.getX(); int y = (int) pageS.getY(); g2D.drawLine(x, y, x, y + 10); g2D.drawLine(x, y + 10, x + 30, y + 10); g2D.drawLine(x + 30, y + 10, x + 40, y); g2D.drawLine(x + 40, y, x + 30, y - 10); g2D.drawLine(x + 30, y - 10, x, y - 10); g2D.drawLine(x, y - 10, x, y); FontMetrics fm = g2D.getFontMetrics(); String pageName = drawArea.getPageName(endState.getPage()); String text = endState.getName() + " (" + pageName + ")"; int tW = fm.stringWidth(text); if (tW > 40) g2D.drawString(text, x + 40 - tW, y + 25); else g2D.drawString(text, x, y + 25); // draw control points if needed if (selectStatus != SelectOptions.NONE) { g2D.setColor(Color.red); g2D.fillRect((int) startPt.getX() - 3, (int) startPt.getY() - 3, 7, 7); g2D.fillRect((int) pageS.getX() - 3, (int) pageS.getY() - 3, 7, 7); g2D.fillRect((int) startCtrlPt.getX() - 3, (int) startCtrlPt.getY() - 3, 7, 7); g2D.fillRect((int) pageSC.getX() - 3, (int) pageSC.getY() - 3, 7, 7); g2D.drawLine( (int) startPt.getX(), (int) startPt.getY(), (int) startCtrlPt.getX(), (int) startCtrlPt.getY()); g2D.drawLine( (int) pageS.getX(), (int) pageS.getY(), (int) pageSC.getX(), (int) pageSC.getY()); } g2D.setColor(color); g2D.draw(curve); } // in on end page else if (ePage == currPage) { curve.setCurve( pageE.getX(), pageE.getY(), pageEC.getX(), pageEC.getY(), endCtrlPt.getX(), endCtrlPt.getY(), endPt.getX(), endPt.getY()); int x = (int) pageE.getX() - 40; int y = (int) pageE.getY(); g2D.drawLine(x, y, x, y + 10); g2D.drawLine(x, y + 10, x + 30, y + 10); g2D.drawLine(x + 30, y + 10, x + 40, y); g2D.drawLine(x + 40, y, x + 30, y - 10); g2D.drawLine(x + 30, y - 10, x, y - 10); g2D.drawLine(x, y - 10, x, y); g2D.drawString( startState.getName() + " (" + drawArea.getPageName(startState.getPage()) + ")", x, y + 25); // control points if needed if (selectStatus != SelectOptions.NONE) { g2D.setColor(Color.red); g2D.fillRect((int) endPt.getX() - 3, (int) endPt.getY() - 3, 7, 7); g2D.fillRect((int) pageE.getX() - 3, (int) pageE.getY() - 3, 7, 7); g2D.fillRect((int) endCtrlPt.getX() - 3, (int) endCtrlPt.getY() - 3, 7, 7); g2D.fillRect((int) pageEC.getX() - 3, (int) pageEC.getY() - 3, 7, 7); g2D.drawLine( (int) endPt.getX(), (int) endPt.getY(), (int) endCtrlPt.getX(), (int) endCtrlPt.getY()); g2D.drawLine( (int) pageE.getX(), (int) pageE.getY(), (int) pageEC.getX(), (int) pageEC.getY()); } g2D.setColor(color); g2D.draw(curve); } } } }