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