You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2010/05/25 06:36:26 UTC
svn commit: r947913 - in
/openjpa/trunk/openjpa-examples/openbooks/src/main/java:
jpa/tools/swing/ErrorDialog.java openbook/client/ErrorHandler.java
Author: ppoddar
Date: Tue May 25 04:36:26 2010
New Revision: 947913
URL: http://svn.apache.org/viewvc?rev=947913&view=rev
Log:
Improve error handling and reporting
Added:
openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/ErrorHandler.java (with props)
Modified:
openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java
Modified: openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java?rev=947913&r1=947912&r2=947913&view=diff
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java (original)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/ErrorDialog.java Tue May 25 04:36:26 2010
@@ -14,7 +14,6 @@
package jpa.tools.swing;
import java.awt.BorderLayout;
-import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -22,119 +21,197 @@ import java.util.Arrays;
import java.util.List;
import javax.swing.BorderFactory;
+import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
+import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
+import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
import javax.swing.JTextPane;
-import javax.swing.text.AttributeSet;
-import javax.swing.text.SimpleAttributeSet;
-import javax.swing.text.StyleConstants;
-import javax.swing.text.StyleContext;
+/**
+ * A dialog to display runtime error.
+ *
+ * @author Pinaki Poddar
+ *
+ */
@SuppressWarnings("serial")
public class ErrorDialog extends JDialog {
- private static List<String> filters = Arrays.asList("java.awt.", "javax.swing.", "sun.reflect.");
- private static AttributeSet red, black;
- static {
- StyleContext ctx = StyleContext.getDefaultStyleContext();
- red = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.RED);
- red = ctx.addAttribute(red, StyleConstants.Bold, true);
- red = ctx.addAttribute(red, StyleConstants.FontSize, 12);
- red = ctx.addAttribute(red, StyleConstants.FontFamily, "Courier");
- black = ctx.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.BLACK);
- black = ctx.addAttribute(black, StyleConstants.Bold, false);
- black = ctx.addAttribute(black, StyleConstants.FontFamily, "Courier");
+ private static List<String> filters = Arrays.asList(
+ "java.awt.",
+ "javax.swing.",
+ "sun.reflect.",
+ "java.util.concurrent.");
+ private static Dimension MESSAGE_SIZE = new Dimension(600,200);
+ private static Dimension STACKTRACE_SIZE = new Dimension(600,300);
+ private static Dimension TOTAL_SIZE = new Dimension(600,500);
+
+
+ static String NEWLINE = "\r\n";
+ static String INDENT = " ";
+
+ private boolean _showingDetails;
+ private boolean _isFiltering = true;
+ private JComponent _message;
+ private JComponent _main;
+ private JScrollPane _details;
+ private JTextPane _stacktrace;
+ private final Throwable _error;
+
+ /**
+ * Creates a modal dialog to display the given exception message.
+ *
+ * @param t the exception to display
+ */
+ public ErrorDialog(Throwable t) {
+ this(null, null, t);
}
public ErrorDialog(JComponent owner, Throwable t) {
+ this(owner, null, t);
+ }
+
+ /**
+ * Creates a modal dialog to display the given exception message.
+ *
+ * @param owner if non-null, then the dialog is positioned (centered) w.r.t. this component
+ * @param t the exception to display
+ */
+ public ErrorDialog(JComponent owner, Icon icon, Throwable t) {
super();
+ setTitle(t.getClass().getName());
setModal(true);
+ if (icon != null && icon instanceof ImageIcon)
+ setIconImage(((ImageIcon)icon).getImage());
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-// Icon icon = Images.ERROR;
-// setIconImage(((ImageIcon)icon).getImage());
- addException(t);
+ _error = t;
+ _message = createErrorMessage(_error);
+ _main = createContent();
+ getContentPane().add(_main);
+
pack();
SwingHelper.position(this, owner);
}
- public ErrorDialog(Throwable t) {
- this(null, t);
- }
-
- void addException(Throwable t) {
- setTitle("Error");
- String txt = t.getClass().getName() + ":" + t.getLocalizedMessage();
- JTextArea message = new JTextArea(txt);
- message.setLineWrap(true);
- message.setWrapStyleWord(true);
- message.setForeground(Color.RED);
- message.setText(txt);
- message.setEditable(false);
-
- JTextPane window = new JTextPane();
- printStackTrace(t, window);
- window.setEditable(false);
- JScrollPane pane = new JScrollPane(window,
- JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
- JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- pane.setPreferredSize(new Dimension(400, 200));
- pane.setBorder(BorderFactory.createTitledBorder("Stacktrace"));
- pane.setPreferredSize(new Dimension(400, 200));
- JPanel main = new JPanel();
- main.setLayout(new BorderLayout());
- main.add(message, BorderLayout.NORTH);
- main.add(pane, BorderLayout.CENTER);
- JPanel buttonPanel = new JPanel();
- JButton ok = new JButton("OK");
- ok.addActionListener(new ActionListener() {
+ /**
+ * Creates the display with the top-level exception message
+ * followed by a pane (that toggles) for detailed stack traces.
+ *
+ * @param t a non-null exception
+ */
+ JComponent createContent() {
+ final JButton showDetails = new JButton("Show Details >>");
+ showDetails.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- ErrorDialog.this.dispose();
+ if (_showingDetails) {
+ _main.remove(_details);
+ _main.validate();
+ _main.setPreferredSize(MESSAGE_SIZE);
+ } else {
+ if (_details == null) {
+ _details = createDetailedMessage(_error);
+ StringBuilder buffer = new StringBuilder();
+ _stacktrace.setText(generateStackTrace(_error, buffer).toString());
+ _stacktrace.setBackground(_main.getBackground());
+ _stacktrace.setPreferredSize(STACKTRACE_SIZE);
+ }
+ _main.add(_details, BorderLayout.CENTER);
+ _main.validate();
+ _main.setPreferredSize(TOTAL_SIZE);
+ }
+ _showingDetails = !_showingDetails;
+ showDetails.setText(_showingDetails ? "<< Hide Details" : "Show Details >>");
+ ErrorDialog.this.pack();
}
});
- buttonPanel.add(ok);
- main.add(buttonPanel, BorderLayout.SOUTH);
- getContentPane().add(main);
- }
- static String NEWLINE = "\r\n";
- StringBuilder printStackTrace(Throwable t, JTextPane text) {
- String message = t.getClass().getName() + ": " + t.getMessage() + NEWLINE;
- text.setCaretPosition(text.getDocument().getLength());
- text.setCharacterAttributes(red, false);
- text.replaceSelection(message);
- StackTraceElement[] traces = t.getStackTrace();
- text.setCharacterAttributes(black, false);
- for (StackTraceElement e : traces) {
- if (!isFiltered(e.getClassName())) {
- String str = " " + e.toString() + NEWLINE;
- text.setCaretPosition(text.getDocument().getLength());
- text.replaceSelection(str);
+ JPanel messagePanel = new JPanel();
+
+ final JCheckBox filter = new JCheckBox("Filter stack traces");
+ filter.setSelected(_isFiltering);
+ filter.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e) {
+ _isFiltering = filter.isSelected();
+ StringBuilder buffer = new StringBuilder();
+ _stacktrace.setText(generateStackTrace(_error, buffer).toString());
+ _stacktrace.repaint();
}
- }
+ });
+ _message.setBackground(messagePanel.getBackground());
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.add(Box.createHorizontalStrut(20));
+ buttonPanel.add(showDetails);
+ buttonPanel.add(filter);
+ buttonPanel.add(Box.createHorizontalGlue());
+ messagePanel.setLayout(new BorderLayout());
+ messagePanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ messagePanel.add(_message, BorderLayout.CENTER);
+ messagePanel.add(buttonPanel, BorderLayout.SOUTH);
+ messagePanel.setPreferredSize(MESSAGE_SIZE);
+ JPanel main = new JPanel();
+ main.setLayout(new BorderLayout());
+ main.add(messagePanel, BorderLayout.NORTH);
+ return main;
+ }
+
+ /**
+ * Creates a non-editable widget to display the error message.
+ *
+ */
+ JComponent createErrorMessage(Throwable t) {
+ String txt = t.getLocalizedMessage();
+ JEditorPane message = new JEditorPane();
+ message.setContentType("text/plain");
+ message.setEditable(false);
+ message.setText(txt);
+ return message;
+ }
+
+ /**
+ * Creates a non-editable widget to display the detailed stack trace.
+ */
+ JScrollPane createDetailedMessage(Throwable t) {
+ _stacktrace = new JTextPane();
+ _stacktrace.setEditable(false);
+ JScrollPane pane = new JScrollPane(_stacktrace,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+
+ return pane;
+ }
+
+ /**
+ * Recursively print the stack trace on the given buffer.
+ */
+ StringBuilder generateStackTrace(Throwable t, StringBuilder buffer) {
+ buffer.append(t.getClass().getName() + ": " + t.getMessage() + NEWLINE);
+ buffer.append(toString(t.getStackTrace()));
Throwable cause = t.getCause();
if (cause !=null && cause != t) {
- printStackTrace(cause, text);
+ generateStackTrace(cause, buffer);
}
- return null;
+ return buffer;
}
StringBuilder toString(StackTraceElement[] traces) {
StringBuilder error = new StringBuilder();
for (StackTraceElement e : traces) {
- if (!isFiltered(e.getClassName())) {
+ if (!_isFiltering || !isSuppressed(e.getClassName())) {
String str = e.toString();
- error.append(str).append("\r\n");
+ error.append(INDENT).append(str).append(NEWLINE);
}
}
return error;
}
- private boolean isFiltered(String className) {
+ /**
+ * Affirms if the error messages from the given class name is to be suppressed.
+ */
+ private boolean isSuppressed(String className) {
for (String s : filters) {
if (className.startsWith(s))
return true;
@@ -146,9 +223,14 @@ public class ErrorDialog extends JDialog
* @param args
*/
public static void main(String[] args) {
- new ErrorDialog(new IllegalArgumentException(
- "This is test error with very long line of error message that should not be in a single line"))
- .setVisible(true);
+ String m1 = "This is test error with very very very very very long line of error message that "
+ + " should not be in a single line. Another message string that shoul dbe split across word." +
+ "The quick brown fox jumpled over the lazy dog";
+ String m2 = "This is another test error with very long line of error message that "
+ + " should not be in a single line";
+ Throwable nested = new NumberFormatException(m2);
+ Throwable top = new IllegalArgumentException(m1, nested);
+ new ErrorDialog(top).setVisible(true);
}
}
Added: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/ErrorHandler.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/ErrorHandler.java?rev=947913&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/ErrorHandler.java (added)
+++ openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/ErrorHandler.java Tue May 25 04:36:26 2010
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package openbook.client;
+
+import javax.swing.SwingUtilities;
+
+import jpa.tools.swing.ErrorDialog;
+
+/**
+ * Handles error.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class ErrorHandler implements Thread.UncaughtExceptionHandler{
+
+ static {
+ System.setProperty("sun.awt.exception.handler", ErrorHandler.class.getName());
+ }
+
+ public void handle(Throwable e) {
+ uncaughtException(Thread.currentThread(), e);
+ }
+
+ public void uncaughtException(Thread t, Throwable e) {
+ if (SwingUtilities.isEventDispatchThread()) {
+ new ErrorDialog(null, Images.ERROR, e).setVisible(true);
+ } else {
+ e.printStackTrace();
+ }
+ }
+}
Propchange: openjpa/trunk/openjpa-examples/openbooks/src/main/java/openbook/client/ErrorHandler.java
------------------------------------------------------------------------------
svn:eol-style = native