001: package net.sourceforge.squirrel_sql.client.gui;
002:
003: /*
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: import net.sourceforge.squirrel_sql.client.IApplication;
019: import net.sourceforge.squirrel_sql.client.mainframe.action.ViewLogsCommand;
020: import net.sourceforge.squirrel_sql.client.resources.SquirrelResources;
021: import net.sourceforge.squirrel_sql.fw.gui.ErrorDialog;
022: import net.sourceforge.squirrel_sql.fw.util.log.ILoggerListener;
023: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
024: import net.sourceforge.squirrel_sql.fw.util.StringManager;
025: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
026:
027: import javax.swing.*;
028: import java.awt.*;
029: import java.awt.event.ActionEvent;
030: import java.awt.event.ActionListener;
031: import java.awt.event.MouseAdapter;
032: import java.awt.event.MouseEvent;
033: import java.util.Vector;
034: import java.util.Date;
035: import java.text.DateFormat;
036:
037: /**
038: * This is the Status bar's Log panel.
039: * It recieves all logs through the ILoggerListener interface.
040: * It updates its status all 200 millis, see _displayLastLogTimer.
041: *
042: * The traffic lights color of the last log is displayed on the JButton _btnLastLog.
043: * If no new log arrives the last log color is displayed for 5000 millis and is the replaced
044: * by the "white" icon, see _whiteIconTimer. This allows the user to have an eye an the logs
045: * without much disturbance.
046: *
047: */
048: public class LogPanel extends JPanel {
049: private static final long serialVersionUID = -2886311809367056785L;
050:
051: private static final StringManager s_stringMgr = StringManagerFactory
052: .getStringManager(MemoryPanel.class);
053:
054: transient private SquirrelResources _resources;
055:
056: private static final int LOG_TYPE_INFO = 0;
057: private static final int LOG_TYPE_WARN = 1;
058: private static final int LOG_TYPE_ERROR = 2;
059:
060: private JButton _btnLastLog = new JButton();
061: private JLabel _lblLogInfo = new JLabel();
062: private JButton _btnViewLogs = new JButton();
063:
064: private Timer _displayLastLogTimer;
065: private Timer _whiteIconTimer;
066:
067: private final Vector<LogData> _logsDuringDisplayDelay = new Vector<LogData>();
068: transient private LogData _curlogToDisplay;
069: transient private IApplication _app;
070:
071: transient private LogStatistics _statistics = new LogStatistics();
072:
073: public LogPanel(IApplication app) {
074: _app = app;
075: _resources = _app.getResources();
076: createGui();
077:
078: setIconForCurLogType();
079:
080: _whiteIconTimer = new Timer(5000, new ActionListener() {
081: public void actionPerformed(ActionEvent e) {
082: _btnLastLog
083: .setIcon(_resources
084: .getIcon(SquirrelResources.IImageNames.WHITE_GEM));
085: }
086: });
087:
088: _whiteIconTimer.setRepeats(false);
089:
090: int displayDelay = 200;
091: _displayLastLogTimer = new Timer(displayDelay,
092: new ActionListener() {
093: public void actionPerformed(ActionEvent e) {
094: updatePanel();
095: }
096: });
097:
098: _displayLastLogTimer.setRepeats(false);
099:
100: LoggerController.addLoggerListener(new ILoggerListener() {
101: public void info(Class<?> source, Object message) {
102: _statistics.setInfoCount(_statistics._infoCount + 1);
103: addLog(LOG_TYPE_INFO, source.getName(), message, null);
104: }
105:
106: public void info(Class<?> source, Object message,
107: Throwable th) {
108: _statistics.setInfoCount(_statistics._infoCount + 1);
109: addLog(LOG_TYPE_INFO, source.getName(), message, th);
110: }
111:
112: public void warn(Class<?> source, Object message) {
113: _statistics.setWarnCount(_statistics._warnCount + 1);
114: addLog(LOG_TYPE_WARN, source.getName(), message, null);
115: }
116:
117: public void warn(Class<?> source, Object message,
118: Throwable th) {
119: _statistics.setWarnCount(_statistics._warnCount + 1);
120: addLog(LOG_TYPE_WARN, source.getName(), message, th);
121: }
122:
123: public void error(Class<?> source, Object message) {
124: _statistics.setErrorCount(_statistics._errorCount + 1);
125: addLog(
126: LOG_TYPE_ERROR,
127: source.getName(),
128: message,
129: message instanceof Throwable ? (Throwable) message
130: : null);
131: }
132:
133: public void error(Class<?> source, Object message,
134: Throwable th) {
135: _statistics.setErrorCount(_statistics._errorCount + 1);
136: addLog(LOG_TYPE_ERROR, source.getName(), message, th);
137: }
138: });
139:
140: _btnLastLog.addMouseListener(new MouseAdapter() {
141: public void mouseEntered(MouseEvent e) {
142: setIconForCurLogType();
143: }
144:
145: public void mouseExited(MouseEvent e) {
146: if (false == _whiteIconTimer.isRunning()) {
147: _btnLastLog
148: .setIcon(_resources
149: .getIcon(SquirrelResources.IImageNames.WHITE_GEM));
150: }
151: }
152: });
153:
154: _btnLastLog.addActionListener(new ActionListener() {
155: public void actionPerformed(ActionEvent e) {
156: showLogInDialog();
157: }
158: });
159:
160: _btnViewLogs.addActionListener(new ActionListener() {
161: public void actionPerformed(ActionEvent e) {
162: new ViewLogsCommand(_app).execute();
163: }
164: });
165:
166: }
167:
168: private void createGui() {
169: setLayout(new BorderLayout(5, 0));
170:
171: ImageIcon viewLogsIcon = _resources
172: .getIcon(SquirrelResources.IImageNames.LOGS);
173: _btnViewLogs.setIcon(viewLogsIcon);
174:
175: Dimension prefButtonSize = new Dimension(viewLogsIcon
176: .getIconWidth(), viewLogsIcon.getIconHeight());
177: _btnLastLog.setPreferredSize(prefButtonSize);
178: _btnViewLogs.setPreferredSize(prefButtonSize);
179:
180: _btnLastLog.setBorder(null);
181: _btnViewLogs.setBorder(null);
182:
183: JPanel pnlButtons = new JPanel(new GridLayout(1, 2, 3, 0));
184: pnlButtons.add(_btnLastLog);
185: pnlButtons.add(_btnViewLogs);
186:
187: add(pnlButtons, BorderLayout.EAST);
188: add(_lblLogInfo, BorderLayout.CENTER);
189:
190: // i18n[LogPanel.viewLastLog=Press to view last log entry]
191: _btnLastLog.setToolTipText(s_stringMgr
192: .getString("LogPanel.viewLastLog"));
193:
194: // i18n[LogPanel.openLogs=Press to open logs]
195: _btnViewLogs.setToolTipText(s_stringMgr
196: .getString("LogPanel.openLogs"));
197: }
198:
199: private void showLogInDialog() {
200: if (null != _curlogToDisplay) {
201: Object[] params = new Object[] { _curlogToDisplay.source,
202: _curlogToDisplay.logTime, _curlogToDisplay.message };
203:
204: // i18n[LogPanel.logMsg=Logged by {0} at {1}:\n\n {2}]
205: String extMsg = s_stringMgr.getString("LogPanel.logMsg",
206: params);
207: ErrorDialog errorDialog = new ErrorDialog(_app
208: .getMainFrame(), extMsg, _curlogToDisplay.throwable);
209:
210: String title;
211:
212: switch (_curlogToDisplay.logType) {
213: case LOG_TYPE_INFO:
214: // i18n[LogPanel.titleInfo=Last log entry (Entry type: Info)]
215: title = s_stringMgr.getString("LogPanel.titleInfo");
216: break;
217: case LOG_TYPE_WARN:
218: // i18n[LogPanel.titleWarn=Last log entry (Entry type: Warning)]
219: title = s_stringMgr.getString("LogPanel.titleWarn");
220: break;
221: case LOG_TYPE_ERROR:
222: // i18n[LogPanel.titleError=Last log entry (Entry type: ERROR)]
223: title = s_stringMgr.getString("LogPanel.titleError");
224: break;
225: default:
226: // i18n[LogPanel.titleUnknown=Last log entry (Entry type: Unknown)]
227: title = s_stringMgr.getString("LogPanel.titleUnknown");
228: break;
229: }
230:
231: errorDialog.setTitle(title);
232: errorDialog.setVisible(true);
233: }
234: }
235:
236: private void addLog(int logType, String source, Object message,
237: Throwable t) {
238: LogData log = new LogData();
239: log.logType = logType;
240: log.source = source;
241: log.message = message;
242: log.throwable = t;
243:
244: synchronized (_logsDuringDisplayDelay) {
245: _logsDuringDisplayDelay.add(log);
246: }
247:
248: _displayLastLogTimer.restart();
249: }
250:
251: private void updatePanel() {
252: LogData[] logs;
253: synchronized (_logsDuringDisplayDelay) {
254: logs = _logsDuringDisplayDelay
255: .toArray(new LogData[_logsDuringDisplayDelay.size()]);
256: _logsDuringDisplayDelay.clear();
257: }
258:
259: _curlogToDisplay = null;
260: for (int i = 0; i < logs.length; i++) {
261: if (null == _curlogToDisplay) {
262: _curlogToDisplay = logs[i];
263: } else if (_curlogToDisplay.logType <= logs[i].logType) {
264: _curlogToDisplay = logs[i];
265: }
266: }
267:
268: _lblLogInfo.setText(_statistics.toString());
269:
270: setIconForCurLogType();
271:
272: _whiteIconTimer.restart();
273: }
274:
275: private void setIconForCurLogType() {
276: if (null == _curlogToDisplay) {
277: _btnLastLog.setIcon(_resources
278: .getIcon(SquirrelResources.IImageNames.WHITE_GEM));
279: return;
280: }
281:
282: switch (_curlogToDisplay.logType) {
283: case LOG_TYPE_INFO:
284: _btnLastLog.setIcon(_resources
285: .getIcon(SquirrelResources.IImageNames.GREEN_GEM));
286: break;
287: case LOG_TYPE_WARN:
288: _btnLastLog.setIcon(_resources
289: .getIcon(SquirrelResources.IImageNames.YELLOW_GEM));
290: break;
291: case LOG_TYPE_ERROR:
292: _btnLastLog.setIcon(_resources
293: .getIcon(SquirrelResources.IImageNames.RED_GEM));
294: break;
295: }
296: }
297:
298: private static class LogData {
299: int logType = -1;
300: Object message = null;
301: Throwable throwable = null;
302: String source;
303: String logTime;
304:
305: public LogData() {
306: logTime = DateFormat.getInstance().format(new Date());
307: }
308:
309: }
310:
311: private static class LogStatistics {
312: private int _errorCount;
313: private int _warnCount;
314: private int _infoCount;
315:
316: private String _toString = "";
317:
318: public LogStatistics() {
319: updateToString();
320: }
321:
322: public String toString() {
323: return _toString;
324: }
325:
326: void setErrorCount(int errorCount) {
327: this ._errorCount = errorCount;
328: updateToString();
329: }
330:
331: private void updateToString() {
332: Object[] params = new Integer[] {
333: Integer.valueOf(_errorCount),
334: Integer.valueOf(_warnCount),
335: Integer.valueOf(_infoCount), };
336: // i18n[LogPanel.logInfoLabel=Logs: Errors {0}, Warnings {1}, Infos {2}]
337: _toString = s_stringMgr.getString("LogPanel.logInfoLabel",
338: params);
339: }
340:
341: void setWarnCount(int warnCount) {
342: this ._warnCount = warnCount;
343: updateToString();
344: }
345:
346: void setInfoCount(int infoCount) {
347: this._infoCount = infoCount;
348: updateToString();
349: }
350: }
351:
352: }
|