pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From til...@apache.org
Subject svn commit: r1704717 - in /pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools: PDFDebugger.java gui/ErrorDialog.java
Date Tue, 22 Sep 2015 20:42:29 GMT
Author: tilman
Date: Tue Sep 22 20:42:26 2015
New Revision: 1704717

URL: http://svn.apache.org/viewvc?rev=1704717&view=rev
Log:
PDFBOX-2941: add dialog box for stack trace, based code by Pinaki Poddar from Apache OpenJPA

Added:
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/ErrorDialog.java   (with
props)
Modified:
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java

Modified: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java?rev=1704717&r1=1704716&r2=1704717&view=diff
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java (original)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java Tue Sep 22 20:42:26
2015
@@ -72,6 +72,7 @@ import org.apache.pdfbox.cos.COSString;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.tools.gui.ArrayEntry;
 import org.apache.pdfbox.tools.gui.DocumentEntry;
+import org.apache.pdfbox.tools.gui.ErrorDialog;
 import org.apache.pdfbox.tools.gui.MapEntry;
 import org.apache.pdfbox.tools.gui.OSXAdapter;
 import org.apache.pdfbox.tools.gui.PDFTreeCellRenderer;
@@ -1020,24 +1021,7 @@ public class PDFDebugger extends JFrame
             public void uncaughtException(Thread thread, Throwable throwable)
             {
                 StringBuilder sb = new StringBuilder();
-                Throwable t = throwable;
-                do
-                {
-                    sb.append(t.toString());
-                    for (StackTraceElement element : t.getStackTrace())
-                    {
-                        sb.append("\n    at ");
-                        sb.append(element);
-                    }
-                    t = t.getCause();
-                    if (t != null)
-                    {
-                        sb.append("\nCaused by: ");
-                    }
-                }
-                while (t != null);
-                JOptionPane.showMessageDialog(null, "Error: " + sb.toString(), "Error",
-                        JOptionPane.ERROR_MESSAGE);
+                new ErrorDialog(throwable).setVisible(true);
             }
         });
         

Added: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/ErrorDialog.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/ErrorDialog.java?rev=1704717&view=auto
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/ErrorDialog.java (added)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/ErrorDialog.java Tue Sep
22 20:42:26 2015
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.pdfbox.tools.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+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.JTextPane;
+
+/**
+ * A dialog to display runtime error.
+ *
+ * @author Pinaki Poddar
+ *
+ * Modified from ErrorDialog.java and SwingHelper.java of the Apache OpenJPA
+ * <a href="https://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/openbooks/src/main/java/jpa/tools/swing/">jpa.tools.swing
+ * package</a>.
+ *
+ */
+@SuppressWarnings("serial")
+public class ErrorDialog extends JDialog
+{
+    private static final List<String> FILTERS = Arrays.asList(
+            "java.awt.",
+            "javax.swing.",
+            "sun.reflect.",
+            "java.util.concurrent.");
+    private static final Dimension MESSAGE_SIZE = new Dimension(800, 200);
+    private static final Dimension STACKTRACE_SIZE = new Dimension(800, 300);
+    private static final Dimension TOTAL_SIZE = new Dimension(800, 500);
+
+    private static final String NEWLINE = "\r\n";
+    private static final 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);
+    }
+
+    /**
+     * 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, 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 icon the icon to display
+     * @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);
+        error = t;
+        message = createErrorMessage(error);
+        main = createContent();
+        getContentPane().add(main);
+
+        pack();
+        position(this, owner);
+    }
+
+    /**
+     * Position the given component at the center of the given parent component or physical
screen.
+     *
+     * @param c the component to be positioned
+     * @param parent the component whose center will match the center of the given component.
If
+     * null, the given component will match the screen center.
+     *
+     */
+    static void position(Component c, Component parent)
+    {
+        Dimension d = c.getPreferredSize();
+        if (parent == null)
+        {
+            Dimension s = Toolkit.getDefaultToolkit().getScreenSize();
+            c.setLocation(s.width / 2 - d.width / 2, s.height / 2 - d.height / 2);
+        }
+        else
+        {
+            Point p = parent.getLocationOnScreen();
+            int pw = parent.getWidth();
+            int ph = parent.getHeight();
+            c.setLocation(p.x + pw / 2 - d.width / 2, p.y + ph / 2 - d.height / 2);
+        }
+    }
+
+    /**
+     * 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
+     */
+    final JComponent createContent()
+    {
+        final JButton showDetails = new JButton("Show Details >>");
+        showDetails.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                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.setCaretPosition(0);
+                        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();
+            }
+        });
+        JPanel messagePanel = new JPanel();
+
+        final JCheckBox filter = new JCheckBox("Filter stack traces");
+        filter.setSelected(isFiltering);
+        filter.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                isFiltering = filter.isSelected();
+                StringBuilder buffer = new StringBuilder();
+                stacktrace.setText(generateStackTrace(error, buffer).toString());
+                stacktrace.setCaretPosition(0);
+                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 panel = new JPanel();
+        panel.setLayout(new BorderLayout());
+        panel.add(messagePanel, BorderLayout.NORTH);
+        return panel;
+    }
+
+    /**
+     * Creates a non-editable widget to display the error message.
+     *
+     */
+    final JComponent createErrorMessage(Throwable t)
+    {
+        String txt = t.getLocalizedMessage();
+        JEditorPane msg = new JEditorPane();
+        msg.setContentType("text/plain");
+        msg.setEditable(false);
+        msg.setText(txt);
+        return msg;
+    }
+
+    /**
+     * 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()).append(": ").append(t.getMessage()).append(NEWLINE);
+        buffer.append(toString(t.getStackTrace()));
+        Throwable cause = t.getCause();
+        if (cause != null && cause != t)
+        {
+            buffer.append("Caused by: ");
+            generateStackTrace(cause, buffer);
+        }
+        return buffer;
+    }
+
+    StringBuilder toString(StackTraceElement[] traces)
+    {
+        StringBuilder err = new StringBuilder();
+        for (StackTraceElement e : traces)
+        {
+            if (!isFiltering || !isSuppressed(e.getClassName()))
+            {
+                String str = e.toString();
+                err.append(INDENT).append(str).append(NEWLINE);
+            }
+        }
+        return err;
+    }
+
+    /**
+     * 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;
+            }
+        }
+        return false;
+    }
+}

Propchange: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/ErrorDialog.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message