001: /* ====================================================================
002: * The QueryForm License, Version 1.1
003: *
004: * Copyright (c) 1998 - 2003 David F. Glasser. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by
022: * David F. Glasser."
023: * Alternately, this acknowledgment may appear in the software itself,
024: * if and wherever such third-party acknowledgments normally appear.
025: *
026: * 4. The names "QueryForm" and "David F. Glasser" must
027: * not be used to endorse or promote products derived from this
028: * software without prior written permission. For written
029: * permission, please contact dglasser@pobox.com.
030: *
031: * 5. Products derived from this software may not be called "QueryForm",
032: * nor may "QueryForm" appear in their name, without prior written
033: * permission of David F. Glasser.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL DAVID F. GLASSER, THE APACHE SOFTWARE
039: * FOUNDATION OR ITS CONTRIBUTORS, OR ANY AUTHORS OR DISTRIBUTORS
040: * OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This product includes software developed by the
051: * Apache Software Foundation (http://www.apache.org/).
052: *
053: * ====================================================================
054: *
055: * $Source: /cvsroot/qform/qform/src/org/glasser/swing/SystemPanel.java,v $
056: * $Revision: 1.4 $
057: * $Author: dglasser $
058: * $Date: 2005/05/23 01:59:28 $
059: *
060: * --------------------------------------------------------------------
061: */
062: package org.glasser.swing;
063:
064: import javax.swing.*;
065: import javax.swing.border.*;
066: import javax.swing.table.*;
067: import java.awt.*;
068: import java.text.*;
069: import java.util.*;
070: import org.glasser.swing.*;
071: import org.glasser.swing.table.*;
072: import org.glasser.util.*;
073:
074: /**
075: * This is a panel that displays the system properties of a
076: * running app, along with the memory usage and the program startup time
077: * (if a Date instance is passed to the constructor.)
078: *
079: * @author Dave Glasser
080: */
081: public class SystemPanel extends JPanel {
082:
083: JTable propsTable = new JTable();
084:
085: PushButtonTableHeader tableHeader = new PushButtonTableHeader();
086:
087: final ListTableModel model = new ListTableModel(
088: new ArrayColumnManager(new String[] { "System Property",
089: "Value" },
090: new Class[] { String.class, String.class }), null);
091:
092: Date runningSince = null;
093:
094: JLabel lblRunningSince = new JLabel();
095: JLabel lblTotalMem = new JLabel();
096: JLabel lblFreeMem = new JLabel();
097:
098: NumberFormat bytesFormatter = NumberFormat.getInstance();
099:
100: Object[][] formConfig = {
101:
102: { lblTotalMem, "Total program memory (bytes): " },
103: { lblFreeMem, "Free program memory (bytes): " },
104: { lblRunningSince, "Up since: " } };
105:
106: Object[][] formConfig2 = {
107: { "Total program memory (bytes): ", lblTotalMem },
108: { "Free program memory (bytes): ", lblFreeMem } };
109:
110: /**
111: * This is the Thread that updates the memory usage stats every half-second.
112: */
113: private Thread memThread = new Thread() {
114: public void run() {
115: while (true) {
116: try {
117: sleep(2000);
118: } catch (InterruptedException ex) {
119: }
120: if (isVisible() == false)
121: continue;
122: lblTotalMem.setText(bytesFormatter.format(Runtime
123: .getRuntime().totalMemory()));
124: lblFreeMem.setText(bytesFormatter.format(Runtime
125: .getRuntime().freeMemory()));
126: }
127: }
128: };
129:
130: public SystemPanel() {
131: this (null);
132: }
133:
134: /**
135: * If a Date is passed to this constructor, it will be displayed
136: * on the panel with the label "Up since:". Otherwise it won't be.
137: *
138: * @param runningSince a java.util.Date that is used to indicate when the app
139: * was started.
140: *
141: */
142: public SystemPanel(Date runningSince) {
143:
144: this .runningSince = runningSince;
145:
146: setLayout(new BorderLayout());
147:
148: // top subpanel
149: JLabel label = new JLabel("System Properties");
150: label.setBorder(new EmptyBorder(0, 0, 5, 10));
151: add(label, BorderLayout.NORTH);
152:
153: // system properties table.
154: propsTable.setModel(model);
155:
156: refreshSystemPropertiesTable();
157:
158: // make the table "push and sort".
159: propsTable.setTableHeader(tableHeader);
160:
161: // make the sorts case-insensitive
162: model.setColumnComparator(0, String.CASE_INSENSITIVE_ORDER);
163: model.setColumnComparator(1, String.CASE_INSENSITIVE_ORDER);
164:
165: // this code is needed for Java 1.2 and earlier.
166: TableColumnModel tcm = propsTable.getColumnModel();
167: for (int j = 0; j < tcm.getColumnCount(); j++) {
168: TableColumn tc = tcm.getColumn(j);
169: tc.setHeaderRenderer(tableHeader.getDefaultRenderer());
170: }
171:
172: tableHeader.addMouseListener(new ListTableModelSorter());
173:
174: add(new JScrollPane(propsTable), BorderLayout.CENTER);
175:
176: // bottom panel
177: if (runningSince != null) {
178: lblRunningSince.setText(runningSince.toString());
179: } else {
180: formConfig = formConfig2;
181: }
182:
183: lblTotalMem.setText(bytesFormatter.format(Runtime.getRuntime()
184: .totalMemory()));
185: lblFreeMem.setText(bytesFormatter.format(Runtime.getRuntime()
186: .freeMemory()));
187:
188: lblRunningSince.setHorizontalAlignment(JLabel.RIGHT);
189: lblTotalMem.setHorizontalAlignment(JLabel.RIGHT);
190: lblFreeMem.setHorizontalAlignment(JLabel.RIGHT);
191:
192: JPanel bottomPanel = new JPanel();
193: bottomPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
194: bottomPanel.setLayout(new GridBagLayout());
195:
196: GridBagConstraints gc = new GridBagConstraints();
197:
198: Font smallFont = new Font("SansSerif", Font.PLAIN, 11);
199:
200: for (int j = 0; j < formConfig.length; j++) {
201: Object[] row = formConfig[j];
202: gc.weightx = 0;
203: gc.gridx = 0;
204: gc.gridy = j;
205: gc.fill = gc.BOTH;
206: gc.ipadx = 5;
207: bottomPanel.add(new JLabel((String) row[1]), gc);
208: gc.gridx = 1;
209: ((JComponent) row[0]).setFont(smallFont);
210: bottomPanel.add((JComponent) row[0], gc);
211: gc.gridx = 2;
212: gc.weightx = 1;
213: bottomPanel.add(new JLabel(), gc);
214: }
215:
216: add(bottomPanel, BorderLayout.SOUTH);
217:
218: memThread.start();
219:
220: }
221:
222: public void refreshSystemPropertiesTable() {
223: Properties props = System.getProperties();
224:
225: ArrayList list = new ArrayList(props.size());
226:
227: for (Enumeration enumer = props.propertyNames(); enumer
228: .hasMoreElements();) {
229: String name = (String) enumer.nextElement();
230: String val = props.getProperty(name);
231: if (name.equals("line.separator")) {
232: if (val != null) {
233: if (val.equals("\r\n")) {
234: val = "\\r\\n";
235: } else if (val.equals("\n")) {
236: val = "\\n";
237: }
238: }
239: }
240:
241: list.add(new Object[] { name, val });
242:
243: }
244:
245: model.setDataList(list);
246:
247: // remove any existing up or down arrow icons from the table header
248: tableHeader.setSortedColumn(-1, false);
249: }
250:
251: /**
252: * Returns a String containing all of the displayed information, for logging
253: * or other purposes. The platform-specific line-separator is used.
254: */
255: public String getInfoAsString() {
256: return getInfoAsString(null);
257: }
258:
259: /**
260: * Returns a String containing all of the displayed information, for logging
261: * or other purposes.
262: *
263: * @param newline a String containing the character or characters that will be
264: * used as a line separator.
265: */
266: public String getInfoAsString(String newline) {
267: if (newline == null)
268: newline = System.getProperty("line.separator");
269: StringBuffer buffer = new StringBuffer(4096);
270: buffer.append("SYSTEM PROPERTIES").append(newline);
271: ArrayList propList = (ArrayList) ((ArrayList) model
272: .getDataList()).clone();
273: for (int j = 0; j < propList.size(); j++) {
274: Object[] row = (Object[]) propList.get(j);
275: buffer.append(row[0]).append("=").append(trim(row[1]))
276: .append(newline);
277: }
278:
279: buffer.append(newline);
280: buffer.append("Total program memory (bytes): ");
281: buffer.append(lblTotalMem.getText()).append(newline);
282: buffer.append("Free program memory (bytes): ");
283: buffer.append(lblFreeMem.getText()).append(newline);
284: buffer.append("Up since: ");
285: buffer.append(lblRunningSince.getText()).append(newline);
286:
287: return buffer.toString();
288: }
289:
290: private String trim(Object o) {
291: if (o == null)
292: return null;
293: return o.toString().trim();
294: }
295:
296: /**
297: * Launches a small test program.
298: */
299: public static void main(String[] args) throws Exception {
300: JFrame frame = new JFrame();
301: frame.setDefaultCloseOperation(3);
302: SystemPanel systemPanel = new SystemPanel(new Date());
303: frame.setContentPane(systemPanel);
304: frame.pack();
305: GUIHelper.centerWindowOnScreen(frame);
306: frame.setVisible(true);
307:
308: System.out.println(systemPanel.getInfoAsString());
309: }
310:
311: }
|