001: package net.sourceforge.squirrel_sql.client.session;
002:
003: /*
004: * Copyright (C) 2001-2004 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.Color;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.MouseAdapter;
024: import java.awt.event.MouseEvent;
025: import java.util.HashMap;
026:
027: import javax.swing.Action;
028: import javax.swing.JTextPane;
029: import javax.swing.SwingUtilities;
030: import javax.swing.text.BadLocationException;
031: import javax.swing.text.Document;
032: import javax.swing.text.SimpleAttributeSet;
033: import javax.swing.text.StyleConstants;
034:
035: import net.sourceforge.squirrel_sql.fw.gui.TextPopupMenu;
036: import net.sourceforge.squirrel_sql.fw.gui.action.BaseAction;
037: import net.sourceforge.squirrel_sql.fw.util.DefaultExceptionFormatter;
038: import net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter;
039: import net.sourceforge.squirrel_sql.fw.util.IMessageHandler;
040: import net.sourceforge.squirrel_sql.fw.util.StringManager;
041: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
042: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
043: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
044:
045: /**
046: * This is the message panel at the bottom of the session sheet.
047: *
048: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
049: */
050: public class MessagePanel extends JTextPane implements IMessageHandler {
051: static final long serialVersionUID = 5859398063643519072L;
052:
053: /** Logger for this class. */
054: private static final ILogger s_log = LoggerController
055: .createLogger(MessagePanel.class);
056:
057: /** Internationalized strings for this class. */
058: private static final StringManager s_stringMgr = StringManagerFactory
059: .getStringManager(MessagePanel.class);
060:
061: /** Popup menu for this component. */
062: private final TextPopupMenu _popupMenu = new MessagePanelPopupMenu();
063:
064: /**
065: * Attribute sets for error and last message.
066: */
067: private SimpleAttributeSet _saSetMessage;
068: // private SimpleAttributeSet _saSetErrorHistory;
069: private SimpleAttributeSet _saSetError;
070: private SimpleAttributeSet _saSetWarning;
071:
072: /**
073: * Save into these attributes the parameters of the last message being output.
074: * @todo In the near future: if more than one message shall be remembered, then these variables
075: * need to be replaced with a dynamic storage (ArrayList or similar).
076: */
077: private int _lastLength;
078: private String _lastMessage;
079: private SimpleAttributeSet _lastSASet;
080:
081: private HashMap<SimpleAttributeSet, SimpleAttributeSet> _saSetHistoryBySaSet = new HashMap<SimpleAttributeSet, SimpleAttributeSet>();
082:
083: private static interface I18N {
084: //i18n[MessagePanel.clearLabel=Clear]
085: String CLEAR_LABEL = s_stringMgr
086: .getString("MessagePanel.clearLabel");
087: }
088:
089: private DefaultExceptionFormatter defaultExceptionFormatter = new DefaultExceptionFormatter();
090:
091: /**
092: * Default ctor.
093: */
094: public MessagePanel() {
095: super ();
096:
097: _popupMenu.setTextComponent(this );
098:
099: // Add mouse listener for displaying popup menu.
100: addMouseListener(new MouseAdapter() {
101: public void mousePressed(MouseEvent evt) {
102: if (evt.isPopupTrigger()) {
103: _popupMenu.show(evt);
104: }
105: }
106:
107: public void mouseReleased(MouseEvent evt) {
108: if (evt.isPopupTrigger()) {
109: _popupMenu.show(evt);
110: }
111: }
112: });
113:
114: ///////////////////////////////////////////////////////////////////
115: // Message
116: _saSetMessage = new SimpleAttributeSet();
117: StyleConstants.setBackground(_saSetMessage, Color.green);
118:
119: SimpleAttributeSet saSetMessageHistory = new SimpleAttributeSet();
120: StyleConstants.setBackground(saSetMessageHistory,
121: getBackground());
122: _saSetHistoryBySaSet.put(_saSetMessage, saSetMessageHistory);
123: //
124: ////////////////////////////////////////////////////////////////
125:
126: ///////////////////////////////////////////////////////////////////
127: // Warning
128: _saSetWarning = new SimpleAttributeSet();
129: StyleConstants.setBackground(_saSetWarning, Color.yellow);
130:
131: SimpleAttributeSet saSetWarningHistory = new SimpleAttributeSet();
132: StyleConstants.setBackground(saSetWarningHistory, new Color(
133: 255, 255, 210)); // a light yellow
134: _saSetHistoryBySaSet.put(_saSetWarning, saSetWarningHistory);
135: //
136: ////////////////////////////////////////////////////////////////
137:
138: /////////////////////////////////////////////////////////////////
139: // Error
140: _saSetError = new SimpleAttributeSet();
141: StyleConstants.setBackground(_saSetError, Color.red);
142:
143: SimpleAttributeSet saSetErrorHistory = new SimpleAttributeSet();
144: StyleConstants.setBackground(saSetErrorHistory, Color.pink);
145: _saSetHistoryBySaSet.put(_saSetError, saSetErrorHistory);
146: //
147: //////////////////////////////////////////////////////////////////
148:
149: }
150:
151: public void addToMessagePanelPopup(Action action) {
152: if (action == null) {
153: throw new IllegalArgumentException("action cannot be null");
154: }
155: _popupMenu.add(action);
156: }
157:
158: /**
159: * Show a message describing the passed throwable object.
160: *
161: * @param th The throwable object.
162: * @param session the session that generated the exception.
163: */
164: public synchronized void showMessage(final Throwable th,
165: final ExceptionFormatter formatter) {
166: if (th == null) {
167: throw new IllegalArgumentException("th cannot be null");
168: }
169: privateShowMessage(th, formatter, _saSetMessage);
170: }
171:
172: /**
173: * Show an error message describing the passed exception. The controls
174: * background color will be changed to show it is an error msg.
175: *
176: * @param th Exception.
177: * @param session the session that generated the exception.
178: */
179: public synchronized void showErrorMessage(final Throwable th,
180: ExceptionFormatter formatter) {
181: if (th == null) {
182: throw new IllegalArgumentException("th cannot be null");
183: }
184: privateShowMessage(th, formatter, _saSetError);
185: }
186:
187: /**
188: * Show a message.
189: *
190: * @param msg The message to be shown.
191: */
192: public synchronized void showMessage(final String msg) {
193: if (msg == null) {
194: throw new IllegalArgumentException("msg cannot be null");
195: }
196: privateShowMessage(msg, _saSetMessage);
197: }
198:
199: public void showWarningMessage(String msg) {
200: if (msg == null) {
201: throw new IllegalArgumentException("msg cannot be null");
202:
203: }
204: privateShowMessage(msg, _saSetWarning);
205: }
206:
207: /**
208: * Show an error message. The controls
209: * background color will be changed to show it is an error msg.
210: * @param th Exception.
211: */
212: public synchronized void showErrorMessage(final String msg) {
213: if (msg == null) {
214: throw new IllegalArgumentException("msg cannot be null");
215: }
216: privateShowMessage(msg, _saSetError);
217: }
218:
219: /**
220: * Private method, the real implementation of the corresponding show*Message methods.
221: *
222: * @param th The throwable whose details shall be displayed.
223: * @param saSet The SimpleAttributeSet to be used for message output.
224: */
225: private void privateShowMessage(final Throwable th,
226: final ExceptionFormatter formatter,
227: final SimpleAttributeSet saSet) {
228: if (th != null) {
229:
230: String message = "";
231: if (formatter == null) {
232: message = defaultExceptionFormatter.format(th);
233: } else {
234: try {
235: message = formatter.format(th);
236: } catch (Exception e) {
237: s_log.error("Unable to format message: "
238: + e.getMessage(), e);
239: }
240: }
241: privateShowMessage(message, saSet);
242: if (s_log.isDebugEnabled()) {
243: s_log.debug("Exception message shown in MessagePanel: "
244: + message);
245: }
246: }
247: }
248:
249: /**
250: * Private method, the real implementation of the corresponding show*Message methods.
251: *
252: * @param msg The message to be displayed.
253: * @param saSet The SimpleAttributeSet to be used for message output.
254: */
255: private void privateShowMessage(final String msg,
256: final SimpleAttributeSet saSet) {
257: if (msg == null) {
258: throw new IllegalArgumentException("null Message");
259: }
260:
261: // Thread safe support for every call to this method:
262: SwingUtilities.invokeLater(new Runnable() {
263: public void run() {
264: addLine(msg, saSet);
265: }
266: });
267: }
268:
269: /**
270: * Do the real appending of text to the message panel. The last message is always highlighted.
271: * @todo Highlight not only the last message, but all messages from SQL statements which were run together.
272: *
273: * @param string The String to be appended.
274: * @param saSet The SimpleAttributeSet to be used for for the string.
275: */
276: private void append(String string, SimpleAttributeSet saSet) {
277: Document document = getStyledDocument();
278: try {
279: /////////////////////////////////////////////////////////////////////////////////
280: // Checks if the former message should be highlighted in a 'history' color.
281: if (document.getLength() >= _lastLength
282: && null != _lastMessage) {
283: SimpleAttributeSet historySaSet = _saSetHistoryBySaSet
284: .get(_lastSASet);
285: document.remove(_lastLength, _lastMessage.length());
286: document.insertString(document.getLength(),
287: _lastMessage, historySaSet);
288: }
289: //
290: ///////////////////////////////////////////////////////////////////////////////////
291:
292: _lastLength = document.getLength();
293: _lastMessage = string;
294: _lastSASet = saSet;
295:
296: document.insertString(document.getLength(), string, saSet);
297: } catch (BadLocationException ble) {
298: s_log.error(
299: "Error appending text to MessagePanel document.",
300: ble);
301: }
302: }
303:
304: /**
305: * Add the passed line to the end of the messages display. Position
306: * display so the the newly added line will be displayed.
307: *
308: * @param line The line to be added.
309: * @param saSet The SimpleAttributeSet to be used for for the string.
310: */
311: private void addLine(String line, SimpleAttributeSet saSet) {
312: if (getDocument().getLength() > 0) {
313: append("\n", saSet);
314: }
315: append(line, saSet);
316: final int len = getDocument().getLength();
317: select(len, len);
318: }
319:
320: /**
321: * Popup menu for this message panel.
322: */
323: private class MessagePanelPopupMenu extends TextPopupMenu {
324: static final long serialVersionUID = -425002646648750251L;
325:
326: public MessagePanelPopupMenu() {
327: super ();
328: add(new ClearAction());
329: }
330:
331: /**
332: * Class handles clearing the message area. Resets the background
333: * colour (to get rid of error msg colour) as well as clearing
334: * the text.
335: */
336: private class ClearAction extends BaseAction {
337: static final long serialVersionUID = 2124058843445088350L;
338:
339: protected ClearAction() {
340: super (I18N.CLEAR_LABEL);
341: }
342:
343: public void actionPerformed(ActionEvent evt) {
344: try {
345: Document doc = MessagePanel.this .getDocument();
346: doc.remove(0, doc.getLength());
347: _lastMessage = null;
348: } catch (BadLocationException ex) {
349: s_log.error("Error clearing document", ex);
350: }
351: }
352: }
353: }
354: }
|