package org.mypsycho.swing.app.beans; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Arrays; import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import org.mypsycho.swing.TextAreaStream; import org.mypsycho.swing.app.utils.SwingHelper; @SuppressWarnings("serial") public class ErrorPane extends JOptionPane { final Throwable detail; final TabPage[] tabs = new TabPage[3]; public ErrorPane(Throwable cause) { this(null, cause, null); } static String getMessage(String message, Throwable cause) { if (message != null) { return message; } if (cause != null) { return (cause.getMessage() != null) ? cause.getMessage() : cause.getClass().getSimpleName(); } return "Undefined error"; } public ErrorPane(String message, Throwable cause, String help) { super(getMessage(message, cause), JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION); Arrays.fill(tabs, new TabPage()); detail = cause; // We have to compute the layout of the message to add it in pane. if ((detail != null) || (help != null)) { SwingHelper h = new SwingHelper("tabs", new JTabbedPane()); Container container = (Container) ((Container) getComponent(0)).getComponent(0); Component messagePane = container.getComponent(1); h.add("message", messagePane); tabs[0] = new TabPage(h.<JTabbedPane>get(), 0); if (detail != null) { final JTextArea stackTraceText = new JTextArea(20, 50); stackTraceText.setTabSize(2); stackTraceText.setEditable(false); stackTraceText.setLineWrap(true); detail.printStackTrace(new TextAreaStream(stackTraceText)); h.with("detail", new BorderLayout(2, 2)) .add("stack", new JScrollPane(stackTraceText), BorderLayout.CENTER) .add("toClipboard", new JButton(), BorderLayout.PAGE_END) .back(); tabs[1] = new TabPage((JTabbedPane) h.get(), 1); } if (help != null) { h.add("help", new JScrollPane(new JEditorPane(help, "text/plain"))); tabs[2] = new TabPage((JTabbedPane) h.get(), detail != null ? 2 : 1); } // If message is not a component, it is not resizable by default. setMessage(h.get()); // Some magic trick so the tabbed pane use the whole space container = (Container) ((Container) getComponent(0)).getComponent(0); container.remove(0); container.add(h.get(), BorderLayout.CENTER); } } /** * Returns the tabbs. * * @return the tabbs */ public TabPage[] getTabs() { return tabs; } public void copyToClipBoard() { ByteArrayOutputStream stack = new ByteArrayOutputStream(); detail.printStackTrace(new PrintStream(stack)); StringSelection stringSelection = new StringSelection(stack.toString()); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents(stringSelection, null); } }