package org.freehep.swing.table.test; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; import junit.framework.TestCase; import org.freehep.swing.popup.PopupListener; import org.freehep.swing.table.DefaultSortableTableModel; import org.freehep.swing.table.TableColumnSelector; import org.freehep.swing.table.TableSorter; /** * A Test routine for the Table Sorter. * Note this uses the /proc filesystem so will only work on Unix (if there) * @author Tony Johnson */ public class TopCpu extends TestCase { private static File proc = new File("/proc"); private static List processes() { List result = new ArrayList(); String[] list = proc.list(); for (int i=0; i<list.length; i++) { try { int n = Integer.parseInt(list[i]); File stat = new File(proc,n+"/stat"); try { BufferedReader reader = new BufferedReader(new FileReader(stat)); String line = reader.readLine(); reader.close(); result.add(new Process(line)); } catch (IOException x) { // too bad; } } catch (NumberFormatException x) { // OK, not a process } } return result; } public void testMain() { TopCpu.main(null); } /** * @param args the command line arguments */ public static void main(String[] args) { if (!proc.exists()) throw new RuntimeException("/proc not found, not Unix?"); List l = processes(); final ProcessTableModel model = new ProcessTableModel(l); TableColumnSelector selector = new TableColumnSelector(model); DefaultSortableTableModel sm = new DefaultSortableTableModel(selector.getFilteredTableModel()); JTable table = new JTable(sm); table.addMouseListener(new PopupListener(selector.createPopupMenu())); new TableSorter(table); JFrame frame = new JFrame("Process List"); frame.setContentPane(new JScrollPane(table)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); // Main thread continues in background to update display //Thread.currentThread().setDaemon(true); for (;;) { try { Thread.sleep(1000); final List ll = processes(); Runnable r = new Runnable() { public void run() { model.update(ll); } }; SwingUtilities.invokeAndWait(r); } catch (Exception x) { x.printStackTrace(); } } } private static class Process { private int pid; private String exe; private String state; private int utime; private int stime; private int dutime; private int dstime; private int prio; Process(String data) { String[] tokens = data.split("\\s+"); pid = Integer.parseInt(tokens[0]); exe = tokens[1]; state = tokens[2]; utime = Integer.parseInt(tokens[13]); stime = Integer.parseInt(tokens[14]); prio = Integer.parseInt(tokens[17]); } public String toString() { return pid+" "+exe+" "+state+" "+utime+" "+stime+" "+prio; } public boolean equals(Object o) { if (o instanceof Process) { Process that = (Process) o; return this.pid == that.pid && this.dutime == that.dutime && this.dstime == that.dstime && this.prio == that.prio && this.exe.equals(that.exe) && this.state.equals(that.state); } else return false; } } private static class ProcessTableModel extends AbstractTableModel { private List processes; private String[] headers = { "pid", "exe", "state", "utime", "stime", "prio" }; private Class[] types = { Integer.class, String.class, String.class, Integer.class , Integer.class, Integer.class }; ProcessTableModel(List processes) { this.processes = processes; } void update(List newProcesses) { ListIterator i1 = processes.listIterator(); ListIterator i2 = newProcesses.listIterator(); int row = 0; int pid1 = 0; int pid2 = 0; Process process1 = null; Process process2 = null; boolean advance1 = true; boolean advance2 = true; for (;;) { if (advance1) { if (i1.hasNext()) { process1 = (Process) i1.next(); pid1 = process1.pid; } else pid1 = Integer.MAX_VALUE; } if (advance2) { if (i2.hasNext()) { process2 = (Process) i2.next(); pid2 = process2.pid; } else pid2 = Integer.MAX_VALUE; } if (pid1 == Integer.MAX_VALUE && pid2 == Integer.MAX_VALUE) break; if (pid1 < pid2) { i1.remove(); fireTableRowsDeleted(row,row); advance1 = true; advance2 = false; } else if (pid1 == pid2) { process2.dutime = process2.utime - process1.utime; process2.dstime = process2.stime - process1.stime; if (!process1.equals(process2)) { i1.set(process2); fireTableRowsUpdated(row,row); } row++; advance1 = advance2 = true; } else if (pid1 > pid2) { i1.add(process2); fireTableRowsInserted(row,row); row++; advance1 = false; advance2 = true; } } } public int getColumnCount() { return headers.length; } public Class getColumnClass(int col) { return types[col]; } public String getColumnName(int col) { return headers[col]; } public int getRowCount() { return processes.size(); } public Object getValueAt(int row, int col) { Process process = (Process) processes.get(row); switch (col) { case 0: return new Integer(process.pid); case 1: return process.exe; case 2: return process.state; case 3: return new Integer(process.dutime); case 4: return new Integer(process.dstime); case 5: return new Integer(process.prio); default: return null; } } } }