package view; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JTree; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeNode; import animation.PseudoCodeNode; /** * A tree-like display of pseudocode. * Extends {@link DefaultTreeCellRenderer} * @author kolja * */ public class PseudoCodeRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = 1L; private static ImageIcon currentLine = new ImageIcon( PseudoCodeNode.class.getResource( "/img/current_line.png" ) ); private Color specialColor = null; @Override public Color getBackgroundNonSelectionColor() { if(specialColor != null) { return specialColor; } else { return RenderHelper.BACKGROUND_COLOR; } } @Override public Color getForeground() { return new Color(0xa9b7c6); } private int countChildren( TreeNode treeNode ) { if( treeNode.isLeaf() ) return 0; else { int sum = 0; for( int i = 0; i < treeNode.getChildCount(); i++ ) { sum += countChildren( treeNode.getChildAt( i ) ) + 1; } return sum; } } private int getLineNumber( TreeNode treeNode ) { TreeNode parent = treeNode.getParent(); if( parent == null ) return 1; int sum = getLineNumber( parent ) + 1; for( int i = 0; i < parent.getChildCount(); i++ ) { if( i == parent.getIndex( treeNode ) ) return sum; sum += countChildren( parent.getChildAt( i ) ) + 1; } return 0; } @Override public Font getFont() { return new Font("Monospaced", Font.PLAIN, 12); } @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean arg2, boolean arg3, boolean arg4, int arg5, boolean arg6) { PseudoCodeNode node = (PseudoCodeNode) value; int width = 10; if( !node.hasSelectedSubnode() && node.isSelected() ) width += 25; if( node.hasBreakPoint() ) width += 15; String line = "" + getLineNumber( (TreeNode) value ); width += tree.getFontMetrics( this.getFont() ).stringWidth( line ); BufferedImage rowNumerImg = new BufferedImage( width, 30, BufferedImage.TYPE_INT_ARGB ); Graphics2D g = (Graphics2D) rowNumerImg.getGraphics(); int x = 5; if( !node.hasSelectedSubnode() && node.isSelected() ) { g.drawImage( currentLine.getImage(), x, 5, 20, 20, null ); x += 25; } g.setColor( RenderHelper.CURRENT_LINE_COLOR ); g.drawString( line, x, 20 ); x += g.getFontMetrics().stringWidth( line ) + 5; if( node.hasBreakPoint() ) { g.setColor( new Color (0xe7887a) ); g.fillOval(x, 10, 10, 10 ); } g.dispose(); this.setClosedIcon( new ImageIcon( rowNumerImg ) ); this.setOpenIcon( new ImageIcon( rowNumerImg ) ); this.setLeafIcon( new ImageIcon( rowNumerImg ) ); Component c = super.getTreeCellRendererComponent(tree, value, arg2, arg3, arg4, arg5, arg6); specialColor = null; if(node.isSelected()) { specialColor = new Color(0x2d6099); } else if (node.hasBreakPoint()) { specialColor = RenderHelper.BREAKPOINT_COLOR; } return c; } }