001package jmri.util.swing; 002 003import java.awt.Component; 004import java.awt.Toolkit; 005import java.awt.datatransfer.Clipboard; 006import java.awt.datatransfer.StringSelection; 007import java.awt.event.ActionEvent; 008 009import javax.annotation.CheckForNull; 010import javax.annotation.Nonnull; 011import javax.swing.BoxLayout; 012import javax.swing.JButton; 013import javax.swing.JLabel; 014import javax.swing.JPanel; 015import javax.swing.JTextArea; 016import javax.swing.border.EmptyBorder; 017 018/** 019 * Static methods to display an Exception Dialog. 020 * <p> 021 * The Exception and additional details about what was happening when the 022 * exception occurred can be passed in using an ExceptionContext object. 023 * <p> 024 * The Dialog has buttons for pasting Exception and System details to Clipboard. 025 * @author Gregory Madsen Copyright (C) 2012 026 * @author Steve Young Copyright (C) 2023 027 */ 028public class ExceptionDisplayFrame { 029 030 private ExceptionDisplayFrame(){} 031 032 private static final EmptyBorder border = new EmptyBorder(10, 20, 10, 20); 033 034 /** 035 * Display an ExceptionDisplayFrame. 036 * 037 * @param context the ExceptionContext to display details for. 038 * @param owner the associated Component, can be null. 039 */ 040 public static void displayExceptionDisplayFrame(@CheckForNull final Component owner, @Nonnull final ExceptionContext context) { 041 JmriJOptionPane.showMessageDialog(owner, 042 initComponents(context), 043 context.getTitle(), 044 JmriJOptionPane.ERROR_MESSAGE); 045 } 046 047 /** 048 * Display an ExceptionDisplayFrame. 049 * 050 * @param ex the Exception to display details for. 051 * @param owner the associated Component, can be null. 052 * 053 */ 054 public static void displayExceptionDisplayFrame(@CheckForNull Component owner, @Nonnull Exception ex) { 055 displayExceptionDisplayFrame( owner, new ExceptionContext( ex, "", "") ); 056 } 057 058 @Nonnull 059 private static JPanel initComponents(@Nonnull ExceptionContext context) { 060 JPanel contentPane = new JPanel(); 061 contentPane.setBorder(border); 062 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 063 064 JPanel titlePanel = new JPanel(); 065 titlePanel.add(new JLabel("<html><h2>" + context.getPreface() + "</h2></html>")); 066 contentPane.add(titlePanel); 067 068 if ( !context.getHint().isBlank() ) { 069 JPanel hintPanel = new JPanel(); 070 hintPanel.add(new JLabel("<html><h3>" + context.getHint() + "</h3></html>")); 071 contentPane.add(hintPanel); 072 } 073 074 contentPane.add(getSummaryPanel(context)); 075 contentPane.add(getButtonPanel(context)); 076 contentPane.add(getStrackTracePanel(context)); 077 return contentPane; 078 } 079 080 @Nonnull 081 private static JPanel getSummaryPanel(@Nonnull ExceptionContext context){ 082 JPanel summaryPanel = new JPanel(); 083 JTextArea jta = new JTextArea(context.getSummary()); 084 jta.setBorder(border); 085 summaryPanel.add(jta); 086 return summaryPanel; 087 } 088 089 @Nonnull 090 private static JPanel getStrackTracePanel(@Nonnull ExceptionContext context){ 091 JPanel strackTracePanel = new JPanel(); 092 JTextArea ta = new JTextArea(context.getStackTraceAsString(10)); 093 ta.setToolTipText(Bundle.getMessage("ExceptionDisplayStackTraceToolTip")); 094 ta.setBorder(border); 095 strackTracePanel.add(ta); 096 return strackTracePanel; 097 } 098 099 @Nonnull 100 private static JPanel getButtonPanel(@Nonnull ExceptionContext context){ 101 102 Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 103 104 JButton exCopyButton = new JButton(Bundle.getMessage("ExceptionDisplayCopyButton")); 105 exCopyButton.addActionListener((ActionEvent e) -> 106 systemClipboard.setContents(new StringSelection(context.getClipboardString(false)), null)); 107 108 JButton systemCopyButton = new JButton(Bundle.getMessage("ExceptionSystemCopyButton")); 109 systemCopyButton.addActionListener((ActionEvent e) -> 110 systemClipboard.setContents(new StringSelection(context.getClipboardString(true)), null)); 111 112 JPanel b1 = new JPanel(); 113 JPanel b2 = new JPanel(); 114 b1.add(exCopyButton); 115 b2.add(systemCopyButton); 116 117 JPanel p = new JPanel(); 118 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 119 p.add(b1); 120 p.add(b2); 121 return p; 122 } 123 124}