@Override public Point getCenter(int page) { if (!ready) return new Point(0, 0); sPage = startState.getPage(); myPage = sPage; ePage = endState.getPage(); if (sPage == ePage) { if (!stub) { int x = (int) ((endPt.getX() - startPt.getX()) / 2 + startPt.getX()); int y = (int) ((endPt.getY() - startPt.getY()) / 2 + startPt.getY()); return new Point(x, y); } else { return new Point( (int) (startPt.getX() + len * .5 * Math.cos(angle)), (int) (startPt.getY() - len * .5 * Math.sin(angle))); } } else { if (page == sPage) { int x = (int) ((pageS.getX() - startPt.getX()) / 2 + startPt.getX()); int y = (int) ((pageS.getY() - startPt.getY()) / 2 + startPt.getY()); return new Point(x, y); } else { int x = (int) ((pageE.getX() - endPt.getX()) / 2 + endPt.getX()); int y = (int) ((pageE.getY() - endPt.getY()) / 2 + endPt.getY()); return new Point(x, y); } } }
public boolean pageConnectorExists(int page, StateObj state, String type) { // force redraw for all connecors if ((sPage != ePage) && ((startState.equals(state) && sPage == page && type.equals("start")) || (endState.equals(state) && ePage == page && type.equals("end")))) return true; else return false; }
@Override public void save(BufferedWriter writer) throws IOException { writer.write("## START STATE TRANSITION OBJECT\n"); writer.write("<transition>\n"); writer.write(i(1) + "<attributes>\n"); for (int i = 0; i < attrib.size(); i++) { ObjAttribute obj = attrib.get(i); obj.save(writer, 1); } writer.write(i(1) + "</attributes>\n"); writer.write( i(1) + "<startState>\n" + i(1) + startState.getName() + "\n" + i(1) + "</startState>\n"); writer.write(i(1) + "<endState>\n" + i(1) + endState.getName() + "\n" + i(1) + "</endState>\n"); writer.write(i(1) + "<startPtX>\n" + i(1) + startPt.getX() + "\n" + i(1) + "</startPtX>\n"); writer.write(i(1) + "<startPtY>\n" + i(1) + startPt.getY() + "\n" + i(1) + "</startPtY>\n"); writer.write(i(1) + "<endPtX>\n" + i(1) + endPt.getX() + "\n" + i(1) + "</endPtX>\n"); writer.write(i(1) + "<endPtY>\n" + i(1) + endPt.getY() + "\n" + i(1) + "</endPtY>\n"); writer.write( i(1) + "<startCtrlPtX>\n" + i(1) + startCtrlPt.getX() + "\n" + i(1) + "</startCtrlPtX>\n"); writer.write( i(1) + "<startCtrlPtY>\n" + i(1) + startCtrlPt.getY() + "\n" + i(1) + "</startCtrlPtY>\n"); writer.write( i(1) + "<endCtrlPtY>\n" + i(1) + endCtrlPt.getX() + "\n" + i(1) + "</endCtrlPtY>\n"); writer.write( i(1) + "<endCtrlPtY>\n" + i(1) + endCtrlPt.getY() + "\n" + i(1) + "</endCtrlPtY>\n"); writer.write( i(1) + "<startStateIndex>\n" + i(1) + startStateIndex + "\n" + i(1) + "</startStateIndex>\n"); writer.write( i(1) + "<endStateIndex>\n" + i(1) + endStateIndex + "\n" + i(1) + "</endStateIndex>\n"); writer.write(i(1) + "<page>\n" + i(1) + myPage + "\n" + i(1) + "</page>\n"); writer.write(i(1) + "<color>\n" + i(1) + color.getRGB() + "\n" + i(1) + "</color>\n"); writer.write(i(1) + "<pageSX>\n" + i(1) + pageS.getX() + "\n" + i(1) + "</pageSX>\n"); writer.write(i(1) + "<pageSY>\n" + i(1) + pageS.getY() + "\n" + i(1) + "</pageSY>\n"); writer.write(i(1) + "<pageSCX>\n" + i(1) + pageSC.getX() + "\n" + i(1) + "</pageSCX>\n"); writer.write(i(1) + "<pageSCY>\n" + i(1) + pageSC.getY() + "\n" + i(1) + "</pageSCY>\n"); writer.write(i(1) + "<pageEX>\n" + i(1) + pageE.getX() + "\n" + i(1) + "</pageEX>\n"); writer.write(i(1) + "<pageEY>\n" + i(1) + pageE.getY() + "\n" + i(1) + "</pageEY>\n"); writer.write(i(1) + "<pageECX>\n" + i(1) + pageEC.getX() + "\n" + i(1) + "</pageECX>\n"); writer.write(i(1) + "<pageECY>\n" + i(1) + pageEC.getY() + "\n" + i(1) + "</pageECY>\n"); writer.write(i(1) + "<stub>\n" + i(1) + stub + "\n" + i(1) + "</stub>\n"); writer.write("</transition>\n"); writer.write("## END STATE TRANSITION OBJECT\n"); }
@Override public void updateObjPages(int page) { if (startState.getPage() == endState.getPage()) { if (attrib != null) { for (int i = 0; i < attrib.size(); i++) { ObjAttribute obj = attrib.get(i); obj.setPage(page); } } myPage = sPage = ePage = page; // updateObj(); } else updateObj(); }
@Override public void makeConnections(Collection<GeneralObj> objList) { for (GeneralObj obj : objList) { if (obj.getType() == GeneralObjType.STATE) { if (obj.getName().equals(startS)) { startState = (StateObj) obj; } if (obj.getName().equals(endS)) { endState = (StateObj) obj; } } } startBorderPts = startState.getBorderPts(); endBorderPts = endState.getBorderPts(); sPage = startState.getPage(); ePage = endState.getPage(); if (stub) { angle = getAngle(startPt, startState.getRealCenter(myPage)); len = (int) startPt.distance(pageS); } }
// will only auto-redraw under certain conditions private void moveEndPts() { startBorderPts = startState.getBorderPts(); endBorderPts = endState.getBorderPts(); sPage = startState.getPage(); ePage = endState.getPage(); if (sPage != ePage && !stub) { int sOffset = drawArea.getOffset(sPage, startState, this, "start"); int eOffset = drawArea.getOffset(ePage, endState, this, "end"); int sBorderOffset = sOffset / 20; if (sBorderOffset < 0) sBorderOffset += 36; if (sBorderOffset > 35) sBorderOffset -= 36; int eBorderOffset = -eOffset / 20; if (eBorderOffset < -18) eBorderOffset += 36; if (eBorderOffset > 17) eBorderOffset -= 36; startPt = startBorderPts.get(0 + sBorderOffset); startCtrlPt = new Point((int) startPt.getX() + 20, (int) startPt.getY()); endPt = endBorderPts.get(18 + eBorderOffset); endCtrlPt = new Point((int) endPt.getX() - 20, (int) endPt.getY()); pageS = new Point(drawArea.getMaxW() - 50, (int) startPt.getY() + sOffset); pageSC = new Point(drawArea.getMaxW() - 70, (int) startPt.getY() + sOffset); pageE = new Point(50, (int) endPt.getY() + eOffset); pageEC = new Point(70, (int) endPt.getY() + eOffset); } else if (stub) { // TODO // System.out.println("in stub loop, moveendpts"); startPt = startBorderPts.get(startStateIndex); pageS.setLocation( new Point( (int) (startPt.getX() + len * Math.cos(angle)), (int) (startPt.getY() - len * Math.sin(angle)))); } else { // or if multiple states selected, dont need to recalculate if ((!recalcCheck() && !drawArea.getRedraw()) || (startState.getSelectStatus() != SelectOptions.NONE && endState.getSelectStatus() != SelectOptions.NONE)) { startStateIndex = tempStartIndex; endStateIndex = tempEndIndex; startPt = startBorderPts.get(startStateIndex); endPt = endBorderPts.get(endStateIndex); // if movement hasnt left the start quadrant, don't recalulate all // points startCtrlPt = new Point((int) startPt.getX() + sdx, (int) startPt.getY() + sdy); endCtrlPt = new Point((int) endPt.getX() + edx, (int) endPt.getY() + edy); } else setEndPts(); } }
@Override public void updateObj() { int oldS = sPage; int oldE = ePage; sPage = startState.getPage(); myPage = sPage; ePage = endState.getPage(); if (oldS != sPage && oldS != oldE) { for (int i = 0; i < attrib.size(); i++) { ObjAttribute obj = attrib.get(i); if (obj.getPage() == oldS) obj.setPage(sPage); } } if (oldE != ePage && oldS != oldE) { for (int i = 0; i < attrib.size(); i++) { ObjAttribute obj = attrib.get(i); if (obj.getPage() == oldE) obj.setPage(ePage); } } if (sPage != ePage && oldS == oldE) { for (int i = 0; i < attrib.size(); i++) { ObjAttribute obj = attrib.get(i); obj.setPage(sPage); } } if ((startState.getSelectStatus() != SelectOptions.TXT && startState.getSelectStatus() != SelectOptions.NONE) || (endState.getSelectStatus() != SelectOptions.TXT && endState.getSelectStatus() != SelectOptions.NONE)) { if (oldS != oldE && sPage == ePage) setEndPts(); else moveEndPts(); curve.setCurve( startPt.getX(), startPt.getY(), startCtrlPt.getX(), startCtrlPt.getY(), endCtrlPt.getX(), endCtrlPt.getY(), endPt.getX(), endPt.getY()); } }
@Override public void adjustShapeOrPosition(int x, int y) { if (selectStatus == SelectOptions.START) { Point currPt = new Point(x, y); double temp; double max = 1000000; for (int i = 0; i < 36; i++) { temp = currPt.distanceSq(startBorderPts.get(i)); if (temp < max) { startStateIndex = i; max = temp; } } startPt.setLocation( startBorderPts.get(startStateIndex).getX(), startBorderPts.get(startStateIndex).getY()); if (stub) { angle = getAngle(startPt, startState.getRealCenter(myPage)); pageS.setLocation( new Point( (int) (startPt.getX() + len * Math.cos(angle)), (int) (startPt.getY() - len * Math.sin(angle)))); } } if (selectStatus == SelectOptions.STARTCTRL) startCtrlPt.setLocation(x, y); if (selectStatus == SelectOptions.ENDCTRL) endCtrlPt.setLocation(x, y); if (selectStatus == SelectOptions.END) { Point currPt = new Point(x, y); double temp; double max = 1000000; for (int i = 0; i < 36; i++) { temp = currPt.distanceSq(endBorderPts.get(i)); if (temp < max) { endStateIndex = i; max = temp; } } endPt.setLocation( endBorderPts.get(endStateIndex).getX(), endBorderPts.get(endStateIndex).getY()); } if (selectStatus == SelectOptions.PAGES) { pageS.setLocation(pageS.getX() + x - xTemp, pageS.getY() + y - yTemp); xTemp = x; yTemp = y; if (stub) { angle = getAngle(pageS, startState.getRealCenter(myPage)); int index = 36 - (int) Math.round((angle / (Math.PI * 2)) * 36); if (index > 35) index -= 36; startStateIndex = index; startPt = startBorderPts.get(index); len = (int) startPt.distance(pageS); } } if (selectStatus == SelectOptions.PAGESC) pageSC.setLocation(x, y); if (selectStatus == SelectOptions.PAGEEC) pageEC.setLocation(x, y); if (selectStatus == SelectOptions.PAGEE) { pageE.setLocation(pageE.getX() + x - xTemp, pageE.getY() + y - yTemp); xTemp = x; yTemp = y; } if (selectStatus == SelectOptions.TXT) { if (attrib != null) { for (int i = 0; i < attrib.size(); i++) { ObjAttribute s = attrib.get(i); if (s.getSelectStatus() != 0) { s.adjustShapeOrPosition(x, y); break; } } } } if (startState.getPage() == endState.getPage()) curve.setCurve( startPt.getX(), startPt.getY(), startCtrlPt.getX(), startCtrlPt.getY(), endCtrlPt.getX(), endCtrlPt.getY(), endPt.getX(), endPt.getY()); if (selectStatus != SelectOptions.ALL) modified = true; }
@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); } } } }
public void setEndPts() { startBorderPts = startState.getBorderPts(); endBorderPts = endState.getBorderPts(); sPage = startState.getPage(); ePage = endState.getPage(); // TODO page connector stacking if (sPage != ePage && !stub) { int sOffset = drawArea.getOffset(sPage, startState, this, "start"); int eOffset = drawArea.getOffset(ePage, endState, this, "end"); int sBorderOffset = sOffset / 20; if (sBorderOffset < 0) sBorderOffset += 36; if (sBorderOffset > 35) sBorderOffset -= 36; int eBorderOffset = -eOffset / 20; if (eBorderOffset < -18) eBorderOffset += 36; if (eBorderOffset > 17) eBorderOffset -= 36; startPt = startBorderPts.get(0 + sBorderOffset); startCtrlPt = new Point((int) startPt.getX() + 20, (int) startPt.getY()); endPt = endBorderPts.get(18 + eBorderOffset); endCtrlPt = new Point((int) endPt.getX() - 20, (int) endPt.getY()); pageS = new Point(drawArea.getMaxW() - 50, (int) startPt.getY() + sOffset); pageSC = new Point(drawArea.getMaxW() - 70, (int) startPt.getY() + sOffset); pageE = new Point(50, (int) endPt.getY() + eOffset); pageEC = new Point(70, (int) endPt.getY() + eOffset); curve = new CubicCurve2D.Double(); } else if (stub) { // TODO // System.out.println("in stub loop, setendpts"); startPt = startBorderPts.get(0); startStateIndex = 0; pageS = new Point((int) startPt.getX() + 60, (int) startPt.getY()); len = 60; angle = 0; } else { Point startCoords = startState.getRealCenter(myPage); Point endCoords = endState.getRealCenter(myPage); double temp; double max = 1000000; for (int i = 0; i < 36; i++) { temp = startCoords.distanceSq(endBorderPts.get(i)); if (temp < max) { endStateIndex = i; max = temp; } } max = 1000000; for (int i = 0; i < 36; i++) { temp = endCoords.distanceSq(startBorderPts.get(i)); if (temp < max) { startStateIndex = i; max = temp; } } // try to prevent overlapping if (startCoords.getX() < endCoords.getX()) { if (startCoords.getY() < endCoords.getY()) { } else { } } else { if (startCoords.getY() < endCoords.getY()) { } else { } } startStateIndex -= 1; if (startStateIndex == -1) startStateIndex = 35; endStateIndex += 1; if (endStateIndex == 36) endStateIndex = 0; startPt = startBorderPts.get(startStateIndex); endPt = endBorderPts.get(endStateIndex); // SELECTION OF CONTROL POINTS // distances between states int dx = (int) startState.getRealCenter(myPage).getX() - (int) endState.getRealCenter(myPage).getX(); int dy = (int) startState.getRealCenter(myPage).getY() - (int) endState.getRealCenter(myPage).getY(); // scaling for distance of control point from start or end point int dxs = (int) (endPt.getX() - startPt.getX()) / 3; int dys = (int) (endPt.getY() - startPt.getY()) / 3; if (dxs < 0) dxs = -dxs; if (dys < 0) dys = -dys; // find angle between states double theta = 0; if (dx == 0) { if (dy <= 0) theta = Math.PI / 2; else theta = 3 * Math.PI / 2; } else if (dx > 0 && dy > 0) theta = 2 * Math.PI - Math.atan((double) dy / dx); else if (dx > 0 && dy <= 0) { if (dy == 0) theta = 0; else theta = -Math.atan((double) dy / (dx)); } else if (dx < 0) theta = Math.PI - Math.atan((double) dy / dx); // determine angle away from start point for start control point double adj = Math.PI / 6; double angleStart = 0; if (dx >= 0 && dy >= 0) angleStart = -Math.PI + theta + adj; // + else if (dx >= 0 && dy < 0) angleStart = Math.PI + theta + adj; // + else if (dx < 0 && dy >= 0) angleStart = -Math.PI + theta + adj; else if (dx < 0 && dy < 0) angleStart = Math.PI + theta + adj; // determine angle away from end point for end control point double angleEnd = 0; if (dx >= 0) angleEnd = theta - adj; else if (dx < 0) angleEnd = theta - adj; // create control point startCtrlPt = new Point( (int) (startPt.getX() + (Math.cos(angleStart) * dxs)), (int) (startPt.getY() - (Math.sin(angleStart) * dys))); endCtrlPt = new Point( (int) (endPt.getX() + (Math.cos(angleEnd) * dxs)), (int) (endPt.getY() - (Math.sin(angleEnd) * dys))); curve = new CubicCurve2D.Double( startPt.getX(), startPt.getY(), startCtrlPt.getX(), startCtrlPt.getY(), endCtrlPt.getX(), endCtrlPt.getY(), endPt.getX(), endPt.getY()); } }