1 33 34 package edu.rice.cs.drjava.ui; 35 36 import javax.swing.*; 37 import javax.swing.event.*; 38 import javax.swing.text.*; 39 import javax.swing.border.*; 40 import java.awt.event.*; 41 import java.awt.*; 42 import java.io.ByteArrayOutputStream ; 43 44 import edu.rice.cs.drjava.DrJava; 45 import edu.rice.cs.util.UnexpectedException; 46 import edu.rice.cs.util.StringOps; 47 import edu.rice.cs.util.swing.BorderlessScrollPane; 48 import edu.rice.cs.drjava.platform.PlatformFactory; 49 50 56 public class DrJavaErrorWindow extends JDialog { 57 58 public static final String SF_ADD_BUG_URL = "http://sourceforge.net/tracker/?func=add&group_id=44253&atid=438935/"; 59 60 61 public static final String SF_LINK_NAME = "http://sourceforge.net/projects/drjava"; 62 63 64 private volatile JEditorPane _errorInfo; 65 66 private final JTextArea _stackTrace; 67 68 private final JLabel _indexLabel; 69 70 private final JScrollPane _stackTraceScroll; 71 72 private final JPanel _bottomPanel; 73 74 private final JPanel _buttonPanel; 75 76 private final JButton _copyButton; 77 78 private final JButton _okButton; 79 80 private final JButton _nextButton; 81 82 private final JButton _prevButton; 83 84 private final JButton _dismissButton; 85 86 private volatile int _errorCount; 87 88 private volatile Throwable _error; 89 90 private volatile int _errorIndex; 91 92 private static volatile JFrame _parentFrame = new JFrame(); 93 94 private static volatile boolean _parentChanged = true; 95 96 97 public static void setFrame(JFrame f) { _parentFrame = f; _parentChanged = true; } 98 99 100 public static JFrame getFrame() { return _parentFrame; } 101 102 103 private static volatile DrJavaErrorWindow _singletonInstance; 104 105 106 public static DrJavaErrorWindow singleton() { 107 if (_parentChanged) { 108 synchronized(DrJavaErrorWindow.class) { 109 if (_parentChanged) { 110 _singletonInstance = new DrJavaErrorWindow(); 111 _parentChanged = false; 112 } 113 } 114 } 115 return _singletonInstance; 116 } 117 118 119 private DrJavaErrorWindow() { 120 super(_parentFrame, "DrJava Errors"); 121 122 this.setSize(600,400); 123 124 _stackTrace = new JTextArea(); 127 _stackTrace.setEditable(false); 128 129 _prevButton = new JButton(_prevAction); 130 _nextButton = new JButton(_nextAction); 131 _copyButton = new JButton(_copyAction); 132 _dismissButton = new JButton(_dismissAction); 133 _okButton = new JButton(_okAction); 134 135 _bottomPanel = new JPanel(new BorderLayout()); 136 _buttonPanel = new JPanel(); 137 _buttonPanel.add(_prevButton); 138 _buttonPanel.add(_nextButton); 139 _buttonPanel.add(_copyButton); 140 _buttonPanel.add(_dismissButton); 141 _buttonPanel.add(_okButton); 142 _indexLabel = new JLabel(); 143 _bottomPanel.add(_indexLabel, BorderLayout.CENTER); 144 _bottomPanel.add(_buttonPanel, BorderLayout.EAST); 145 146 _stackTraceScroll = new BorderlessScrollPane(_stackTrace, 147 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 148 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 149 _errorInfo = _errorInfo = new JEditorPane("text/html", HEADER_HTML+NO_ERRORS_HTML); 150 _errorInfo.setEditable(false); 151 _errorInfo.setBackground(getContentPane().getBackground()); 152 final JPanel cp = new JPanel(new BorderLayout(5,5)); 153 cp.setBorder(new EmptyBorder(5,5,5,5)); 154 setContentPane(cp); 155 cp.add(_errorInfo, BorderLayout.NORTH); 156 cp.add(_stackTraceScroll, BorderLayout.CENTER); 157 cp.add(_bottomPanel, BorderLayout.SOUTH); 158 getRootPane().setDefaultButton(_okButton); 159 init(); 160 } 161 162 163 public void setVisible(boolean b) { 164 if (b) { 165 init(); 166 } 167 super.setVisible(b); 168 } 169 170 171 private void init() { 172 _errorCount = DrJavaErrorHandler.getErrorCount(); 173 if (_errorCount>0) { 174 _error = DrJavaErrorHandler.getError(0); 175 _errorIndex = 0; 176 } 177 else { 178 _error = null; 179 _errorIndex = -1; 180 } 181 _prevAction.setEnabled(false); 182 _nextAction.setEnabled(_errorCount>1); 183 _dismissAction.setEnabled(_errorCount>0); 184 _copyAction.setEnabled(_errorCount>0); 185 updateErrorInfo(); 186 } 187 188 189 private void updateErrorInfo() { 190 getContentPane().remove(_errorInfo); 191 if (_error!=null) { 192 final StringBuilder b = new StringBuilder (); 193 if (_error instanceof DrJavaErrorHandler.LoggedCondition) { 194 b.append("Logged condition: "); 195 b.append(_error.getMessage()); 196 b.append('\n'); 197 boolean first = true; 198 for (StackTraceElement ste: _error.getStackTrace()) { 199 if (first) { first = false; continue; } 200 b.append("\tat "); 201 b.append(ste); 202 b.append('\n'); 203 } 204 } 205 else { 206 b.append(StringOps.getStackTrace(_error)); 207 if (_error instanceof UnexpectedException) { 208 Throwable t = ((UnexpectedException)_error).getCause(); 209 b.append("\nCaused by:\n"); 210 b.append(StringOps.getStackTrace(t)); 211 } 212 } 213 214 b.append("\n\n"); 215 b.append(getSystemAndDrJavaInfo()); 216 217 _stackTrace.setText(b.toString()); 218 _stackTrace.setCaretPosition(0); 219 220 final StringBuilder b2 = new StringBuilder (); 221 b2.append(HEADER_HTML); 222 b2.append(_errorCount); 223 b2.append(" error"); 224 b2.append(((_errorCount>1)?"s":"")); 225 b2.append(" occured!<br>"); 226 b2.append(ERRORS_FOOTER_HTML); 227 _errorInfo = new JEditorPane("text/html", b2.toString()); 228 _errorInfo.addHyperlinkListener(new HyperlinkListener() { 229 public void hyperlinkUpdate(HyperlinkEvent e) { 230 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 231 try { 232 PlatformFactory.ONLY.openURL(e.getURL()); 233 } catch(Exception ex) { } 234 } 235 } 236 }); 237 _errorInfo.setEditable(false); 238 _errorInfo.setBackground(getContentPane().getBackground()); 239 _indexLabel.setText("Error "+(_errorIndex+1)+" of "+(_errorCount)); 240 } 241 else { 242 _errorInfo = new JEditorPane("text/html", HEADER_HTML+NO_ERRORS_HTML); 243 _errorInfo.addHyperlinkListener(new HyperlinkListener() { 244 public void hyperlinkUpdate(HyperlinkEvent e) { 245 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 246 try { 247 PlatformFactory.ONLY.openURL(e.getURL()); 248 } catch(Exception ex) { } 249 } 250 } 251 }); 252 _errorInfo.setEditable(false); 253 _errorInfo.setBackground(getContentPane().getBackground()); 254 _stackTrace.setText(""); 255 _indexLabel.setText(""); 256 } 257 getContentPane().add(_errorInfo, BorderLayout.NORTH); 258 validate(); 259 } 260 261 264 public static String getSystemAndDrJavaInfo() { 265 final StringBuilder b = new StringBuilder (); 266 b.append("System Properties:\n"); 267 b.append("DrJava Version "); 268 b.append(edu.rice.cs.drjava.Version.getBuildTimeString()); 269 b.append('\n'); 270 java.util.Properties props = System.getProperties(); 271 int size = props.size(); 272 java.util.Iterator entries = props.entrySet().iterator(); 273 while(entries.hasNext()) { 274 java.util.Map.Entry entry = (java.util.Map.Entry)entries.next(); 275 b.append(entry.getKey()); 276 b.append(" = "); 277 if (entry.getKey().equals("line.separator")) { 278 b.append("\""); 279 String ls = (String )entry.getValue(); 280 for(int i=0; i<ls.length(); ++i) { 281 int ch = ls.charAt(i); 282 b.append("\\u"); 283 String hexString = "0000" + Integer.toHexString(ch); 284 b.append(hexString.substring(hexString.length()-4)); 285 } 286 b.append("\""); 287 } 288 else { 289 b.append(entry.getValue()); 290 } 291 b.append('\n'); 292 } 293 b.append('\n'); 294 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 295 try { 296 DrJava.getConfig().saveConfiguration(baos, "DrJava configuration file"); 297 b.append(baos.toString()); 298 } 299 catch(java.io.IOException ioe) { 300 b.append("IOException when trying to print DrJava configuration file"); 301 } 302 303 b.append("\n\nUsed memory: about "); 304 b.append(StringOps.memSizeToString(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())); 305 b.append("\nFree memory: about "); 306 b.append(StringOps.memSizeToString(Runtime.getRuntime().freeMemory())); 307 b.append("\nTotal memory: about "); 308 b.append(StringOps.memSizeToString(Runtime.getRuntime().totalMemory())); 309 b.append("\nTotal memory can expand to: about "); 310 b.append(StringOps.memSizeToString(Runtime.getRuntime().maxMemory())); 311 b.append("\n\n"); 312 313 String infoText = b.toString(); 315 316 String userHome = System.getProperty("user.home"); 317 String anonUserHome = "<anonymized user.home>"; 318 infoText = replaceString(infoText, userHome, anonUserHome); 319 320 String userDir = System.getProperty("user.dir"); 321 String anonUserDir = "<anonymized user.dir>"; 322 infoText = replaceString(infoText, userDir, anonUserDir); 323 324 String userName = System.getProperty("user.name"); 325 String anonUserName = "<anonymized user.name>"; 326 infoText = replaceString(infoText, userName, anonUserName); 327 328 return infoText; 329 } 330 331 332 private final Action _okAction = new AbstractAction("OK") { 333 public void actionPerformed(ActionEvent e) { 334 DrJavaErrorWindow.this.dispose(); 335 } 336 }; 337 338 339 private final Action _prevAction = new AbstractAction("Previous") { 340 public void actionPerformed(ActionEvent e) { 341 if (_errorIndex>0) { 342 --_errorIndex; 343 _error = DrJavaErrorHandler.getError(_errorIndex); 344 if (_errorIndex==0) { setEnabled(false); } 345 if (_errorCount>1) { _nextAction.setEnabled(true); } 346 updateErrorInfo(); 347 } 348 } 349 }; 350 351 352 private static String replaceString(String text, String orig, String repl) { 353 int pos = 0; 354 while((pos=text.indexOf(orig,pos))>=0) { 355 text = text.substring(0,pos) + repl + text.substring(pos+orig.length(), text.length()); 357 } 358 return text; 359 } 360 361 362 private final Action _nextAction = new AbstractAction("Next") { 363 public void actionPerformed(ActionEvent e) { 364 if (_errorIndex<_errorCount-1) { 365 ++_errorIndex; 366 _error = DrJavaErrorHandler.getError(_errorIndex); 367 if (_errorIndex==_errorCount-1) { setEnabled(false); } 368 if (_errorCount>1) { _prevAction.setEnabled(true); } 369 updateErrorInfo(); 370 } 371 } 372 }; 373 374 375 private Action _dismissAction = new AbstractAction("Dismiss") { 376 public void actionPerformed(ActionEvent e) { 377 DrJavaErrorHandler.clearErrors(); 378 _errorCount = 0; 379 _error = null; 380 _errorIndex = -1; 381 setEnabled(false); 382 _prevAction.setEnabled(false); 383 _nextAction.setEnabled(false); 384 _copyAction.setEnabled(false); 385 updateErrorInfo(); 386 JButton errorsButton = DrJavaErrorHandler.getButton(); 387 if (errorsButton!=null) { errorsButton.setVisible(false); } 388 _okAction.actionPerformed(e); 389 } 390 }; 391 392 393 private Action _copyAction = new AbstractAction("Copy This Error") { 394 public void actionPerformed(ActionEvent e) { 395 _stackTrace.grabFocus(); 396 _stackTrace.getActionMap().get(DefaultEditorKit.selectAllAction).actionPerformed(e); 397 _stackTrace.getActionMap().get(DefaultEditorKit.copyAction).actionPerformed(e); 398 } 399 }; 400 401 404 private final String HEADER_HTML = 405 "<html><font size=\"-1\" face=\"sans-serif, Arial, Helvetica, Geneva\"><b>"; 406 private final String ERRORS_FOOTER_HTML = 407 "Please submit a bug report containing the information below " + 408 "and an account of the actions that caused the bug (if known) to " + 409 "<a HREF=\"" + SF_ADD_BUG_URL + "\"><b>" + SF_LINK_NAME + "</b></a>.<br>" + 410 "You may wish to save all your work and restart DrJava.<br>" + 411 "Thanks for your help in making DrJava better!</b></font></p></html>"; 412 private final String NO_ERRORS_HTML = 413 "No errors occurred!<br>" + 414 "Thanks for using DrJava!</b></font></p></html>"; 415 } | Popular Tags |