001: package net.sourceforge.squirrel_sql.client.gui;
002:
003: /*
004: * Copyright (C) 2001-2003 Gerd Wagner
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
021: import net.sourceforge.squirrel_sql.fw.util.StringManager;
022: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
023: import net.sourceforge.squirrel_sql.fw.gui.ErrorDialog;
024: import net.sourceforge.squirrel_sql.client.IApplication;
025: import net.sourceforge.squirrel_sql.client.session.event.SessionEvent;
026: import net.sourceforge.squirrel_sql.client.session.event.SessionAdapter;
027: import net.sourceforge.squirrel_sql.client.resources.SquirrelResources;
028:
029: import java.awt.*;
030: import java.awt.event.ActionEvent;
031: import java.awt.event.ActionListener;
032: import java.util.*;
033: import java.text.DateFormat;
034:
035: import javax.swing.*;
036: import javax.swing.Timer;
037:
038: public class MemoryPanel extends JPanel {
039: private static final long serialVersionUID = 1L;
040:
041: /** Internationalized strings for this class. */
042: private static final StringManager s_stringMgr = StringManagerFactory
043: .getStringManager(MemoryPanel.class);
044:
045: private JProgressBar _bar;
046: private JButton _btnGarbage;
047: private JButton _btnSessionGCStatus;
048: transient private IApplication _app;
049: private HashMap<IIdentifier, MemorySessionInfo> _sessionInfosBySessionIDs = new HashMap<IIdentifier, MemorySessionInfo>();
050:
051: public MemoryPanel(IApplication app) {
052: _app = app;
053:
054: _bar = new JProgressBar();
055:
056: _bar.setStringPainted(true);
057:
058: _btnGarbage = new JButton();
059: // i18n[MemoryPanel.runGC=Run garbage collection]
060: _btnGarbage.setToolTipText(s_stringMgr
061: .getString("MemoryPanel.runGC"));
062: _btnGarbage.setBorder(null);
063:
064: ImageIcon trashIcon = _app.getResources().getIcon(
065: SquirrelResources.IImageNames.TRASH);
066: _btnGarbage.setIcon(trashIcon);
067:
068: Dimension prefButtonSize = new Dimension(trashIcon
069: .getIconWidth(), trashIcon.getIconHeight());
070:
071: _btnGarbage.setPreferredSize(prefButtonSize);
072:
073: _btnGarbage.addActionListener(new ActionListener() {
074: public void actionPerformed(ActionEvent e) {
075: System.gc();
076: }
077: });
078:
079: _btnSessionGCStatus = new JButton() {
080: private static final long serialVersionUID = 1L;
081:
082: public void paint(Graphics g) {
083: super .paint(g);
084: // paintNumWaitingGC(g);
085: }
086: };
087:
088: _btnSessionGCStatus.setBorder(null);
089:
090: updateGcStatus();
091:
092: _btnSessionGCStatus.setBorder(null);
093: _btnSessionGCStatus.setPreferredSize(prefButtonSize);
094:
095: _btnSessionGCStatus.addActionListener(new ActionListener() {
096: public void actionPerformed(ActionEvent e) {
097: showSessionGCStatus();
098: }
099: });
100:
101: JPanel pnlButtons = new JPanel(new GridLayout(1, 2, 3, 0));
102: pnlButtons.add(_btnSessionGCStatus);
103: pnlButtons.add(_btnGarbage);
104:
105: this .setLayout(new BorderLayout(5, 0));
106: this .add(pnlButtons, BorderLayout.EAST);
107: this .add(_bar, BorderLayout.CENTER);
108:
109: this .setBorder(null);
110:
111: _app.getSessionManager().addSessionListener(
112: new SessionAdapter() {
113: public void sessionClosed(SessionEvent evt) {
114: IIdentifier id = evt.getSession()
115: .getIdentifier();
116: MemorySessionInfo msi = _sessionInfosBySessionIDs
117: .get(id);
118: if (null == msi) {
119: throw new IllegalStateException(
120: "A session with ID " + id
121: + " has not been created");
122: }
123: msi.closed = new Date();
124: updateGcStatus();
125: }
126:
127: public void sessionConnected(SessionEvent evt) {
128: IIdentifier id = evt.getSession()
129: .getIdentifier();
130: if (null != _sessionInfosBySessionIDs.get(id)) {
131: throw new IllegalStateException(
132: "A session with ID "
133: + id
134: + " has already been created");
135: }
136: MemorySessionInfo msi = new MemorySessionInfo(
137: id, evt.getSession().getAlias()
138: .getName());
139: _sessionInfosBySessionIDs.put(id, msi);
140:
141: }
142:
143: public void sessionFinalized(IIdentifier sessionId) {
144: MemorySessionInfo msi = _sessionInfosBySessionIDs
145: .get(sessionId);
146: if (null == msi) {
147: throw new IllegalStateException(
148: "A session with ID " + sessionId
149: + " has not been created");
150: }
151: msi.finalized = new Date();
152: updateGcStatus();
153: }
154: });
155:
156: Timer t = new Timer(500, new ActionListener() {
157: public void actionPerformed(ActionEvent e) {
158: updateLabel();
159: }
160: });
161: t.start();
162: }
163:
164: private void updateGcStatus() {
165: SessionGCStatus gcStat = getSessionGCStatus();
166: _btnSessionGCStatus.setToolTipText(gcStat.tooltip);
167: _btnSessionGCStatus.setBackground(gcStat.color);
168: _btnSessionGCStatus.setText(gcStat.numSessAwaitingGC);
169: }
170:
171: private SessionGCStatus getSessionGCStatus() {
172: SessionGCStatus ret = new SessionGCStatus();
173:
174: int numSessAwaitingGC = 0;
175: for (Iterator<MemorySessionInfo> i = _sessionInfosBySessionIDs
176: .values().iterator(); i.hasNext();) {
177: MemorySessionInfo msi = i.next();
178: if (null != msi.closed && null == msi.finalized) {
179: ++numSessAwaitingGC;
180: }
181: }
182:
183: ret.numSessAwaitingGC = "" + numSessAwaitingGC;
184:
185: // i18n [MemoryPanel.gcStatusToolTip={0} Sessions waiting for garbage collection]
186: ret.tooltip = s_stringMgr.getString(
187: "MemoryPanel.gcStatusToolTip", new Integer(
188: ret.numSessAwaitingGC));
189:
190: ret.color = Color.yellow;
191: if (numSessAwaitingGC < 2) {
192: ret.color = Color.green;
193: } else if (numSessAwaitingGC > 4) {
194: ret.color = Color.red;
195: }
196:
197: return ret;
198:
199: }
200:
201: private void updateLabel() {
202: long total = Runtime.getRuntime().totalMemory() >> 10 >> 10;
203: long free = Runtime.getRuntime().freeMemory() >> 10 >> 10;
204: long just = total - free;
205:
206: _bar.setMinimum(0);
207: _bar.setMaximum((int) total);
208: _bar.setValue((int) just);
209:
210: Object[] params = new Long[] { Long.valueOf(just),
211: Long.valueOf(total) };
212:
213: // i18n[MemoryPanel.memSize={0} of {1} MB];
214: String msg = s_stringMgr.getString("MemoryPanel.memSize",
215: params);
216: _bar.setString(msg);
217: }
218:
219: private void showSessionGCStatus() {
220: StringBuffer[] params = new StringBuffer[] {
221: new StringBuffer(getSessionGCStatus().tooltip),
222: new StringBuffer(), new StringBuffer(),
223: new StringBuffer() };
224:
225: MemorySessionInfo[] msis = _sessionInfosBySessionIDs.values()
226: .toArray(new MemorySessionInfo[0]);
227:
228: Arrays.sort(msis);
229:
230: for (int i = 0; i < msis.length; i++) {
231: if (null != msis[i].closed && null == msis[i].finalized) {
232: params[1].append(msis[i].toString()).append('\n');
233: } else if (null == msis[i].closed) {
234: params[2].append(msis[i].toString()).append('\n');
235: } else if (null != msis[i].finalized) {
236: params[3].append(msis[i].toString()).append('\n');
237: }
238: }
239:
240: // i18n [MemoryPanel.gcStatus={0}\n\n
241: //Sessions waiting for garbage collection:\n
242: //==================================================\n
243: //{1}\n
244: //Sessions open:\n
245: //==================================================\n
246: //{2}\n
247: //Sessions garbage collected:\n
248: //==================================================\n
249: //{3}\n]
250: String msg = s_stringMgr.getString("MemoryPanel.gcStatus",
251: (Object[]) params);
252: ErrorDialog errorDialog = new ErrorDialog(_app.getMainFrame(),
253: msg);
254:
255: // i18n[MemoryPanel.statusDialogTitle=Session garbage collection status]
256: errorDialog.setTitle(s_stringMgr
257: .getString("MemoryPanel.statusDialogTitle"));
258: errorDialog.setVisible(true);
259: }
260:
261: private static class MemorySessionInfo implements
262: Comparable<MemorySessionInfo> {
263: MemorySessionInfo(IIdentifier sessionId, String aliasName) {
264: this .sessionId = sessionId;
265: this .aliasName = aliasName;
266: }
267:
268: IIdentifier sessionId;
269: String aliasName;
270: java.util.Date created = new Date();
271: java.util.Date closed;
272: java.util.Date finalized;
273:
274: public String toString() {
275: DateFormat df = DateFormat.getInstance();
276:
277: Object[] params = new Object[] { sessionId, aliasName,
278: df.format(created),
279: null == closed ? "" : df.format(closed),
280: null == finalized ? "" : df.format(finalized) };
281:
282: if (null != closed && null == finalized) {
283: // i18n[MemoryPanel.sessionInfo.toString1=Session: ID={0}, Alias={1}: created at {2}, closed at {3}]
284: return s_stringMgr.getString(
285: "MemoryPanel.sessionInfo.toString1", params);
286: } else if (null == closed) {
287: // i18n[MemoryPanel.sessionInfo.toString2=Session: ID={0}, Alias={1}: created at {2}]
288: return s_stringMgr.getString(
289: "MemoryPanel.sessionInfo.toString2", params);
290: } else if (null != finalized) {
291: // i18n[MemoryPanel.sessionInfo.toString3=Session: ID={0}, Alias={1}: created at {2}, closed at {3}, finalized at {4}]
292: return s_stringMgr.getString(
293: "MemoryPanel.sessionInfo.toString3", params);
294: } else {
295: throw new IllegalStateException("Unknown Session state");
296: }
297: }
298:
299: public int compareTo(MemorySessionInfo other) {
300: return Integer.valueOf(sessionId.toString()).compareTo(
301: Integer.valueOf(other.sessionId.toString()));
302: }
303:
304: /**
305: * @see java.lang.Object#hashCode()
306: */
307: @Override
308: public int hashCode() {
309: final int prime = 31;
310: int result = 1;
311: result = prime * result
312: + ((sessionId == null) ? 0 : sessionId.hashCode());
313: return result;
314: }
315:
316: /**
317: * @see java.lang.Object#equals(java.lang.Object)
318: */
319: @Override
320: public boolean equals(Object obj) {
321: if (this == obj)
322: return true;
323: if (obj == null)
324: return false;
325: if (getClass() != obj.getClass())
326: return false;
327: final MemorySessionInfo other = (MemorySessionInfo) obj;
328: if (sessionId == null) {
329: if (other.sessionId != null)
330: return false;
331: } else if (!sessionId.equals(other.sessionId))
332: return false;
333: return true;
334: }
335:
336: }
337:
338: private static class SessionGCStatus {
339: String tooltip;
340: Color color;
341: String numSessAwaitingGC;
342: }
343:
344: }
|