Repository navigation
Expand file tree
/
Copy pathThrowableDialog.java
More file actions
169 lines (149 loc) · 7.06 KB
/
Copy pathThrowableDialog.java
File metadata and controls
169 lines (149 loc) · 7.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
*
* Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
* that is described in this document. In particular, and without limitation, these intellectual property
* rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
* more additional patents or pending patent applications in the U.S. and in other countries.
*
* U.S. Government Rights - Commercial software. Government users are subject to the Sun
* Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
* supplements.
*
* Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
* registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
* are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
* U.S. and other countries.
*
* UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
* Company, Ltd.
*/
package com.sun.max.gui;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
/**
* A dialog for displaying the details of an exception. Initially the dialog only shows the exception's
* {@linkplain Throwable#getMessage() message}. It includes a button for expanding the dialog to also show the stack
* trace. When the stack trace is shown, pressing the same button hides the stack trace.
*
* @author Doug Simon
* @author Aritra Bandyopadhyay
*/
public final class ThrowableDialog extends JDialog {
/**
* Creates a dialog to display the details of an exception and makes it visible.
*
* @param throwable the exception whose details are being displayed
* @param owner the {@code Frame} from which the dialog is displayed
* @param title the {@code String} to display in the dialog's title bar
*/
public static void show(Throwable throwable, Frame owner, String title) {
new ThrowableDialog(throwable, owner, title).setVisible(true);
}
/**
* Creates a dialog to display the details of an exception and makes it visible on the
* {@linkplain SwingUtilities#invokeLater(Runnable) AWT dispatching thread}.
*
* @param throwable the exception whose details are being displayed
* @param owner the {@code Frame} from which the dialog is displayed
* @param title the {@code String} to display in the dialog's title bar
*/
public static void showLater(Throwable throwable, Frame owner, String title) {
final ThrowableDialog dialog = new ThrowableDialog(throwable, owner, title);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
dialog.setVisible(true);
}
});
}
/**
* Creates a dialog to display the details of an exception. The dialog is not displayed by this method.
*
* @param throwable the exception whose details are being displayed
* @param owner the {@code Frame} from which the dialog is displayed
* @param title the {@code String} to display in the dialog's title bar
*/
private ThrowableDialog(Throwable throwable, Frame owner, String title) {
super(owner, title, true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setAlwaysOnTop(true);
final JToggleButton stackTraceButton = new JToggleButton("Show stack trace");
final JButton closeButton = new JButton("Close");
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
}
});
final JPanel buttonsPanel = new JPanel();
buttonsPanel.add(closeButton);
buttonsPanel.add(stackTraceButton);
final Container mainPane = getContentPane();
//mainPane.setLayout(new FlowLayout());
mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.PAGE_AXIS));
final JLabel message = new JLabel(throwable.getMessage());
final JPanel messagePanel = new JPanel();
messagePanel.add(message);
mainPane.add(messagePanel);
mainPane.add(buttonsPanel);
pack();
final Dimension dialogWithoutStackTracePreferredSize = getPreferredSize();
final JTextArea stackTraceText = new JTextArea(20, 40);
throwable.printStackTrace(new PrintWriter(new Writer() {
@Override
public void close() throws IOException {
}
@Override
public void flush() throws IOException {
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
stackTraceText.append(new String(cbuf, off, len));
}
}));
final JScrollPane stackTracePanel = new JScrollPane(stackTraceText, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
final Dimension stackTraceTextPreferredSize = stackTraceText.getPreferredSize();
stackTracePanel.setBorder(new TitledBorder("Stack trace"));
final Dimension stackTracePanelPreferredSize = new Dimension(
stackTraceTextPreferredSize.width + stackTracePanel.getVerticalScrollBar().getPreferredSize().width * 2,
stackTraceTextPreferredSize.height + stackTracePanel.getHorizontalScrollBar().getPreferredSize().height);
stackTracePanel.setPreferredSize(stackTracePanelPreferredSize);
stackTracePanel.setVisible(false);
stackTraceButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (stackTraceButton.isSelected()) {
stackTraceButton.setText("Hide stack trace");
stackTracePanel.setVisible(true);
setSize(new Dimension(Math.max(dialogWithoutStackTracePreferredSize.width, stackTracePanelPreferredSize.width),
dialogWithoutStackTracePreferredSize.height + Math.min(1000, stackTracePanelPreferredSize.height)));
} else {
stackTraceButton.setText("Show stack trace");
stackTracePanel.setVisible(false);
setSize(dialogWithoutStackTracePreferredSize);
}
validate();
}
});
mainPane.add(stackTracePanel);
setSize(dialogWithoutStackTracePreferredSize);
pack();
setLocationRelativeTo(owner);
}
// Test code
public static void main(String[] args) {
try {
recurse(0);
} catch (RuntimeException runtimeException) {
new ThrowableDialog(runtimeException, null, "Runtime Exception");
}
}
static void recurse(int more) {
if (more > 345) {
throw new RuntimeException("This is a test. Repeat. This is a test.");
}
recurse(more + 1);
}
}