📄 treecanvas.java
字号:
ParseNode n= (ParseNode)t.getInfo(); FontMetrics m= g.getFontMetrics(g.getFont()); int h= m.getHeight(); Color c= nodeColor(n); String lab= n.getLabel(); boolean isSelected= (t == selectedNode); int w= m.stringWidth(lab); int a= m.getAscent(); int w1= (w < MIN_NODE_WIDTH) ? MIN_NODE_WIDTH : w; int xR= x - (int)((w1/2)*EXTRA_WIDTH); int yR= y; int wR= (int)(w1*EXTRA_WIDTH); int hR= (int)(h*EXTRA_HEIGHT); if (doShadow) { g.setColor(RECT_SHADOW_COLOR); g.fillRect(xR + (xR - SOURCE_X)*NODE_Z/(SOURCE_Z - NODE_Z), yR + (yR - SOURCE_Y)*NODE_Z/(SOURCE_Z - NODE_Z), wR, hR); } if (isSelected) { g.setColor(SELECT_COLOR); g.fillRect(xR - SELECT_WIDTH, yR - SELECT_WIDTH, wR + 2*SELECT_WIDTH, hR + 2*SELECT_WIDTH); } if (!t.getExpand()) { g.setColor(UNEXPAND_COLOR); g.fillRect(xR - SELECT_WIDTH, yR - SELECT_WIDTH, wR + 2*SELECT_WIDTH, hR + 2*SELECT_WIDTH); } g.setColor(c); g.fillRect(xR, yR, wR, hR); if (t.nKids() > 0) { int xR1= xR - hScroll.getValue(); int yR1= yR - vScroll.getValue(); locator.locatorRegister(new Rectangle(xR1, yR1, wR, hR), t); } g.setColor(TEXT_COLOR); g.drawString(lab, x - w/2, y + (int)(a * EXTRA_HEIGHT)); } private void drawTree(Graphics g, OffsetTree t, int x, int y, int minX, int minY, int maxX, int maxY) { if (y > maxY) return; FontMetrics m= g.getFontMetrics(g.getFont()); int h= m.getHeight(); if (x + colSep/2 >= minX && y + rowSep >= minY && x - colSep/2 <= maxX) { drawNode(g, t, x, y); } if (t.getExpand()) { for (int i= 0; i < t.nKids(); i++) { OffsetTree kid= (OffsetTree)t.kid(i); ParseNode kidNode= (ParseNode)kid.getInfo(); Color cKid= edgeColor(kidNode); int eX0= x; int eY0= y + (int)(h*EXTRA_HEIGHT); int eX1= x + kid.getOffset()*colSep; int eY1= y + rowSep; if (doShadow) { int eX0Offset= (eX0 - SOURCE_X)*EDGE_Z/(SOURCE_Z - EDGE_Z); int eY0Offset= (eY0 - SOURCE_Y)*EDGE_Z/(SOURCE_Z - EDGE_Z); int eX1Offset= (eX1 - SOURCE_X)*EDGE_Z/(SOURCE_Z - EDGE_Z); int eY1Offset= (eY1 - SOURCE_Y)*EDGE_Z/(SOURCE_Z - EDGE_Z); g.setColor(LINE_SHADOW_COLOR); g.drawLine(eX0 + eX0Offset, eY0 + eY0Offset, eX1 + eX1Offset, eY1 + eY1Offset); } g.setColor(cKid); g.drawLine(eX0, eY0, eX1, eY1); g.drawLine(eX0 + 1, eY0, eX1 + 1, eY1); drawTree(g, kid, x + kid.getOffset()*colSep, y + rowSep, minX, minY, maxX, maxY); } } //if (t.getExpand()) } private Color nodeColor(ParseNode n) { int nodeType= n.getType(); ParseNode mNode= (mouseNode == null) ? null : (ParseNode)mouseNode.getInfo(); ParseNode lastMNode= (mouseDownNode == null) ? null : (ParseNode)mouseDownNode.getInfo(); return (mNode == n) ? ((isMouseDown && n == lastMNode) ? MOUSE_DOWN_COLOR : MOUSE_IN_COLOR) : (nodeType == ParseNode.ERROR) ? ERROR_COLOR : (nodeType == ParseNode.TERM) ? TERM_COLOR : NON_TERM_COLOR;; } private Color edgeColor(ParseNode n) { int nodeType= n.getType(); return (nodeType == ParseNode.ERROR) ? ERROR_COLOR : (nodeType == ParseNode.TERM) ? TERM_COLOR : NON_TERM_COLOR;; } private Dimension minSize= new Dimension(200, 80); private Dimension prefSize= new Dimension(400, 1600); private GridLocator locator; private Rectangle mouseRect; private OffsetTree mouseNode; private OffsetTree mouseDownNode; private int rowLo= 0; private int colLo= 0; private OffsetForest forest; private OffsetTree selectedNode; private String hintMsg; //hint msg. to output on top of canvas. private Image hintBuf; //buffer for hint message. private Dimension hintBufDim; //dimensions of allocated hint buf. private boolean didSelect; private boolean isMouseDown; private boolean doShadow= true; private static final String TERM_HINT= "terminal"; private static final String NON_TERM_HINT= "non-terminal"; private static final String ERROR_HINT= "error"; private static final Color HINT_BG_COLOR= Color.yellow; private static final Color HINT_FG_COLOR= Color.black; private static final int HINT_SPACE= 20; private static final int HINT_Y_INSET= 3; private static final int FONTSIZE= 14; private static final int MIN_NODE_WIDTH= 20; private static final int TREE_SEP= 0; private static final double EXTRA_WIDTH= 1.2; private static final double EXTRA_HEIGHT= 1.2; private static final Color TERM_COLOR= Color.red; private static final Color NON_TERM_COLOR= Color.green; private static final Color ERROR_COLOR= Color.pink; private static final Color MOUSE_IN_COLOR= Color.lightGray; private static final Color MOUSE_DOWN_COLOR= Color.gray; private static final Color SELECT_COLOR= Color.yellow; private static final Color UNEXPAND_COLOR= Color.black; private static final int SELECT_WIDTH= 3; private static final Color TEXT_COLOR= Color.black; //Right-hand axes with Z increasing towards viewer. Canvas is at Z= 0. //Ensure light source is real far away, relative to object //distances so that all parts of the object have similar sized shadows. //Coordinates of light source. private static final int SOURCE_X= -10000; private static final int SOURCE_Y= -10000; //must be < 0 to overlay shadows. private static final int SOURCE_Z= 10000; private static final int NODE_Z= 8; //Nodes at plane z= NODE_Z private static final int EDGE_Z= 7; //Edges at plane z= EDGE_Z private static final int RECT_GRAY= 220; private static final int LINE_GRAY= 200; private static final Color RECT_SHADOW_COLOR= new Color(RECT_GRAY, RECT_GRAY, RECT_GRAY); private static final Color LINE_SHADOW_COLOR= new Color(LINE_GRAY, LINE_GRAY, LINE_GRAY); private int rowSep= 50; private int colSep= 100; /* Simple test program, basically tests addKid() and constructors. */ static public void main(String args[]) { OffsetForest forest= new OffsetForest(); OffsetTree t000= new OffsetTree(new ParseNode("A", 1)); OffsetTree t001= new OffsetTree(new ParseNode("B", 1)); OffsetTree t002= new OffsetTree(new ParseNode("C", 1)); OffsetTree t00= new OffsetTree(new ParseNode("D", 1), t000, t001, t002); t00.addKid(new OffsetTree(new ParseNode("E", 1))); t00.addKid(new OffsetTree(new ParseNode("F", 1), new OffsetTree(new ParseNode("G", 1))), 1); OffsetTree OffsetTrees[]= { t00, new OffsetTree(new ParseNode("H", 1), new OffsetTree(new ParseNode("I", 1)), new OffsetTree(new ParseNode("J", 1))), new OffsetTree(new ParseNode("K", 1)), new OffsetTree(new ParseNode("L", 1)) }; OffsetTree t0= new OffsetTree(new ParseNode("M", 1), OffsetTrees); forest.addElement(t0); OffsetTree prg= new OffsetTree(new ParseNode("program", 1)); OffsetTree stmts= new OffsetTree(new ParseNode("stmts", 1)); prg.addKid(stmts); OffsetTree assgnStmt= new OffsetTree(new ParseNode("assgn", 1)); stmts.addKid(assgnStmt); assgnStmt.addKid(new OffsetTree(new ParseNode("a", 1))); assgnStmt.addKid(new OffsetTree(new ParseNode(":=", 1))); OffsetTree expr= new OffsetTree(new ParseNode("expr", 1)); assgnStmt.addKid(expr); OffsetTree term= new OffsetTree(new ParseNode("term", 1)); expr.addKid(term); OffsetTree factor= new OffsetTree(new ParseNode("factor", 1)); term.addKid(factor); factor.addKid(new OffsetTree(new ParseNode("1", 1))); OffsetTree stmtsRest= new OffsetTree(new ParseNode("stmtsRest", 1)); stmts.addKid(stmtsRest); stmtsRest.addKid(new OffsetTree(new ParseNode(";", 1))); forest.addElement(prg); OffsetTree tStmts= new OffsetTree(new ParseNode("stmts", 0)); OffsetTree tAssgn= new OffsetTree(new ParseNode("assgn", 0)); tStmts.addKid(tAssgn); tAssgn.addKid(new OffsetTree(new ParseNode("a", 0))); tAssgn.addKid(new OffsetTree(new ParseNode(":=", 0))); OffsetTree tRestStmts= new OffsetTree(new ParseNode("restStmts", 0)); tStmts.addKid(tRestStmts); tRestStmts.addKid(new OffsetTree(new ParseNode(";", 0))); forest.addElement(tStmts); OffsetTree x= new OffsetTree(new ParseNode("stmts", 0), new OffsetTree(new ParseNode("assgnStmt", 0), new OffsetTree(new ParseNode("a", 0)), new OffsetTree(new ParseNode(":=", 0)), new OffsetTree(new ParseNode("expr", 0), new OffsetTree(new ParseNode("term", 0), new OffsetTree(new ParseNode("factor", 0), new OffsetTree(new ParseNode("1", 0)))))), new OffsetTree(new ParseNode(";", 0)), new OffsetTree(new ParseNode("stmts", 0), new OffsetTree(new ParseNode("assgnStmt", 0), new OffsetTree(new ParseNode("b", 0)), new OffsetTree(new ParseNode(":=", 0)), new OffsetTree(new ParseNode("expr", 0), new OffsetTree(new ParseNode("expr", 0), new OffsetTree(new ParseNode("term", 0), new OffsetTree(new ParseNode("factor", 0), new OffsetTree(new ParseNode("1", 0))))), new OffsetTree(new ParseNode("+", 0)), new OffsetTree(new ParseNode("term", 0), new OffsetTree(new ParseNode("factor", 0), new OffsetTree(new ParseNode("2", 0)))))))); forest.addElement(x); TreeCanvas treeCanvas= new TreeCanvas(200, 200, "Test tree"); treeCanvas.setForest(forest); Frame frame= new Frame("TreeCanvas Test"); frame.setLayout(new FlowLayout()); frame.add(treeCanvas.getComponent()); frame.resize(400, 400); frame.show(); treeCanvas.repaint(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -