1:
31:
32: package ;
33:
34: import ;
35: import ;
36: import ;
37: import ;
38: import ;
39: import ;
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53: import ;
54: import ;
55:
56:
62: public class ExceptionDialog extends JDialog
63: {
64:
67: private final class OKAction extends AbstractAction
68: {
69:
72: private OKAction ()
73: {
74: putValue(NAME, UIManager.getDefaults().getString("OptionPane.okButtonText"));
75: }
76:
77:
82: public void actionPerformed (final ActionEvent event)
83: {
84: setVisible(false);
85: }
86: }
87:
88:
91: private final class DetailsAction extends AbstractAction
92: {
93:
96: private DetailsAction ()
97: {
98: putValue(NAME, ">>");
99: }
100:
101:
106: public void actionPerformed (final ActionEvent event)
107: {
108: setScrollerVisible(!(isScrollerVisible()));
109: if (isScrollerVisible())
110: {
111: putValue(NAME, "<<");
112: }
113: else
114: {
115: putValue(NAME, ">>");
116: }
117: adjustSize();
118: }
119: }
120:
121:
124: private final JTextArea backtraceArea;
125:
126:
129: private final JLabel messageLabel;
130:
131:
134: private Exception currentEx;
135:
136:
139: private DetailsAction detailsAction;
140:
141:
144: private final JScrollPane scroller;
145:
146:
149: private final JPanel filler;
150:
151:
154: private static ExceptionDialog defaultDialog;
155:
156:
159: public ExceptionDialog ()
160: {
161: setModal(true);
162: detailsAction = new DetailsAction();
163:
164: messageLabel = new JLabel();
165: backtraceArea = new JTextArea();
166:
167: scroller = new JScrollPane(backtraceArea);
168: scroller.setVisible(false);
169:
170: final JPanel detailPane = new JPanel();
171: detailPane.setLayout(new GridBagLayout());
172: GridBagConstraints gbc = new GridBagConstraints();
173: gbc.anchor = GridBagConstraints.CENTER;
174: gbc.fill = GridBagConstraints.NONE;
175: gbc.weightx = 0;
176: gbc.weighty = 0;
177: gbc.gridx = 0;
178: gbc.gridy = 0;
179: final JLabel icon = new JLabel(UIManager.getDefaults().getIcon("OptionPane.errorIcon"));
180: icon.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
181: detailPane.add(icon, gbc);
182:
183: gbc = new GridBagConstraints();
184: gbc.anchor = GridBagConstraints.WEST;
185: gbc.fill = GridBagConstraints.NONE;
186: gbc.weightx = 1;
187: gbc.weighty = 1;
188: gbc.gridx = 1;
189: gbc.gridy = 0;
190: detailPane.add(messageLabel);
191:
192: gbc = new GridBagConstraints();
193: gbc.anchor = GridBagConstraints.SOUTH;
194: gbc.fill = GridBagConstraints.HORIZONTAL;
195: gbc.weightx = 0;
196: gbc.weighty = 0;
197: gbc.gridx = 0;
198: gbc.gridy = 2;
199: gbc.gridwidth = 2;
200: detailPane.add(createButtonPane(), gbc);
201:
202: filler = new JPanel();
203: filler.setPreferredSize(new Dimension(0, 0));
204: filler.setBackground(Color.green);
205: gbc = new GridBagConstraints();
206: gbc.anchor = GridBagConstraints.NORTH;
207: gbc.fill = GridBagConstraints.HORIZONTAL;
208: gbc.weightx = 1;
209: gbc.weighty = 5;
210: gbc.gridx = 0;
211: gbc.gridy = 3;
212: gbc.gridwidth = 2;
213: detailPane.add(filler, gbc);
214:
215: gbc = new GridBagConstraints();
216: gbc.anchor = GridBagConstraints.SOUTHWEST;
217: gbc.fill = GridBagConstraints.BOTH;
218: gbc.weightx = 1;
219: gbc.weighty = 5;
220: gbc.gridx = 0;
221: gbc.gridy = 4;
222: gbc.gridwidth = 2;
223: detailPane.add(scroller, gbc);
224:
225: setContentPane(detailPane);
226: }
227:
228:
232: public void adjustSize ()
233: {
234: final Dimension scSize = scroller.getPreferredSize();
235: final Dimension cbase = filler.getPreferredSize();
236: cbase.width = Math.max(scSize.width, cbase.width);
237: cbase.height = 0;
238: filler.setMinimumSize(cbase);
239: pack();
240:
241: }
242:
243:
248: protected void setScrollerVisible (final boolean b)
249: {
250: scroller.setVisible(b);
251: }
252:
253:
258: protected boolean isScrollerVisible ()
259: {
260: return scroller.isVisible();
261: }
262:
263:
268: private JPanel createButtonPane ()
269: {
270: final JPanel buttonPane = new JPanel();
271: buttonPane.setLayout(new FlowLayout(2));
272: buttonPane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
273: final OKAction okAction = new OKAction();
274:
275: final JButton ok = new ActionButton(okAction);
276: final JButton details = new ActionButton(detailsAction);
277:
278: FloatingButtonEnabler.getInstance().addButton(ok);
279: FloatingButtonEnabler.getInstance().addButton(details);
280:
281: buttonPane.add(ok);
282: buttonPane.add(details);
283: return buttonPane;
284: }
285:
286:
292: public void setMessage (final String mesg)
293: {
294: messageLabel.setText(mesg);
295: }
296:
297:
303: public String getMessage ()
304: {
305: return messageLabel.getText();
306: }
307:
308:
315: public void setException (final Exception e)
316: {
317: currentEx = e;
318: if (e == null)
319: {
320: detailsAction.setEnabled(false);
321: backtraceArea.setText("");
322: }
323: else
324: {
325: backtraceArea.setText(readFromException(e));
326: }
327: }
328:
329:
335: private String readFromException (final Exception e)
336: {
337: String text = "No backtrace available";
338: try
339: {
340: final StringWriter writer = new StringWriter();
341: final PrintWriter pwriter = new PrintWriter(writer);
342: e.printStackTrace(pwriter);
343: text = writer.toString();
344: writer.close();
345: }
346: catch (Exception ex)
347: {
348: Log.info("ExceptionDialog: exception suppressed.");
349: }
350: return text;
351: }
352:
353:
358: public Exception getException ()
359: {
360: return currentEx;
361: }
362:
363:
371: public static void showExceptionDialog
372: (final String title, final String message, final Exception e)
373: {
374: if (defaultDialog == null)
375: {
376: defaultDialog = new ExceptionDialog();
377: }
378: if (e != null)
379: {
380: Log.error("UserError", e);
381: }
382: defaultDialog.setTitle(title);
383: defaultDialog.setMessage(message);
384: defaultDialog.setException(e);
385: defaultDialog.adjustSize();
386: defaultDialog.setVisible(true);
387: }
388:
389: }