001: package net.sourceforge.squirrel_sql.client.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.BorderLayout;
022: import java.awt.Color;
023: import java.awt.Dimension;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.awt.event.WindowAdapter;
027: import java.awt.event.WindowEvent;
028: import java.io.BufferedReader;
029: import java.io.IOException;
030: import java.io.InputStreamReader;
031: import java.net.URL;
032: import java.util.StringTokenizer;
033:
034: import javax.swing.BorderFactory;
035: import javax.swing.Icon;
036: import javax.swing.JButton;
037: import javax.swing.JDialog;
038: import javax.swing.JEditorPane;
039: import javax.swing.JLabel;
040: import javax.swing.JPanel;
041: import javax.swing.JScrollPane;
042: import javax.swing.JTabbedPane;
043: import javax.swing.Timer;
044: import javax.swing.event.ChangeEvent;
045: import javax.swing.event.ChangeListener;
046:
047: import net.sourceforge.squirrel_sql.client.IApplication;
048: import net.sourceforge.squirrel_sql.client.gui.builders.UIFactory;
049: import net.sourceforge.squirrel_sql.client.plugin.PluginInfo;
050: import net.sourceforge.squirrel_sql.client.resources.SquirrelResources;
051: import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException;
052: import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTablePanel;
053: import net.sourceforge.squirrel_sql.fw.datasetviewer.HashtableDataSet;
054: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
055: import net.sourceforge.squirrel_sql.fw.gui.PropertyPanel;
056: import net.sourceforge.squirrel_sql.fw.util.StringManager;
057: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
058: import net.sourceforge.squirrel_sql.fw.util.Utilities;
059: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
060: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
061:
062: import com.jgoodies.forms.builder.ButtonBarBuilder;
063:
064: /**
065: * About box dialog.
066: *
067: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
068: */
069: public class AboutBoxDialog extends JDialog {
070: private static final long serialVersionUID = 1L;
071:
072: /** Logger for this class. */
073: private final static ILogger s_log = LoggerController
074: .createLogger(AboutBoxDialog.class);
075:
076: /** Internationalized strings for this class. */
077: private static final StringManager s_stringMgr = StringManagerFactory
078: .getStringManager(AboutBoxDialog.class);
079:
080: /** Singleton instance of this class. */
081: private static AboutBoxDialog s_instance;
082:
083: /** The tabbed panel. */
084: private JTabbedPane _tabPnl;
085:
086: /** System panel. */
087: private SystemPanel _systemPnl;
088:
089: /** Close button for dialog. */
090: private final JButton _closeBtn = new JButton(s_stringMgr
091: .getString("AboutBoxDialog.close"));
092:
093: private AboutBoxDialog(IApplication app) {
094: super (app.getMainFrame(), s_stringMgr
095: .getString("AboutBoxDialog.about"), true);
096: setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
097: createGUI(app);
098: }
099:
100: /**
101: * Show the About Box.
102: *
103: * @param app Application API.
104: *
105: * @throws IllegalArgumentException
106: * Thrown if a <TT>null</TT> <TT>IApplication</TT> object passed.
107: */
108: public static synchronized void showAboutBox(IApplication app)
109: throws IllegalArgumentException {
110: if (app == null) {
111: throw new IllegalArgumentException(
112: "Null IApplication passed");
113: }
114: if (s_instance == null) {
115: s_instance = new AboutBoxDialog(app);
116: }
117: s_instance.setVisible(true);
118: }
119:
120: private void createGUI(IApplication app) {
121: final JPanel contentPane = new JPanel(new BorderLayout());
122: setContentPane(contentPane);
123: contentPane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4,
124: 4));
125:
126: final boolean isDebug = s_log.isDebugEnabled();
127: long start = 0;
128:
129: _tabPnl = UIFactory.getInstance().createTabbedPane();
130:
131: if (isDebug) {
132: start = System.currentTimeMillis();
133: }
134: _tabPnl.add(s_stringMgr.getString("AboutBoxDialog.about"),
135: new AboutPanel(app));
136: if (isDebug) {
137: // i18n[AboutBoxDialog.aboutpanelcreatetime=AboutPanel created in ]
138: s_log.debug(s_stringMgr
139: .getString("AboutBoxDialog.aboutpanelcreatetime")
140: + (System.currentTimeMillis() - start) + "ms");
141: }
142:
143: if (isDebug) {
144: start = System.currentTimeMillis();
145: }
146: _tabPnl.add(s_stringMgr.getString("AboutBoxDialog.credits"),
147: new CreditsPanel(app)); // i18n
148: if (isDebug) {
149: // i18n[AboutBoxDialog.creditspanelcreatetime=CreditsPanel created in ]
150: s_log.debug(s_stringMgr
151: .getString("AboutBoxDialog.creditspanelcreatetime")
152: + (System.currentTimeMillis() - start) + "ms");
153: }
154:
155: if (isDebug) {
156: start = System.currentTimeMillis();
157: }
158: _systemPnl = new SystemPanel();
159: _tabPnl.add(s_stringMgr.getString("AboutBoxDialog.system"),
160: _systemPnl);
161: if (isDebug) {
162: // i18n[AboutBoxDialog.systempanelcreatetime=SystemPanel created in ]
163: s_log.debug(s_stringMgr
164: .getString("AboutBoxDialog.systempanelcreatetime")
165: + (System.currentTimeMillis() - start) + "ms");
166: }
167:
168: _tabPnl.addChangeListener(new ChangeListener() {
169: public void stateChanged(ChangeEvent evt) {
170: String title = _tabPnl.getTitleAt(_tabPnl
171: .getSelectedIndex());
172: if (title.equals(s_stringMgr
173: .getString("AboutBoxDialog.system"))) {
174: _systemPnl._memoryPnl.startTimer();
175: } else {
176: _systemPnl._memoryPnl.stopTimer();
177: }
178: }
179: });
180:
181: contentPane.add(_tabPnl, BorderLayout.CENTER);
182:
183: // Ok button at bottom of dialog.
184: // JPanel btnsPnl = new JPanel();
185: // JButton okBtn = new JButton("OK");
186:
187: // _closeBtn.addActionListener(new ActionListener()
188: // {
189: // public void actionPerformed(ActionEvent evt)
190: // {
191: // setVisible(false);
192: // }
193: // });
194: // btnsPnl.add(okBtn);
195: // contentPane.add(btnsPnl, BorderLayout.SOUTH);
196: contentPane.add(createButtonBar(), BorderLayout.SOUTH);
197:
198: getRootPane().setDefaultButton(_closeBtn);
199:
200: addWindowListener(new WindowAdapter() {
201: public void windowActivated(WindowEvent evt) {
202: String title = _tabPnl.getTitleAt(_tabPnl
203: .getSelectedIndex());
204: if (title.equals(s_stringMgr
205: .getString("AboutBoxDialog.system"))) {
206: _systemPnl._memoryPnl.startTimer();
207: }
208: }
209:
210: public void windowDeactivated(WindowEvent evt) {
211: String title = _tabPnl.getTitleAt(_tabPnl
212: .getSelectedIndex());
213: if (title.equals(s_stringMgr
214: .getString("AboutBoxDialog.system"))) {
215: _systemPnl._memoryPnl.stopTimer();
216: }
217: }
218: });
219:
220: pack();
221: GUIUtils.centerWithinParent(this );
222: setResizable(true);
223: }
224:
225: private JPanel createButtonBar() {
226: _closeBtn.addActionListener(new ActionListener() {
227: public void actionPerformed(ActionEvent evt) {
228: setVisible(false);
229: }
230: });
231:
232: final ButtonBarBuilder builder = new ButtonBarBuilder();
233: builder.addGlue();
234: // builder.addGridded(new JButton("Alter"));
235: // builder.addRelatedGap();
236: builder.addGridded(_closeBtn);
237:
238: return builder.getPanel();
239: }
240:
241: private static final class CreditsPanel extends JScrollPane {
242: private static final long serialVersionUID = 1L;
243:
244: CreditsPanel(IApplication app) {
245: super ();
246:
247: setBorder(BorderFactory.createEmptyBorder());
248:
249: final JEditorPane credits = new JEditorPane();
250: credits.setEditable(false);
251: credits.setContentType("text/html");
252:
253: // Required with the first beta of JDK1.4.1 to stop
254: // this scrollpane from being too tall.
255: credits.setPreferredSize(new Dimension(200, 200));
256:
257: String creditsHtml = readCreditsHtml(app);
258:
259: StringBuffer pluginHtml = new StringBuffer();
260: // Get list of all plugin developers names. Allow for multiple
261: // developers for a plugin in the form "John Smith, James Brown".
262: PluginInfo[] pi = app.getPluginManager()
263: .getPluginInformation();
264: for (int i = 0; i < pi.length; ++i) {
265: pluginHtml.append("<br><b>").append(
266: pi[i].getDescriptiveName()).append(":</b>");
267:
268: String authors = pi[i].getAuthor();
269: StringTokenizer strok = new StringTokenizer(authors,
270: ",");
271: while (strok.hasMoreTokens()) {
272: pluginHtml.append("<br>").append(
273: strok.nextToken().trim());
274: }
275: String contribs = pi[i].getContributors();
276: strok = new StringTokenizer(contribs, ",");
277: while (strok.hasMoreTokens()) {
278: pluginHtml.append("<br>").append(
279: strok.nextToken().trim());
280: }
281:
282: pluginHtml.append("<br>");
283: }
284:
285: creditsHtml = creditsHtml.replaceAll("@@replace",
286: pluginHtml.toString());
287: credits.setText(creditsHtml);
288:
289: setViewportView(credits);
290: credits.setCaretPosition(0);
291: }
292:
293: private String readCreditsHtml(IApplication app) {
294: final URL url = app.getResources().getCreditsURL();
295: StringBuffer buf = new StringBuffer(2048);
296:
297: if (url != null) {
298: try {
299: BufferedReader rdr = new BufferedReader(
300: new InputStreamReader(url.openStream()));
301: try {
302: String line = null;
303: while ((line = rdr.readLine()) != null) {
304: String internationalizedLine = Utilities
305: .replaceI18NSpanLine(line,
306: s_stringMgr);
307: buf.append(internationalizedLine);
308: }
309: } finally {
310: rdr.close();
311: }
312: } catch (IOException ex) {
313: // i18n[AboutBoxDialog.error.creditsfile=Error reading credits file]
314: String errorMsg = s_stringMgr
315: .getString("AboutBoxDialog.error.creditsfile");
316: s_log.error(errorMsg, ex);
317: buf.append(errorMsg + ": " + ex.toString());
318: }
319: } else {
320: // i18n[AboutBoxDialog.error.creditsfileurl=Couldn't retrieve Credits File URL]
321: String errorMsg = s_stringMgr
322: .getString("AboutBoxDialog.error.creditsfileurl");
323: s_log.error(errorMsg);
324: buf.append(errorMsg);
325: }
326: return buf.toString();
327: }
328:
329: }
330:
331: private static final class AboutPanel extends JPanel {
332: private static final long serialVersionUID = 1L;
333:
334: AboutPanel(IApplication app) {
335: super ();
336: final SquirrelResources rsrc = app.getResources();
337: setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
338: setLayout(new BorderLayout());
339: setBackground(new Color(
340: SquirrelResources.S_SPLASH_IMAGE_BACKGROUND));
341: Icon icon = rsrc
342: .getIcon(SquirrelResources.IImageNames.SPLASH_SCREEN);
343: add(BorderLayout.CENTER, new JLabel(icon));
344:
345: VersionPane versionPane = new VersionPane(true);
346: versionPane.setBorder(BorderFactory.createEmptyBorder(10,
347: 10, 10, 10));
348: add(BorderLayout.SOUTH, versionPane);
349: }
350: }
351:
352: private static final class SystemPanel extends JPanel {
353: private static final long serialVersionUID = 1L;
354: private MemoryPanel _memoryPnl;
355:
356: SystemPanel() {
357: super ();
358: setLayout(new BorderLayout());
359: DataSetViewerTablePanel propsPnl = new DataSetViewerTablePanel();
360: propsPnl.init(null);
361: try {
362: propsPnl.show(new HashtableDataSet(System
363: .getProperties()));
364: } catch (DataSetException ex) {
365: // i18n[AboutBoxDialog.error.systemprops=Error occured displaying System Properties]
366: s_log.error(s_stringMgr
367: .getString("AboutBoxDialog.error.systemprops"),
368: ex);
369: }
370:
371: _memoryPnl = new MemoryPanel();
372: add(new JScrollPane(propsPnl.getComponent()),
373: BorderLayout.CENTER);
374: add(_memoryPnl, BorderLayout.SOUTH);
375:
376: //setPreferredSize(new Dimension(400, 400));
377: }
378: }
379:
380: private static class MemoryPanel extends PropertyPanel implements
381: ActionListener {
382: private static final long serialVersionUID = 1L;
383: private final JLabel _totalMemoryLbl = new JLabel();
384: private final JLabel _usedMemoryLbl = new JLabel();
385: private final JLabel _freeMemoryLbl = new JLabel();
386: private Timer _timer;
387:
388: MemoryPanel() {
389: super ();
390: add(new JLabel(s_stringMgr
391: .getString("AboutBoxDialog.heapsize")),
392: _totalMemoryLbl);
393: add(new JLabel(s_stringMgr
394: .getString("AboutBoxDialog.usedheap")),
395: _usedMemoryLbl);
396: add(new JLabel(s_stringMgr
397: .getString("AboutBoxDialog.freeheap")),
398: _freeMemoryLbl);
399:
400: JButton gcBtn = new JButton(s_stringMgr
401: .getString("AboutBoxDialog.gc"));
402: gcBtn.addActionListener(new ActionListener() {
403: public void actionPerformed(ActionEvent evt) {
404: System.gc();
405: }
406: });
407: add(gcBtn, new JLabel(""));
408: }
409:
410: public void removeNotify() {
411: super .removeNotify();
412: stopTimer();
413: }
414:
415: /**
416: * Update component with the current memory status.
417: *
418: * @param evt The current event.
419: */
420: public void actionPerformed(ActionEvent evt) {
421: updateMemoryStatus();
422: }
423:
424: synchronized void startTimer() {
425: if (_timer == null) {
426: // i18n[AboutBoxDialog.info.startmemtime=Starting memory timer (AboutBox)]
427: s_log.debug(s_stringMgr
428: .getString("AboutBoxDialog.info.startmemtime"));
429: //_thread = new Thread(new MemoryTimer());
430: //_thread.start();
431: updateMemoryStatus();
432: _timer = new Timer(2000, this );
433: _timer.start();
434: }
435: }
436:
437: synchronized void stopTimer() {
438: if (_timer != null) {
439: // i18n[AboutBoxDialog.info.endmemtimer=Ending memory timer (AboutBox)]
440: s_log.debug(s_stringMgr
441: .getString("AboutBoxDialog.info.endmemtimer"));
442: _timer.stop();
443: _timer = null;
444: }
445: }
446:
447: private void updateMemoryStatus() {
448: Runtime rt = Runtime.getRuntime();
449: final long totalMemory = rt.totalMemory();
450: final long freeMemory = rt.freeMemory();
451: final long usedMemory = totalMemory - freeMemory;
452: _totalMemoryLbl.setText(Utilities
453: .formatSize(totalMemory, 1));
454: _usedMemoryLbl.setText(Utilities.formatSize(usedMemory, 1));
455: _freeMemoryLbl.setText(Utilities.formatSize(freeMemory, 1));
456: }
457: }
458: }
|