001 package nl.cwi.sen1.tide.tool.srcviewer; 002 003 import java.awt.Color; 004 import java.awt.Dimension; 005 import java.awt.FontMetrics; 006 import java.awt.Graphics; 007 import java.awt.Polygon; 008 import java.awt.Rectangle; 009 import java.util.HashMap; 010 import java.util.Map; 011 012 import javax.swing.JComponent; 013 import javax.swing.JTextArea; 014 015 import nl.cwi.sen1.tide.tool.support.Rule; 016 017 class LineNumberCanvas extends JComponent { 018 private final static int BORDER = 2; 019 JTextArea text; 020 FontMetrics fontMetrics; 021 FontMetrics sourceMetrics; 022 023 int cpe; 024 025 Map<Rule, Integer> rulesByRule; 026 Map<Integer, Rule> rulesByLine; 027 028 Polygon rulePoly; 029 030 //{{{ public LineNumberCanvas(JTextArea text) 031 032 public LineNumberCanvas(JTextArea text) { 033 this.text = text; 034 rulesByRule = new HashMap<Rule, Integer>(); 035 rulesByLine = new HashMap<Integer, Rule>(); 036 } 037 038 //}}} 039 040 //{{{ private void checkMetrics() 041 042 private void checkMetrics() { 043 if (fontMetrics != getFontMetrics(getFont()) 044 || sourceMetrics != text.getFontMetrics(text.getFont())) { 045 fontMetrics = getFontMetrics(getFont()); 046 sourceMetrics = text.getFontMetrics(text.getFont()); 047 048 rulePoly = new Polygon(); 049 rulePoly.addPoint(0, 0); 050 rulePoly.addPoint( 051 fontMetrics.stringWidth("1999"), 052 sourceMetrics.getHeight() / 2); 053 rulePoly.addPoint(0, sourceMetrics.getHeight()); 054 } 055 } 056 057 //}}} 058 059 //{{{ public void paint(Graphics g) 060 061 public void paint(Graphics g) { 062 Dimension dim = getSize(); 063 Rectangle clip = g.getClipBounds(); 064 065 checkMetrics(); 066 067 g.setColor(getBackground()); 068 g.fillRect(clip.x, clip.y, clip.width, clip.height); 069 070 int line = clip.y / sourceMetrics.getHeight(); 071 int y = line * sourceMetrics.getHeight(); 072 line++; 073 074 while (y < (clip.y + clip.height)) { 075 if (line == cpe) { 076 g.setColor(SourceFileViewer.COLOR_CPE); 077 g.fillRect(0, y, clip.width, sourceMetrics.getHeight()); 078 } 079 080 Rule rule = rulesByLine.get(new Integer(line)); 081 if (rule != null) { 082 g.setColor(getRuleColor(rule)); 083 Polygon rulePoly = getRulePoly(rule); 084 rulePoly.translate(0, y); 085 g.fillPolygon(rulePoly); 086 rulePoly.translate(0, -y); 087 } 088 089 g.setColor(getForeground()); 090 String label = String.valueOf(line++); 091 g.drawString( 092 label, 093 dim.width - fontMetrics.stringWidth(label) - BORDER, 094 y + sourceMetrics.getMaxAscent()); 095 y += sourceMetrics.getHeight(); 096 } 097 098 } 099 100 //}}} 101 //{{{ public Dimension getPreferredSize() 102 103 public Dimension getPreferredSize() { 104 checkMetrics(); 105 106 return new Dimension(fontMetrics.stringWidth("1999") + BORDER, 0); 107 } 108 109 //}}} 110 //{{{ public Dimension getMinimumSize() 111 112 public Dimension getMinimumSize() { 113 return getPreferredSize(); 114 } 115 116 //}}} 117 118 //{{{ public void setCpe(int line) 119 120 public void setCpe(int line) { 121 cpe = line; 122 repaint(); 123 } 124 125 //}}} 126 //{{{ public void clearCpe() 127 128 public void clearCpe() { 129 cpe = -1; 130 repaint(); 131 } 132 133 //}}} 134 135 //{{{ public void addLocationRule(Rule rule, int line) 136 137 public void addLocationRule(Rule rule, int line) { 138 rulesByRule.put(rule, new Integer(line)); 139 rulesByLine.put(new Integer(line), rule); 140 } 141 142 //}}} 143 //{{{ public void removeLocationRule(Rule rule) 144 145 public void removeLocationRule(Rule rule) { 146 Integer line = rulesByRule.remove(rule); 147 if (line != null) { 148 rulesByLine.remove(line); 149 } 150 } 151 152 //}}} 153 154 //{{{ public Color getRuleColor(Rule rule) 155 156 public Color getRuleColor(Rule rule) { 157 if (rule.isBreakpoint()) { 158 return SourceFileViewer.COLOR_BREAKPOINT; 159 } 160 161 return SourceFileViewer.COLOR_WATCHPOINT; 162 } 163 164 //}}} 165 166 //{{{ public Polygon getRulePoly(Rule rule) 167 168 public Polygon getRulePoly(Rule rule) { 169 return rulePoly; 170 } 171 172 //}}} 173 174 }