/*
 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.ui;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

import sun.jvm.hotspot.debugger.*;

public class ProcessListPanel extends JPanel {
  private Debugger           dbg;
  private AbstractTableModel dataModel;
  private java.util.List     els;
  private boolean            sortByName   = true;
  private boolean            sortReversed = false;
  private javax.swing.Timer  timer;
  private JTable             table;

  
Takes a Debugger in constructor. Updates the list once during construction; list can be updated automatically by "starting" the panel.
/** Takes a Debugger in constructor. Updates the list once during construction; list can be updated automatically by "starting" the panel. */
public ProcessListPanel(Debugger dbg) { super(); this.dbg = dbg; update(); dataModel = new AbstractTableModel() { public int getColumnCount() { return 2; } public int getRowCount() { return els.size(); } public String getColumnName(int col) { switch (col) { case 0: return "Process Name"; case 1: return "Process ID"; default: throw new RuntimeException("Index " + col + " out of bounds"); } } public Object getValueAt(int row, int col) { ProcessInfo info = (ProcessInfo) els.get(row); switch (col) { case 0: return info.getName(); case 1: return new Integer(info.getPid()); default: throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds"); } } }; // Create user interface setLayout(new BorderLayout()); table = new JTable(dataModel); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JTableHeader header = table.getTableHeader(); header.setReorderingAllowed(false); table.setRowSelectionAllowed(true); table.setColumnSelectionAllowed(false); // Provide sorting in similar fashion to Task Manager header.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { int viewColumn = table.getColumnModel().getColumnIndexAtX(e.getX()); int column = table.convertColumnIndexToModel(viewColumn); if (column != -1) { boolean newSortByName = (column == 0); if (newSortByName == sortByName) { // Switch sense of "reversed" instead sortReversed = !sortReversed; } else { sortByName = newSortByName; sortReversed = false; } // Keep the current selection if possible int i = table.getSelectedRow(); int pid = getPid(els, i); sort(els); i = findPid(els, pid); dataModel.fireTableDataChanged(); if ((i >= 0) || (els.size() > 0)) { if (i >= 0) { table.setRowSelectionInterval(i, i); } else { table.setRowSelectionInterval(0, 0); } } } } }); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane, BorderLayout.CENTER); if (els.size() > 0) { table.setRowSelectionInterval(0, 0); } }
Set update interval for automatic updating of the process list
/** Set update interval for automatic updating of the process list */
public void setAutoUpdateInterval(int millis) { getTimer().setDelay(millis); }
Start auto updating of the panel
/** Start auto updating of the panel */
public void start() { getTimer().start(); }
Stop auto updating of the panel
/** Stop auto updating of the panel */
public void stop() { getTimer().stop(); }
Call this to update the panel's notion of the process list
/** Call this to update the panel's notion of the process list */
public synchronized void update() { if (!dbg.hasProcessList()) { throw new RuntimeException("ProcessListPanel requires that debugger supports getProcessList()"); } java.util.List newEls = dbg.getProcessList(); sort(newEls); if (table != null) { // Keep the current selection if possible int i = table.getSelectedRow(); int pid = getPid(els, i); i = findPid(newEls, pid); els = newEls; dataModel.fireTableDataChanged(); if ((i >= 0) || (els.size() > 0)) { if (i >= 0) { table.setRowSelectionInterval(i, i); } else { table.setRowSelectionInterval(0, 0); } } } else { els = newEls; } }
Call this to get the selected ProcessInfo, or null if none selected
/** Call this to get the selected ProcessInfo, or null if none selected */
public synchronized ProcessInfo getSelectedProcess() { int i = table.getSelectedRow(); if (i < 0) { return null; } return (ProcessInfo) els.get(i); } private synchronized void sort(java.util.List els) { Comparator c; if (sortByName) { c = new Comparator() { public int compare(Object o1, Object o2) { int scale = (sortReversed ? -1 : 1); return scale * ((ProcessInfo) o1).getName().compareToIgnoreCase(((ProcessInfo) o2).getName()); } }; } else { c = new Comparator() { public int compare(Object o1, Object o2) { int scale = (sortReversed ? -1 : 1); int pid1 = ((ProcessInfo) o1).getPid(); int pid2 = ((ProcessInfo) o2).getPid(); int ret; if (pid1 < pid2) ret = -1; else if (pid1 == pid2) ret = 0; else ret = 1; return ret * scale; } }; } Collections.sort(els, c); } private javax.swing.Timer getTimer() { if (timer == null) { timer = new javax.swing.Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { update(); } }); } return timer; } private synchronized int getPid(java.util.List els, int index) { return ((ProcessInfo) els.get(index)).getPid(); } private synchronized int findPid(java.util.List els, int pid) { for (int i = 0; i < els.size(); i++) { ProcessInfo info = (ProcessInfo) els.get(i); if (info.getPid() == pid) { return i; } } return -1; } }