DrJavaErrorWindow.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
edu.rice.cs.drjava.ui |
![]() |
![]() |
DrJava |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
| Metric | Description | |
|---|---|---|
/*BEGIN_COPYRIGHT_BLOCK
*
* Copyright (c) 2001-2008, JavaPLT group at Rice University (drjava@rice.edu)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software is Open Source Initiative approved Open Source Software.
* Open Source Initative Approved is a trademark of the Open Source Initiative.
*
* This file is part of DrJava. Download the current version of this project
* from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
*
* END_COPYRIGHT_BLOCK*/
package edu.rice.cs.drjava.ui;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import edu.rice.cs.drjava.DrJava;
import edu.rice.cs.util.UnexpectedException;
import edu.rice.cs.util.StringOps;
import edu.rice.cs.util.swing.BorderlessScrollPane;
import edu.rice.cs.drjava.platform.PlatformFactory;
import edu.rice.cs.plt.lambda.Runnable1;
import edu.rice.cs.plt.lambda.LambdaUtil;
/** Displays uncaught exceptions and logged conditions.
* This window is not automatically updated when new errors occur. In the case of errors, we want to
* minimize the effects on the GUI. If we want to see an updated dialog, we can click on the "DrJava Errors"
* button again.
* @version $Id: DrJavaErrorWindow.java 4633 2008-08-07 21:12:30Z dlsmith $
*/
public class DrJavaErrorWindow extends JDialog {
/** Sourceforge add bug URL */
public static final String SF_ADD_BUG_URL = "http://sourceforge.net/tracker/?func=add&group_id=44253&atid=438935/";
/** Sourceforge URL */
public static final String SF_LINK_NAME = "http://sourceforge.net/projects/drjava";
/** information about the error */
private volatile JEditorPane _errorInfo;
/** contains the stack trace */
private final JTextArea _stackTrace;
/** label with index */
private final JLabel _indexLabel;
/** scroll pane for _stackTrace */
private final JScrollPane _stackTraceScroll;
/** compresses the buttonPanel into the east */
private final JPanel _bottomPanel;
/** contains the butons */
private final JPanel _buttonPanel;
/** the button that copies the stack trace to the clipboard */
private final JButton _copyButton;
/** the button that closes this window */
private final JButton _okButton;
/** the button that moves to the next error */
private final JButton _nextButton;
/** the button that moves to the previous error */
private final JButton _prevButton;
/** the button that clears all errors and closes the window */
private final JButton _dismissButton;
/** the number of errors that had occurred */
private volatile int _errorCount;
/** the currently selected error */
private volatile Throwable _error;
/** the currently selected error index */
private volatile int _errorIndex;
/** the parent frame */
private static volatile JFrame _parentFrame = null;
/** true if parent changed since last singleton() call */
private static volatile boolean _parentChanged = true;
/** Sets the parent frame. */
public static void setFrame(JFrame f) { _parentFrame = f; _parentChanged = true; }
/** Gets the parent frame. */
public static JFrame getFrame() { return _parentFrame; }
/** The singleton instance of this dialog. */
private static volatile DrJavaErrorWindow _singletonInstance;
/** Returns the singleton instance. Recreates it if necessary. */
public static DrJavaErrorWindow singleton() {
if (_parentChanged) {
synchronized(DrJavaErrorWindow.class) {
if (_parentChanged) {
_singletonInstance = new DrJavaErrorWindow();
_parentChanged = false;
}
}
}
return _singletonInstance;
}
/** Creates a window to graphically display the errors that have occurred in the code of DrJava. */
private DrJavaErrorWindow() {
super(_parentFrame, "DrJava Errors");
this.setSize(600,400);
// If we set this pane to be of type text/rtf, it wraps based on words
// as opposed to based on characters.
_stackTrace = new JTextArea();
_stackTrace.setEditable(false);
_prevButton = new JButton(_prevAction);
_nextButton = new JButton(_nextAction);
_copyButton = new JButton(_copyAction);
_dismissButton = new JButton(_dismissAction);
_okButton = new JButton(_okAction);
_bottomPanel = new JPanel(new BorderLayout());
_buttonPanel = new JPanel();
_buttonPanel.add(_prevButton);
_buttonPanel.add(_nextButton);
_buttonPanel.add(_copyButton);
_buttonPanel.add(_dismissButton);
_buttonPanel.add(_okButton);
_indexLabel = new JLabel();
_bottomPanel.add(_indexLabel, BorderLayout.CENTER);
_bottomPanel.add(_buttonPanel, BorderLayout.EAST);
_stackTraceScroll = new BorderlessScrollPane(_stackTrace,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
_errorInfo = new JEditorPane("text/html", HEADER_HTML+NO_ERRORS_HTML);
_errorInfo.setEditable(false);
_errorInfo.setBackground(getContentPane().getBackground());
final JPanel cp = new JPanel(new BorderLayout(5,5));
cp.setBorder(new EmptyBorder(5,5,5,5));
setContentPane(cp);
cp.add(_errorInfo, BorderLayout.NORTH);
cp.add(_stackTraceScroll, BorderLayout.CENTER);
cp.add(_bottomPanel, BorderLayout.SOUTH);
getRootPane().setDefaultButton(_okButton);
init();
}
protected WindowAdapter _windowListener = new WindowAdapter() {
public void windowDeactivated(WindowEvent we) {
DrJavaErrorWindow.this.toFront();
}
public void windowClosing(WindowEvent we) {
DrJavaErrorWindow.this.dispose();
if (DrJavaErrorHandler.getButton()==null) { System.exit(1); }
}
};
/** Lambda that calls _cancel. */
protected final Runnable1<WindowEvent> CANCEL = new Runnable1<WindowEvent>() {
public void run(WindowEvent e) {
if (DrJavaErrorHandler.getButton()==null) { System.exit(1); }
}
};
/** Validates before changing visibility. Only runs in the event thread.
* @param vis true if frame should be shown, false if it should be hidden.
*/
public void setVisible(boolean vis) {
assert EventQueue.isDispatchThread();
validate();
if (vis) {
init();
if (_parentFrame!=null) {
edu.rice.cs.drjava.DrJavaRoot.installModalWindowAdapter(this, LambdaUtil.NO_OP, CANCEL);
}
toFront();
}
else {
if (_parentFrame!=null) {
edu.rice.cs.drjava.DrJavaRoot.removeModalWindowAdapter(this);
_parentFrame.toFront();
}
}
super.setVisible(vis);
}
/** Initialize the dialog. */
private void init() {
_errorCount = DrJavaErrorHandler.getErrorCount();
if (_errorCount>0) {
_error = DrJavaErrorHandler.getError(0);
_errorIndex = 0;
}
else {
_error = null;
_errorIndex = -1;
}
_prevAction.setEnabled(false);
_nextAction.setEnabled(_errorCount>1);
_dismissAction.setEnabled(_errorCount>0);
_copyAction.setEnabled(_errorCount>0);
updateErrorInfo();
}
/** Update the buttons and text area after next or previous. */
private void updateErrorInfo() {
getContentPane().remove(_errorInfo);
if (_error != null) {
final StringBuilder b = new StringBuilder();
if (_error instanceof DrJavaErrorHandler.LoggedCondition) {
b.append("Logged condition: ");
b.append(_error.getMessage());
b.append('\n');
boolean first = true;
for (StackTraceElement ste: _error.getStackTrace()) {
if (first) { first = false; continue; /* skip first frame, that's the log method itself */ }
b.append("\tat ");
b.append(ste);
b.append('\n');
}
}
else {
b.append(StringOps.getStackTrace(_error));
if (_error instanceof UnexpectedException) {
Throwable t = ((UnexpectedException)_error).getCause();
b.append("\nCaused by:\n");
b.append(StringOps.getStackTrace(t));
}
}
b.append("\n\n");
b.append(getSystemAndDrJavaInfo());
_stackTrace.setText(b.toString());
_stackTrace.setCaretPosition(0);
final StringBuilder b2 = new StringBuilder();
b2.append(HEADER_HTML);
b2.append(_errorCount);
b2.append(" error");
b2.append(((_errorCount>1)?"s":""));
b2.append(" occured!<br>");
b2.append(ERRORS_FOOTER_HTML);
_errorInfo = new JEditorPane("text/html", b2.toString());
_errorInfo.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
try {
PlatformFactory.ONLY.openURL(e.getURL());
} catch(Exception ex) { /* ignore, just not open web page */ }
}
}
});
_errorInfo.setEditable(false);
_errorInfo.setBackground(getContentPane().getBackground());
_indexLabel.setText("Error "+(_errorIndex+1)+" of "+(_errorCount));
}
else {
_errorInfo = new JEditorPane("text/html", HEADER_HTML+NO_ERRORS_HTML);
_errorInfo.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
try {
PlatformFactory.ONLY.openURL(e.getURL());
} catch(Exception ex) { /* ignore, just not open web page */ }
}
}
});
_errorInfo.setEditable(false);
_errorInfo.setBackground(getContentPane().getBackground());
_stackTrace.setText("");
_indexLabel.setText("");
}
getContentPane().add(_errorInfo, BorderLayout.NORTH);
validate();
}
/** Return a string with the system properties, the DrJava configuration file contents, and
* information about memory. The data is anonymized.
* @return information string */
public static String getSystemAndDrJavaInfo() {
final StringBuilder b = new StringBuilder();
b.append("System Properties:\n");
b.append("DrJava Version ");
b.append(edu.rice.cs.drjava.Version.getVersionString());
b.append('\n');
b.append("DrJava Build Time ");
b.append(edu.rice.cs.drjava.Version.getBuildTimeString());
b.append("\n\n");
java.util.Properties props = System.getProperties();
// int size = props.size();
java.util.Iterator entries = props.entrySet().iterator();
while(entries.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry)entries.next();
b.append(entry.getKey());
b.append(" = ");
if (entry.getKey().equals("line.separator")) {
b.append("\"");
String ls = (String)entry.getValue();
for(int i=0; i<ls.length(); ++i) {
int ch = ls.charAt(i);
b.append("\\u");
String hexString = "0000" + Integer.toHexString(ch);
b.append(hexString.substring(hexString.length()-4));
}
b.append("\"");
}
else {
b.append(entry.getValue());
}
b.append('\n');
}
b.append('\n');
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
DrJava.getConfig().saveConfiguration(baos, "DrJava configuration file");
b.append(baos.toString());
}
catch(java.io.IOException ioe) {
b.append("IOException when trying to print DrJava configuration file");
}
b.append("\n\nUsed memory: about ");
b.append(StringOps.memSizeToString(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()));
b.append("\nFree memory: about ");
b.append(StringOps.memSizeToString(Runtime.getRuntime().freeMemory()));
b.append("\nTotal memory: about ");
b.append(StringOps.memSizeToString(Runtime.getRuntime().totalMemory()));
b.append("\nTotal memory can expand to: about ");
b.append(StringOps.memSizeToString(Runtime.getRuntime().maxMemory()));
b.append("\n\n");
// filter out user.dir, user.home and user.name
String infoText = b.toString();
String userHome = System.getProperty("user.home");
String anonUserHome = "<anonymized user.home>";
infoText = replaceString(infoText, userHome, anonUserHome);
String userDir = System.getProperty("user.dir");
String anonUserDir = "<anonymized user.dir>";
infoText = replaceString(infoText, userDir, anonUserDir);
String userName = System.getProperty("user.name");
String anonUserName = "<anonymized user.name>";
infoText = replaceString(infoText, userName, anonUserName);
return infoText;
}
/* Close the window. */
private final Action _okAction = new AbstractAction("OK") {
public void actionPerformed(ActionEvent e) {
DrJavaErrorWindow.this.dispose();
if (DrJavaErrorHandler.getButton()==null) { System.exit(1); }
}
};
/* Go to the previous error. */
private final Action _prevAction = new AbstractAction("Previous") {
public void actionPerformed(ActionEvent e) {
if (_errorIndex>0) {
--_errorIndex;
_error = DrJavaErrorHandler.getError(_errorIndex);
if (_errorIndex==0) { setEnabled(false); }
if (_errorCount>1) { _nextAction.setEnabled(true); }
updateErrorInfo();
}
}
};
/** Replaces all occurrences of orig in text with repl. */
private static String replaceString(String text, String orig, String repl) {
int pos = 0;
while((pos=text.indexOf(orig,pos))>=0) {
// found occurrence at pos
text = text.substring(0,pos) + repl + text.substring(pos+orig.length(), text.length());
}
return text;
}
/** Go to the next error. */
private final Action _nextAction = new AbstractAction("Next") {
public void actionPerformed(ActionEvent e) {
if (_errorIndex<_errorCount-1) {
++_errorIndex;
_error = DrJavaErrorHandler.getError(_errorIndex);
if (_errorIndex==_errorCount-1) { setEnabled(false); }
if (_errorCount>1) { _prevAction.setEnabled(true); }
updateErrorInfo();
}
}
};
/** Dismiss all errors and close the window. */
private Action _dismissAction = new AbstractAction("Dismiss") {
public void actionPerformed(ActionEvent e) {
DrJavaErrorHandler.clearErrors();
_errorCount = 0;
_error = null;
_errorIndex = -1;
setEnabled(false);
_prevAction.setEnabled(false);
_nextAction.setEnabled(false);
_copyAction.setEnabled(false);
updateErrorInfo();
JButton errorsButton = DrJavaErrorHandler.getButton();
if (errorsButton != null) { errorsButton.setVisible(false); }
_okAction.actionPerformed(e);
}
};
/** Copy currently selected error to clip board. */
private Action _copyAction = new AbstractAction("Copy This Error") {
public void actionPerformed(ActionEvent e) {
_stackTrace.grabFocus();
_stackTrace.getActionMap().get(DefaultEditorKit.selectAllAction).actionPerformed(e);
_stackTrace.getActionMap().get(DefaultEditorKit.copyAction).actionPerformed(e);
}
};
/** Canned message for the user.
*/
private static final String HEADER_HTML =
"<html><font size=\"-1\" face=\"sans-serif, Arial, Helvetica, Geneva\"><b>";
private static final String ERRORS_FOOTER_HTML =
"Please submit a bug report containing the information below " +
"and an account of the actions that caused the bug (if known) to " +
"<a href=\"" + SF_ADD_BUG_URL + "\"><b>" + SF_LINK_NAME + "</b></a>.<br>" +
"You may wish to save all your work and restart DrJava.<br>" +
"Thanks for your help in making DrJava better!</b></font></p></html>";
private static final String NO_ERRORS_HTML =
"No errors occurred!<br>" +
"Thanks for using DrJava!</b></font></p></html>";
}
The table below shows all metrics for DrJavaErrorWindow.java.
| Metric | Value | Description | |
|---|---|---|---|



