PseudoCodeRenderer.java 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package view;
  2. import java.awt.Color;
  3. import java.awt.Component;
  4. import java.awt.Font;
  5. import java.awt.Graphics2D;
  6. import java.awt.image.BufferedImage;
  7. import javax.swing.ImageIcon;
  8. import javax.swing.JTree;
  9. import javax.swing.tree.DefaultTreeCellRenderer;
  10. import javax.swing.tree.TreeNode;
  11. import animation.PseudoCodeNode;
  12. /**
  13. * A tree-like display of pseudocode.
  14. * Extends {@link DefaultTreeCellRenderer}
  15. * @author kolja
  16. *
  17. */
  18. public class PseudoCodeRenderer extends DefaultTreeCellRenderer {
  19. private static final long serialVersionUID = 1L;
  20. private static ImageIcon currentLine = new ImageIcon( PseudoCodeNode.class.getResource( "/img/current_line.png" ) );
  21. private Color specialColor = null;
  22. @Override
  23. public Color getBackgroundNonSelectionColor() {
  24. if(specialColor != null) {
  25. return specialColor;
  26. } else {
  27. return RenderHelper.BACKGROUND_COLOR;
  28. }
  29. }
  30. @Override
  31. public Color getForeground() {
  32. return new Color(0xa9b7c6);
  33. }
  34. private int countChildren( TreeNode treeNode )
  35. {
  36. if( treeNode.isLeaf() )
  37. return 0;
  38. else
  39. {
  40. int sum = 0;
  41. for( int i = 0; i < treeNode.getChildCount(); i++ )
  42. {
  43. sum += countChildren( treeNode.getChildAt( i ) ) + 1;
  44. }
  45. return sum;
  46. }
  47. }
  48. private int getLineNumber( TreeNode treeNode )
  49. {
  50. TreeNode parent = treeNode.getParent();
  51. if( parent == null )
  52. return 1;
  53. int sum = getLineNumber( parent ) + 1;
  54. for( int i = 0; i < parent.getChildCount(); i++ )
  55. {
  56. if( i == parent.getIndex( treeNode ) )
  57. return sum;
  58. sum += countChildren( parent.getChildAt( i ) ) + 1;
  59. }
  60. return 0;
  61. }
  62. @Override
  63. public Font getFont() {
  64. return new Font("Monospaced", Font.PLAIN, 12);
  65. }
  66. @Override
  67. public Component getTreeCellRendererComponent(JTree tree, Object value, boolean arg2, boolean arg3, boolean arg4, int arg5, boolean arg6) {
  68. PseudoCodeNode node = (PseudoCodeNode) value;
  69. int width = 10;
  70. if( !node.hasSelectedSubnode() && node.isSelected() )
  71. width += 25;
  72. if( node.hasBreakPoint() )
  73. width += 15;
  74. String line = "" + getLineNumber( (TreeNode) value );
  75. width += tree.getFontMetrics( this.getFont() ).stringWidth( line );
  76. BufferedImage rowNumerImg = new BufferedImage( width, 30, BufferedImage.TYPE_INT_ARGB );
  77. Graphics2D g = (Graphics2D) rowNumerImg.getGraphics();
  78. int x = 5;
  79. if( !node.hasSelectedSubnode() && node.isSelected() )
  80. {
  81. g.drawImage( currentLine.getImage(), x, 5, 20, 20, null );
  82. x += 25;
  83. }
  84. g.setColor( RenderHelper.CURRENT_LINE_COLOR );
  85. g.drawString( line, x, 20 );
  86. x += g.getFontMetrics().stringWidth( line ) + 5;
  87. if( node.hasBreakPoint() )
  88. {
  89. g.setColor( new Color (0xe7887a) );
  90. g.fillOval(x, 10, 10, 10 );
  91. }
  92. g.dispose();
  93. this.setClosedIcon( new ImageIcon( rowNumerImg ) );
  94. this.setOpenIcon( new ImageIcon( rowNumerImg ) );
  95. this.setLeafIcon( new ImageIcon( rowNumerImg ) );
  96. Component c = super.getTreeCellRendererComponent(tree, value, arg2, arg3, arg4, arg5, arg6);
  97. specialColor = null;
  98. if(node.isSelected()) {
  99. specialColor = new Color(0x2d6099);
  100. } else if (node.hasBreakPoint()) {
  101. specialColor = RenderHelper.BREAKPOINT_COLOR;
  102. }
  103. return c;
  104. }
  105. }