001 /**
002 * Created by IntelliJ IDEA.
003 * User: Wei Wang
004 * Date: Jan 15, 2003
005 * Time: 1:10:46 PM
006 */
007
008 package EVolve.util.SourceBrowser;
009
010 import EVolve.Scene;
011 import javax.swing.*;
012 import javax.swing.event.*;
013 import java.io.*;
014 import java.awt.*;
015 import java.awt.event.*;
016 import java.util.ArrayList;
017
018 public class SourceBrowser {
019 private JInternalFrame window;
020 private JDesktopPane desktop;
021 private String target;
022 private ArrayList textBuffer;
023 private int line_no = 0;
024 private int caretPosition = 0;
025 private JPopupMenu popup;
026 private JMenuItem itemFind, itemFindNext, itemFindPrevious;
027 private JTextArea textArea;
028 private String loadedFilename;
029
030 public SourceBrowser() {
031 window = null;
032 desktop = Scene.getUIManager().getDesktop();
033 textBuffer = new ArrayList();
034 popup = new JPopupMenu();
035 loadedFilename = null;
036
037 itemFind = new JMenuItem("Find...");
038 itemFind.setMnemonic(KeyEvent.VK_F);
039 itemFind.addActionListener(new ActionListener() {
040 public void actionPerformed(ActionEvent e) {
041 target = (String)JOptionPane.showInputDialog(Scene.getFrame(), "Input string to be find:", "Find...", JOptionPane.QUESTION_MESSAGE, null, null, target);
042 caretPosition = 0;
043 find(target, 0, textBuffer.size(),false);
044 }
045 });
046 popup.add(itemFind);
047
048 itemFindNext = new JMenuItem("Find Next");
049 itemFindNext.setMnemonic(KeyEvent.VK_N);
050 itemFindNext.addActionListener(new ActionListener() {
051 public void actionPerformed(ActionEvent e) {
052 findNext(target);
053 }
054 });
055 popup.add(itemFindNext);
056
057 itemFindPrevious = new JMenuItem("Find Previous");
058 itemFindPrevious.setMnemonic(KeyEvent.VK_P);
059 itemFindPrevious.addActionListener(new ActionListener() {
060 public void actionPerformed(ActionEvent e) {
061 findPrevious(target);
062 }
063 });
064 popup.add(itemFindPrevious);
065 }
066
067 public void showSourceFile(String entityName) {
068 if (entityName == null) return;
069
070 String className = extractClassName(entityName);
071 String fileName = ClassExplorer.v().getSourceFileFromClass(className);
072
073 if (fileName == null) {
074 return;
075 }
076
077 if (window == null) {
078 window = new JInternalFrame(entityName,true, true, true, true);
079 window.addInternalFrameListener(new InternalFrameAdapter() {
080 public void internalFrameClosing(InternalFrameEvent e) {
081 window = null;
082 }
083 });
084 window.setClosable(true);
085 window.setBounds(desktop.getSize().width - 600, 0, 600, 300);
086 window.setResizable(true);
087 desktop.add(window);
088 textArea = new JTextArea();
089 }
090 window.moveToFront();
091 window.setVisible(true);
092 if (fileName.equals(loadedFilename)) {
093 int position = find(target,0,textBuffer.size(),true);
094 textArea.setCaretPosition(position);
095 } else {
096 window.getContentPane().removeAll();
097 window.getContentPane().add(loadSourceFile(fileName));
098 }
099 window.setTitle(entityName);
100 }
101
102 private JScrollPane loadSourceFile(String fileName) {
103 textArea = new JTextArea();
104 line_no = 0;
105
106 try {
107 RandomAccessFile file = new RandomAccessFile(fileName,"r");
108 textBuffer.clear();
109
110 String line = file.readLine();
111 while (line!=null) {
112 textBuffer.add(line + "\n");
113 textArea.append(line + "\n");
114 line = file.readLine();
115 }
116 caretPosition = 0;
117 int position = find(target,0,textBuffer.size(),true);
118 if (position!=-1) textArea.setCaretPosition(position);
119 addPopupTrigger(textArea);
120 } catch (IOException e) {
121 Scene.showErrorMessage("Error occurred when accessing source file:\n" +
122 "\""+fileName+"\".");
123 }
124
125
126 return new JScrollPane(textArea);
127 }
128
129 private String extractClassName(String entityName) {
130 int index = entityName.lastIndexOf('(');
131 target = "";
132
133 if (index == -1) {
134 /* no '(' found, this is not a method/location entity */
135 return entityName;
136 }
137 String className = entityName.substring(0,index);
138 index = className.lastIndexOf('.');
139
140 if (index != -1) {
141 className = entityName.substring(0,index);
142 target = entityName.substring(index+1,entityName.indexOf('('));
143 }
144
145 return className;
146 }
147
148 private boolean isEntity(String line) {
149 if ((line!=null)&&(line.indexOf('(')!=-1))
150 //&&
151 //((line.indexOf("public") != -1) ||
152 //(line.indexOf("private") != -1) ||
153 //(line.indexOf("protected") != -1))) {
154 {
155 return true;
156 }
157
158 return false;
159 }
160
161 private int find(String target, int start_line_no, int end_line_no, boolean target_is_entity) {
162 String line;
163 boolean found = false;
164
165 for (int i=start_line_no; i<end_line_no; i++) {
166 line = (String)textBuffer.get(i);
167 if ((line.indexOf(target) != -1) && ((!target_is_entity) || isEntity(line))) {
168 found = true;
169 line_no = i;
170 textArea.setCaretPosition(caretPosition);
171 break;
172 }
173 caretPosition += line.length();
174 }
175
176 if (!found) {
177 Scene.showErrorMessage("String \""+target+"\" is not found.");
178 }
179
180 return found ? caretPosition : -1;
181 }
182
183 private int findNext(String target) {
184 caretPosition = 0;
185
186 for (int i=0; i<=line_no; i++) {
187 caretPosition += ((String)textBuffer.get(i)).length();
188 }
189
190 return find(target, line_no+1, textBuffer.size(), false);
191 }
192
193 private int findPrevious(String target) {
194 String line;
195 boolean found = false;
196
197 caretPosition = 0;
198
199 for (int i=0; i<line_no-1; i++) {
200 caretPosition += ((String)textBuffer.get(i)).length();
201 }
202
203 for (int i=line_no - 1; i>=0; i--) {
204 line = (String)textBuffer.get(i);
205 if (line.indexOf(target) != -1) {
206 found = true;
207 textArea.setCaretPosition(caretPosition);
208 line_no = i;
209 break;
210 }
211 caretPosition -= line.length();
212 }
213
214 if (!found) {
215 Scene.showErrorMessage("String \""+target+"\" is not found.");
216 }
217
218 return found ? caretPosition : -1;
219 }
220
221 protected void addPopupTrigger(Component component) {
222 component.addMouseListener(new MouseAdapter() {
223 public void mouseReleased(MouseEvent e) {
224 if (e.isPopupTrigger()) {
225 showPopup(e);
226 }
227 }
228
229 public void mousePressed(MouseEvent e) {
230 if (e.isPopupTrigger()) {
231 showPopup(e);
232 }
233 }
234 });
235 }
236
237 private void showPopup(MouseEvent e) {
238 int mouseX = e.getX();
239 int mouseY = e.getY();
240 Rectangle rect = e.getComponent().getBounds();
241 Rectangle rect2 = popup.getBounds();
242 int posX= mouseX, posY = mouseY;
243 if (mouseY+rect2.height > rect.height)
244 posY = posY - rect2.height;
245 if (mouseX+rect2.width>rect.width)
246 posX = posX - rect2.width;
247 popup.show(e.getComponent(), posX, posY);
248 }
249 }