001: package net.sourceforge.squirrel_sql.fw.gui;
002:
003: /*
004: * Copyright (C) 2001-2003 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: import java.awt.*;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.awt.event.KeyEvent;
025: import java.sql.SQLException;
026:
027: import javax.swing.*;
028:
029: import net.sourceforge.squirrel_sql.fw.util.StringManager;
030: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
031: import net.sourceforge.squirrel_sql.fw.util.Utilities;
032:
033: public class ErrorDialog extends JDialog {
034: /** Internationalized strings for this class. */
035: private static final StringManager s_stringMgr = StringManagerFactory
036: .getStringManager(ErrorDialog.class);
037:
038: private interface IStringKeys {
039: String ERROR = "ErrorDialog.error";
040: String UNKNOWN_ERROR = "ErrorDialog.unknownerror";
041: }
042:
043: /** Close button. */
044: private JButton _closeBtn;
045:
046: /** Display stack trace button. */
047: private JButton _stackTraceBtn;
048:
049: /** Display more errors. */
050: private JButton _moreBtn;
051:
052: /** Panel to display the stack trace in. */
053: private JScrollPane _stackTraceScroller;
054:
055: /** Panel to display more errors in. */
056: private JScrollPane _moreErrorsScroller;
057:
058: /** Handler for Stack Trace button. */
059: private ActionListener _stackTraceHandler = new StackTraceButtonHandler();
060:
061: /** Handler for Close button. */
062: private ActionListener _closeHandler = new CloseButtonHandler();
063:
064: /** Handler for More button. */
065: private ActionListener _moreHandler = new MoreButtonHandler();
066:
067: public ErrorDialog(Throwable th) {
068: this ((Frame) null, th);
069: }
070:
071: public ErrorDialog(Frame owner, Throwable th) {
072: super (owner, s_stringMgr.getString(IStringKeys.ERROR), true);
073: createUserInterface(null, th);
074: }
075:
076: public ErrorDialog(Dialog owner, Throwable th) {
077: super (owner, s_stringMgr.getString(IStringKeys.ERROR), true);
078: createUserInterface(null, th);
079: }
080:
081: public ErrorDialog(Frame owner, String msg) {
082: super (owner, s_stringMgr.getString(IStringKeys.ERROR), true);
083: createUserInterface(msg, null);
084: }
085:
086: public ErrorDialog(Frame owner, String msg, Throwable th) {
087: super (owner, s_stringMgr.getString(IStringKeys.ERROR), true);
088: createUserInterface(msg, th);
089: }
090:
091: public ErrorDialog(Dialog owner, String msg) {
092: super (owner, s_stringMgr.getString(IStringKeys.ERROR), true);
093: createUserInterface(msg, null);
094: }
095:
096: /**
097: * Dispose of this dialog after cleaning up all listeners.
098: */
099: public void dispose() {
100: if (_closeBtn != null && _closeHandler != null) {
101: _closeBtn.removeActionListener(_closeHandler);
102: }
103: if (_stackTraceBtn != null && _stackTraceHandler != null) {
104: _stackTraceBtn.removeActionListener(_stackTraceHandler);
105: }
106: if (_moreBtn != null && _moreHandler != null) {
107: _moreBtn.removeActionListener(_moreHandler);
108: }
109: super .dispose();
110: }
111:
112: /**
113: * Create user interface.
114: *
115: * @param msg Message to be displayed. Can be null.
116: * @param th Exception to be shown. Can be null.
117: */
118: private void createUserInterface(String msg, Throwable th) {
119: if (msg == null || msg.length() == 0) {
120: if (th != null) {
121: msg = th.getMessage();
122: if (msg == null || msg.length() == 0) {
123: msg = th.toString();
124: }
125: }
126: }
127: if (msg == null || msg.length() == 0) {
128: msg = s_stringMgr.getString(IStringKeys.UNKNOWN_ERROR);
129: }
130:
131: _stackTraceScroller = new JScrollPane(new StackTracePanel(th));
132: _stackTraceScroller.setVisible(false);
133:
134: final MoreErrorsPanel moreErrPnl = createMoreErrorsPanel(th);
135: if (moreErrPnl != null) {
136: _moreErrorsScroller = new JScrollPane(moreErrPnl);
137: _moreErrorsScroller.setVisible(false);
138: }
139:
140: Container content = getContentPane();
141: content.setLayout(new GridBagLayout());
142:
143: GridBagConstraints gbc;
144:
145: gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1,
146: GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
147: new Insets(5, 5, 5, 5), 0, 0);
148: content.add(createMessagePanel(msg, th), gbc);
149:
150: gbc = new GridBagConstraints(0, 1, 1, 1, 0, 0,
151: GridBagConstraints.NORTHWEST,
152: GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5),
153: 0, 0);
154: content.add(createButtonsPanel(th), gbc);
155:
156: gbc = new GridBagConstraints(0, 2, 1, 1, 3, 3,
157: GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
158: new Insets(0, 5, 5, 5), 0, 0);
159: content.add(_stackTraceScroller, gbc);
160:
161: if (_moreErrorsScroller != null) {
162: gbc = new GridBagConstraints(0, 2, 1, 1, 3, 3,
163: GridBagConstraints.NORTHWEST,
164: GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0,
165: 0);
166: content.add(_moreErrorsScroller, gbc);
167: }
168:
169: getRootPane().setDefaultButton(_closeBtn);
170:
171: if (null == th) {
172: setSize(400, 200);
173: } else {
174: setSize(400, 500);
175: }
176:
177: AbstractAction closeAction = new AbstractAction() {
178: public void actionPerformed(ActionEvent actionEvent) {
179: setVisible(false);
180: dispose();
181: }
182: };
183: KeyStroke escapeStroke = KeyStroke.getKeyStroke(
184: KeyEvent.VK_ESCAPE, 0);
185: getRootPane().getInputMap(
186: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
187: escapeStroke, "CloseAction");
188: getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
189: .put(escapeStroke, "CloseAction");
190: getRootPane().getInputMap(JComponent.WHEN_FOCUSED).put(
191: escapeStroke, "CloseAction");
192: getRootPane().getActionMap().put("CloseAction", closeAction);
193:
194: GUIUtils.centerWithinParent(ErrorDialog.this );
195: }
196:
197: /**
198: * Create the message panel.
199: *
200: * @param msg The message to be displayed.
201: * @param th The exception to be displayed.
202: *
203: * @return The newly created message panel.
204: */
205: private JComponent createMessagePanel(String msg, Throwable th) {
206: if (msg == null || msg.length() == 0) {
207: if (th != null) {
208: msg = th.getMessage();
209: if (msg == null || msg.length() == 0) {
210: msg = th.toString();
211: }
212: }
213: }
214: if (msg == null || msg.length() == 0) {
215: msg = s_stringMgr.getString(IStringKeys.UNKNOWN_ERROR);
216: }
217: JScrollPane sp = new JScrollPane(new MessagePanel(msg));
218: // Dimension dim = sp.getPreferredSize();
219: // dim.width = PREFERRED_WIDTH;
220: // sp.setPreferredSize(new Dimension(sp.getPreferredSize().width, 200));
221:
222: return sp;
223: }
224:
225: /**
226: * Create the buttons panel.
227: *
228: * @param th The exception.
229: *
230: * @return The newly created buttons panel.
231: */
232: private JPanel createButtonsPanel(Throwable th) {
233: JPanel btnsPnl = new JPanel();
234: if (th != null) {
235: _stackTraceBtn = new JButton(s_stringMgr
236: .getString("ErrorDialog.stacktrace"));
237: _stackTraceBtn.addActionListener(_stackTraceHandler);
238: btnsPnl.add(_stackTraceBtn);
239: if (_moreErrorsScroller != null) {
240: _moreBtn = new JButton(s_stringMgr
241: .getString("ErrorDialog.more"));
242: _moreBtn.addActionListener(_moreHandler);
243: btnsPnl.add(_moreBtn);
244: }
245: }
246: _closeBtn = new JButton(s_stringMgr
247: .getString("ErrorDialog.close"));
248: _closeBtn.addActionListener(_closeHandler);
249: btnsPnl.add(_closeBtn);
250:
251: return btnsPnl;
252: }
253:
254: private static Color getTextAreaBackgroundColor() {
255: return (Color) UIManager.get("TextArea.background");
256: }
257:
258: private MoreErrorsPanel createMoreErrorsPanel(Throwable th) {
259: if (th instanceof SQLException) {
260: SQLException ex = ((SQLException) th).getNextException();
261: if (ex != null) {
262: return new MoreErrorsPanel(ex);
263: }
264: }
265: return null;
266: }
267:
268: /**
269: * Panel to display the message in.
270: */
271: private final class MessagePanel extends MultipleLineLabel {
272: MessagePanel(String msg) {
273: super ();
274: setText(msg);
275: setBackground(ErrorDialog.getTextAreaBackgroundColor());
276: // Dimension dim = getPreferredSize();
277: // dim.width = PREFERRED_WIDTH;
278: // setPreferredSize(dim);
279: // setRows(3);
280: }
281: }
282:
283: /**
284: * Panel to display the stack trace in.
285: */
286: private final class StackTracePanel extends MultipleLineLabel {
287: StackTracePanel(Throwable th) {
288: super ();
289: setBackground(ErrorDialog.getTextAreaBackgroundColor());
290: if (th != null) {
291: setText(Utilities.getStackTrace(th));
292: }
293: }
294: }
295:
296: private final class MoreErrorsPanel extends MultipleLineLabel {
297: MoreErrorsPanel(SQLException ex) {
298: super ();
299: StringBuffer buf = new StringBuffer();
300: setBackground(ErrorDialog.getTextAreaBackgroundColor());
301: while (ex != null) {
302: String msg = ex.getMessage();
303: if (msg != null && msg.length() > 0) {
304: buf.append(msg).append('\n');
305: } else {
306: buf.append(ex.toString()).append('\n');
307: }
308: ex = ex.getNextException();
309: }
310: setText(buf.toString());
311: }
312: }
313:
314: /**
315: * Handler for Close button. Disposes of this dialog.
316: */
317: private final class CloseButtonHandler implements ActionListener {
318: /**
319: * Disposes of this dialog.
320: */
321: public void actionPerformed(ActionEvent evt) {
322: ErrorDialog.this .dispose();
323: }
324:
325: }
326:
327: /**
328: * Handler for Stack Trace button. Shows/hides the stack trace.
329: */
330: private final class StackTraceButtonHandler implements
331: ActionListener {
332: /**
333: * Show/hide the stack trace.
334: */
335: public void actionPerformed(ActionEvent evt) {
336: boolean currentlyVisible = _stackTraceScroller.isVisible();
337: if (!currentlyVisible) {
338: if (_moreErrorsScroller != null) {
339: _moreErrorsScroller.setVisible(false);
340: }
341: }
342: _stackTraceScroller.setVisible(!currentlyVisible);
343: ErrorDialog.this .validate();
344: }
345: }
346:
347: /**
348: * Handler for More button. Shows/hides more information about the error..
349: */
350: private final class MoreButtonHandler implements ActionListener {
351: /**
352: * Show/hide the extra errors.
353: */
354: public void actionPerformed(ActionEvent evt) {
355: boolean currentlyVisible = _moreErrorsScroller.isVisible();
356: if (!currentlyVisible) {
357: _stackTraceScroller.setVisible(false);
358: }
359: _moreErrorsScroller.setVisible(!currentlyVisible);
360: ErrorDialog.this.validate();
361: }
362: }
363: }
|