KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > textarea > StructureMatcher


1 /*
2  * StructureMatcher.java - Abstract interface for bracket matching, etc.
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2003 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.textarea;
24
25 //{{{ Imports
26
import java.awt.*;
27 import org.gjt.sp.jedit.TextUtilities;
28 //}}}
29

30 /**
31  * An interface for matching parts of a source file's stucture. The default
32  * implementation matches brackets. The XML plugin provides an implementation
33  * for matching XML tags.
34  *
35  * @author Slava Pestov
36  * @version $Id: StructureMatcher.java 7156 2006-10-02 21:33:17Z kpouer $
37  * @since jEdit 4.2pre3
38  */

39 public interface StructureMatcher
40 {
41     //{{{ getMatch() method
42
/**
43      * Returns the element matching the one at the given text area's
44      * caret position, or null.
45      * @since jEdit 4.2pre3
46      */

47     Match getMatch(TextArea textArea);
48     //}}}
49

50     //{{{ selectMatch() method
51
/**
52      * Selects from the caret to the matching structure element (if there is
53      * one, otherwise the behavior of this method is undefined).
54      * @since jEdit 4.2pre3
55      */

56     void selectMatch(TextArea textArea);
57     //}}}
58

59     //{{{ BracketMatcher class
60
static class BracketMatcher implements StructureMatcher
61     {
62         public Match getMatch(TextArea textArea)
63         {
64             int offset = textArea.getCaretPosition()
65                 - textArea.getLineStartOffset(
66                 textArea.getCaretLine());
67
68             if(offset != 0)
69             {
70                 int bracketOffset = TextUtilities.findMatchingBracket(
71                     textArea.getBuffer(),
72                     textArea.getCaretLine(),
73                     offset - 1);
74                 if(bracketOffset != -1)
75                 {
76                     int bracketLine = textArea
77                         .getLineOfOffset(
78                         bracketOffset);
79                     return new Match(this,
80                         bracketLine,
81                         bracketOffset,
82                         bracketLine,
83                         bracketOffset + 1);
84                 }
85             }
86
87             return null;
88         }
89
90         public void selectMatch(TextArea textArea)
91         {
92             textArea.selectToMatchingBracket();
93         }
94     } //}}}
95

96     //{{{ Match class
97
/**
98      * A structure match, denoted by a start and end position.
99      * @since jEdit 4.2pre3
100      */

101     public static class Match
102     {
103         public StructureMatcher matcher;
104         public int startLine;
105         public int start;
106         public int endLine;
107         public int end;
108
109         public Match() {}
110
111         public Match(StructureMatcher matcher)
112         {
113             this.matcher = matcher;
114         }
115
116         public Match(StructureMatcher matcher, int startLine,
117             int start, int endLine, int end)
118         {
119             this(matcher);
120             this.startLine = startLine;
121             this.start = start;
122             this.endLine = endLine;
123             this.end = end;
124         }
125     } //}}}
126

127     //{{{ Highlight class
128
/**
129      * Paints the structure match highlight.
130      */

131     static class Highlight extends TextAreaExtension
132     {
133         Highlight(TextArea textArea)
134         {
135             this.textArea = textArea;
136         }
137
138         public void paintValidLine(Graphics2D gfx, int screenLine,
139             int physicalLine, int start, int end, int y)
140         {
141             if(!textArea.getPainter().isStructureHighlightEnabled())
142                 return;
143
144             Match match = textArea.getStructureMatch();
145             if(match != null)
146             {
147                 paintHighlight(gfx,screenLine,
148                     start,end,y,match);
149             }
150         }
151
152         private int[] getOffsets(int screenLine, Match match)
153         {
154             int x1, x2;
155
156             int matchStartLine = textArea.getScreenLineOfOffset(
157                 match.start);
158             int matchEndLine = textArea.getScreenLineOfOffset(
159                 match.end);
160
161             if(matchStartLine == screenLine)
162             {
163                 x1 = match.start;
164             }
165             else
166             {
167                 x1 = textArea.getScreenLineStartOffset(
168                     screenLine);
169             }
170
171             if(matchEndLine == screenLine)
172             {
173                 x2 = match.end;
174             }
175             else
176             {
177                 x2 = textArea.getScreenLineEndOffset(
178                     screenLine) - 1;
179             }
180
181             return new int[] {
182                 textArea.offsetToXY(x1).x,
183                 textArea.offsetToXY(x2).x
184             };
185         }
186     
187         private void paintHighlight(Graphics gfx, int screenLine,
188             int start, int end, int y,
189             Match match)
190         {
191             if(!textArea.isStructureHighlightVisible())
192                 return;
193
194             if(match.start >= end || match.end < start)
195             {
196                 return;
197             }
198
199             int matchStartLine = textArea.getScreenLineOfOffset(
200                 match.start);
201             int matchEndLine = textArea.getScreenLineOfOffset(
202                 match.end);
203
204             FontMetrics fm = textArea.getPainter().getFontMetrics();
205             int height = fm.getHeight();
206
207             int[] offsets = getOffsets(screenLine,match);
208             int x1 = offsets[0];
209             int x2 = offsets[1];
210
211             gfx.setColor(textArea.getPainter().getStructureHighlightColor());
212
213             gfx.drawLine(x1,y,x1,y + height - 1);
214             gfx.drawLine(x2,y,x2,y + height - 1);
215
216             if(matchStartLine == screenLine || screenLine == 0)
217                 gfx.drawLine(x1,y,x2,y);
218             else
219             {
220                 offsets = getOffsets(screenLine - 1,match);
221                 int prevX1 = offsets[0];
222                 int prevX2 = offsets[1];
223
224                 gfx.drawLine(Math.min(x1,prevX1),y,
225                     Math.max(x1,prevX1),y);
226                 gfx.drawLine(Math.min(x2,prevX2),y,
227                     Math.max(x2,prevX2),y);
228             }
229
230             if(matchEndLine == screenLine)
231             {
232                 gfx.drawLine(x1,y + height - 1,
233                     x2,y + height - 1);
234             }
235         }
236
237         private TextArea textArea;
238     } //}}}
239
}
240
Popular Tags