package hr.iii.common.ui; import hr.iii.common.utilities.UtilitiesText; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import javax.swing.text.html.HTML; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.PrintWriter; import java.io.StringWriter; import java.net.MalformedURLException; import java.util.ResourceBundle; import java.util.logging.Level; /** * Class ExceptionDialog is the generic error/exception dialog * * @author Emil Marceta * @version 1.0 */ public class ExceptionDialog extends JDialog implements ActionListener { private static final ResourceBundle BUNDLE = UtilitiesText.getResourceBundleForName( "ExceptionDialog" ); private static final String OPEN_HTML = ""; private static final String CLOSE_HTML = ""; private JPanel main = new JPanel(); private JPanel messagePanel = new JPanel(); private JPanel internalErroLabelPanel = null; private JPanel buttons = new JPanel(); private JTabbedPane tabPane = new JTabbedPane(); private JTextArea textArea = new JTextArea(); private JScrollPane scrollPane = new JScrollPane(textArea); private UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults(); // private Icon errorIcon = uiDefaults.getIcon("OptionPane.errorIcon"); Icon errorIcon = new ImageIcon("images/errorIcon.png"); // private Icon warningIcon = uiDefaults.getIcon("OptionPane.warningIcon"); Icon warningIcon = new ImageIcon("images/warningIcon.png"); // private Icon informationIcon = uiDefaults.getIcon("OptionPane.informationIcon"); Icon informationIcon = new ImageIcon("images/informationIcon.png"); private JLabel internalErrorLabel = null; private JLabel messageLabel = null; private JLabel exceptionMessageLabel = null; private JLabel iconLabel = null; private JButton close = new JButton( BUNDLE.getString( "title.zatvori" ) );//"Zatvori"); private JButton shutdown = new JButton(BUNDLE.getString( "title.ugasi" ) );//"Ugasi"); /** * Constructor ExceptionDialog * * @param parent * @param title * @param message * @param throwable */ public ExceptionDialog(Frame parent, String title, String message, Throwable throwable, Level level) { super(parent); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setModal(true); initialize(title, message, throwable, level); } public ExceptionDialog(Dialog parent, String title, String message, Throwable throwable, Level level) { super(parent); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setModal(true); initialize(title, message, throwable, level); } /** * Constructor ExceptionDialog * * @param parent * @param message * @param throwable */ public ExceptionDialog(Frame parent, String message, Throwable throwable, Level level) { super(parent); setModal(true); initialize(getDialogTitle(level), message, throwable, level); } /** * Initialize the dialog * * @param title . * @param message . * @param throwable . */ private void initialize(String title, String message, Throwable throwable, Level level) { Container pane = getContentPane(); setTitle(title); if (JDialog.isDefaultLookAndFeelDecorated()) { boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations(); if (supportsWindowDecorations) { setUndecorated(true); getRootPane().setWindowDecorationStyle(getDecorationStyle(level)); } } setResizable(true); messageLabel = new JLabel(createMessage(message), SwingConstants.CENTER); iconLabel = levelIcon(level); iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0)); if (level == Level.SEVERE) { shutdown.addActionListener(this); buttons.add(shutdown); } else { close.addActionListener(this); buttons.add(close); } // textArea.setText(stackTrace(throwable)); textArea.setEditable(false); textArea.setCaretPosition(0); try { exceptionMessageLabel = getExceptionMessageLabel(throwable); } catch (MalformedURLException e) { e.printStackTrace(System.err); } messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); messagePanel.add(Box.createGlue()); messagePanel.add(messageLabel); if (exceptionMessageLabel != null) { messagePanel.add(exceptionMessageLabel); } messagePanel.add(Box.createGlue()); main.setLayout(new BorderLayout()); main.add(iconLabel, BorderLayout.WEST); main.add(messagePanel, BorderLayout.CENTER); if (level == Level.SEVERE) { internalErroLabelPanel = new JPanel(); internalErroLabelPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); internalErroLabelPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); internalErrorLabel = new JLabel( BUNDLE.getString( "errorMessage.restartGreska" ) ); internalErroLabelPanel.add(internalErrorLabel); main.add(internalErroLabelPanel, BorderLayout.NORTH); } main.add(buttons, BorderLayout.SOUTH); tabPane.add(main, BUNDLE.getString( "title.greska") ); tabPane.add(scrollPane, BUNDLE.getString( "title.detalji" ) ); tabPane.setPreferredSize(new Dimension(650, 175)); pane.setLayout(new BorderLayout()); pane.add(tabPane, BorderLayout.CENTER); pane.add(buttons, BorderLayout.SOUTH); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { close.doClick(); } }); } private JLabel getExceptionMessageLabel(Throwable t) throws MalformedURLException { HyperlinkLabel label; if (t == null || (t.getMessage() == null || "".equals(t.getMessage()))) return new JLabel(); Throwable cause = unnestToRoot(t); label = new HyperlinkLabel(cause.getMessage(), null, "file://", SwingConstants.CENTER); label.addHyperlinkListener(new HyperlinkListener() { /** * Called when a hypertext link is updated. * * @param e the event responsible for the update */ public void hyperlinkUpdate(HyperlinkEvent e) { if (HyperlinkEvent.EventType.ACTIVATED != e.getEventType()) return; if (tabPane.getTabCount() > 1) tabPane.setSelectedIndex(1); } }); return label; } public static Throwable unnestToRoot(Throwable exception) { Throwable nestedException = exception.getCause(); return nestedException == null ? exception : unnestToRoot(nestedException); } private String createMessage(String message) { StringBuilder sb = new StringBuilder(); sb.append(OPEN_HTML + openTag(HTML.Tag.CENTER) + message + closeTag(HTML.Tag.CENTER)); sb.append(CLOSE_HTML); return sb.toString(); } private String openTag(HTML.Tag t) { return "<" + t + ">"; } private String closeTag(HTML.Tag t) { return ""; } private int getDecorationStyle(Level level) { if (level == Level.SEVERE) { return JRootPane.ERROR_DIALOG; } else if (level == Level.WARNING) { return JRootPane.WARNING_DIALOG; } else { return JRootPane.PLAIN_DIALOG; } } private JLabel levelIcon(Level level) { if (level == Level.SEVERE) { return new JLabel(errorIcon); } else if (level == Level.WARNING) { return new JLabel(warningIcon); } else { return new JLabel(informationIcon); } } private String getDialogTitle(Level level) { if (level == Level.SEVERE) { return BUNDLE.getString( "title.greska" ); } else if (level == Level.WARNING) { return BUNDLE.getString( "title.upozorenje" ); } else { return BUNDLE.getString( "title.info" ); } } private String stackTrace(Throwable throwable) { String value; if (throwable == null) { value = BUNDLE.getString( "errorMessage.dodatniDetaljiNedostupni" ); return value; } Throwable cause = unnestToRoot(throwable); StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); cause.printStackTrace(printWriter); printWriter.flush(); value = stringWriter.toString(); return value; } public void actionPerformed(ActionEvent e) { final Object source = e.getSource(); if (source == close) { this.dispose(); } else if (source == shutdown) { System.exit(-1); } } public static void main(String[] args) { ExceptionDialog d = new ExceptionDialog(null, BUNDLE.getString( "errorMessage.pokretanjePrograma" ), new Exception(BUNDLE.getString( "title.poruka" )), Level.SEVERE); d.pack(); d.setVisible(true); System.exit(-1); } }