/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.nmedit.nomad.core.forms; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.io.PrintWriter; import java.io.StringWriter; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; public class ExceptionDialog extends JPanel { /** * */ private static final long serialVersionUID = -1830717129957093522L; private static transient int iconType = -1; private static transient Icon messageIcon; private transient Icon icon; private int currentIconType; private Throwable throwable; private boolean tinfoVisible = false; private JComponent tinfoComponent; private transient String stackTrace; private JDialog dialog; public ExceptionDialog(JDialog dialog, Object message, Throwable throwable) { this(dialog, JOptionPane.ERROR_MESSAGE, message, throwable); } public ExceptionDialog(JDialog dialog, int messageIcon, Object message, Throwable throwable) { this.dialog = dialog; this.currentIconType = messageIcon; this.throwable = throwable; JPanel messagePan = new JPanel(); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); messagePan.setLayout(new BoxLayout(messagePan, BoxLayout.Y_AXIS)); Box box = Box.createVerticalBox(); Box box2 = Box.createHorizontalBox(); JLabel label = new JLabel(String.valueOf(message), getIcon(), JLabel.LEFT); label.setAlignmentX(JComponent.LEFT_ALIGNMENT); label.setAlignmentY(JComponent.TOP_ALIGNMENT); box2 = Box.createHorizontalBox(); box2.add(label); box2.add(Box.createHorizontalGlue()); box.add(box2);/**/ messagePan.add(box); messagePan.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); //messagePan.add(Box.createVerticalStrut(4)); // messagePan.add(new JSeparator(JSeparator.HORIZONTAL)); //messagePan.add(Box.createVerticalStrut(4)); //messagePan.add(Box.createVerticalStrut(4)); setLayout(new BorderLayout()); add(messagePan, BorderLayout.NORTH); box = Box.createHorizontalBox(); JButton btn = new JButton(new DialogAction(DialogAction.MoreLess)); btn.setAlignmentX(JComponent.RIGHT_ALIGNMENT); btn.setAlignmentY(JComponent.TOP_ALIGNMENT); box.add(btn); box.add(Box.createHorizontalStrut(4)); btn = new JButton(new DialogAction(DialogAction.COPY)); btn.setAlignmentX(JComponent.RIGHT_ALIGNMENT); btn.setAlignmentY(JComponent.TOP_ALIGNMENT); box.add(btn); btn = new JButton(new DialogAction(DialogAction.CLOSE)); btn.setDefaultCapable(true); dialog.getRootPane().setDefaultButton(btn); btn.setAlignmentX(JComponent.RIGHT_ALIGNMENT); btn.setAlignmentY(JComponent.TOP_ALIGNMENT); box.add(Box.createGlue()); box.add(btn); add(box, BorderLayout.SOUTH); } public static void main(String[] args) { try { try { throw new RuntimeException("test"); } catch (Throwable t) { throw new Exception("Wrapped Exception", t); } } catch (Throwable t) { ExceptionDialog.showErrorDialog(null, "The Title", "The Message", t); } } public static void showErrorDialog(JComponent parent, Object message, String title, Throwable throwable) { JDialog dialog = new JDialog(); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setTitle(title); dialog.setMinimumSize(new Dimension(180, 100)); ExceptionDialog ed = new ExceptionDialog(dialog, message, throwable); dialog.getContentPane().setLayout(new BorderLayout()); dialog.getContentPane().add(ed, BorderLayout.CENTER); dialog.setResizable(false); dialog.setModal(true); ed.checkBounds(); dialog.setVisible(true); } private void checkBounds() { Dimension s = Toolkit.getDefaultToolkit().getScreenSize(); dialog.pack(); Dimension d = dialog.getSize(); d.width = Math.min(d.width, s.width/2); d.height = Math.min(d.height, s.height/3); dialog.setBounds((s.width-d.width)/2, (s.height-d.height)/2, d.width, d.height); } public boolean isThrowableInfoVisible() { return tinfoVisible; } public void setThrowableInfoVisible(boolean visible) { if (this.tinfoVisible != visible) { this.tinfoVisible = visible; if (visible) { if (tinfoComponent == null) tinfoComponent = createInfoComponent(); add(tinfoComponent, BorderLayout.CENTER); checkBounds(); } else if (tinfoComponent != null) { remove(tinfoComponent); checkBounds(); } } } public void copyToClipBoard() { StringSelection stringSelection = new StringSelection( getStackTrace() ); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents( stringSelection, null ); } private String getStackTrace() { if (stackTrace == null) { StringWriter sw = new StringWriter(); throwable.printStackTrace(new PrintWriter(sw)); stackTrace = sw.getBuffer().toString(); } return stackTrace; } private JComponent createInfoComponent() { JTextArea text = new JTextArea(); text.setFont(new Font("monospaced", Font.PLAIN, 11)); text.setTabSize(4); text.setEditable(false); text.setText(getStackTrace()); JScrollPane sp = new JScrollPane(text); return sp; } public void close() { dialog.dispose(); } private class DialogAction extends AbstractAction { /** * */ private static final long serialVersionUID = -192407757621759091L; public static final String CLOSE = "Close"; public static final String COPY = "Copy to Clipboard"; public static final String MoreLess = "MoreLess"; public DialogAction (String command) { putValue(ACTION_COMMAND_KEY, command); if (command == CLOSE) { putValue(NAME, "Close"); putValue(MNEMONIC_KEY, KeyEvent.VK_C); } else if (command == COPY) { putValue(NAME, "Copy to Clipboard"); } else if (command == MoreLess) { putValue(NAME, "More"); } } public void actionPerformed(ActionEvent e) { if (e.getActionCommand() == CLOSE) close(); else if (e.getActionCommand() == COPY) copyToClipBoard(); else if (e.getActionCommand() == MoreLess) { setThrowableInfoVisible(!isThrowableInfoVisible()); if (isThrowableInfoVisible()) putValue(NAME, "Less"); else putValue(NAME, "More"); } } } public Throwable getThrowable() { return throwable; } protected Icon getIcon() { if (icon == null) icon = getIconForType(currentIconType); return icon; } protected Icon getIconForType(int messageType) { if (iconType == messageType && messageIcon != null) return messageIcon; if(messageType < 0 || messageType > 3) return null; String propertyName = null; switch(messageType) { case 0: propertyName = "OptionPane.errorIcon"; break; case 1: propertyName = "OptionPane.informationIcon"; break; case 2: propertyName = "OptionPane.warningIcon"; break; case 3: propertyName = "OptionPane.questionIcon"; break; } if (propertyName != null) { Icon i = UIManager.getIcon(propertyName); if (i != null) { iconType = messageType; messageIcon = i; return i; } } return null; } }