[Mc4j-cvs] mc4j/src/org/mc4j/jre15/components LogManager.java,NONE,1.1 ThreadMBeanThreadBrowserCompo
Brought to you by:
ghinkl
From: Greg H. <gh...@us...> - 2006-05-22 02:38:59
|
Update of /cvsroot/mc4j/mc4j/src/org/mc4j/jre15/components In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv32360/src/org/mc4j/jre15/components Modified Files: ThreadMBeanThreadBrowserComponent.java ThreadsViewComponent.java Added Files: LogManager.java Log Message: Visual tweaks --- NEW FILE: LogManager.java --- /* * JBoss, Home of Professional Open Source */ package org.mc4j.jre15.components; import org.mc4j.console.dashboard.components.BeanComponent; import org.mc4j.ems.connection.bean.EmsBean; import org.jdesktop.swingx.JXTreeTable; import org.jdesktop.swingx.autocomplete.ComboBoxCellEditor; import org.jdesktop.swingx.treetable.DefaultTreeTableModel; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import javax.swing.*; import javax.swing.table.TableCellEditor; import java.util.*; import java.util.List; import java.util.logging.LoggingMXBean; import java.util.logging.Logger; import java.util.logging.Level; import java.awt.*; /** * @author <a href="mailto:gh...@jb...">Greg Hinkle</a> */ public class LogManager extends JPanel implements BeanComponent { LoggingMXBean loggingBean; JXTreeTable treeTable; LoggerInfoTreeTableModel model; Map<String, String> parents = new HashMap<String, String>(); Map<String,List<String>> children = new HashMap<String, List<String>>(); Map<String, DefaultMutableTreeNode> nodes = new HashMap<String, DefaultMutableTreeNode>(); Map<String, String> levels = new HashMap<String, String>(); public void setBean(EmsBean emsBean) { loggingBean = (LoggingMXBean) emsBean.getProxy(java.util.logging.LoggingMXBean.class); } public void setContext(Map context) { model = new LoggerInfoTreeTableModel(); List<String> names = loggingBean.getLoggerNames(); DefaultMutableTreeNode root = new DefaultMutableTreeNode(""); model.setRoot(root); nodes.put("",root); // Go through and map the parents for (String name : names) { String parent = loggingBean.getParentLoggerName(name); System.out.println(name + " -> " + parent); if (!"".equals(name)) // The jdk returns a "" -> "" mapping for some stupid reason, lets ignore it with a special case parents.put(name, parent); } children = new HashMap<String, List<String>>(); Iterator iter = parents.entrySet().iterator(); while (iter.hasNext()) { Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next(); if (!children.containsKey(entry.getValue())) { List<String> childList = new ArrayList<String>(); childList.add(entry.getKey()); children.put(entry.getValue(),childList); } else { List<String> childList = children.get(entry.getValue()); childList.add(entry.getKey()); } } loadChildren(((DefaultMutableTreeNode)model.getRoot()).getUserObject().toString()); levels.put("",loggingBean.getLoggerLevel("")); // Load the root level // Load the levels for (String name : nodes.keySet()) { levels.put(name, loggingBean.getLoggerLevel(name)); } treeTable = new JXTreeTable(model); treeTable.setRootVisible(true); JComboBox b = new JComboBox(new Object[] { Level.SEVERE, Level.WARNING, Level.INFO, Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST }); treeTable.getColumnExt(1).setCellEditor(new ComboBoxCellEditor(b)); setLayout(new BorderLayout()); add(new JScrollPane(treeTable), BorderLayout.CENTER); } private void loadChildren(String name) { List<String> childList = children.get(name); DefaultMutableTreeNode node = nodes.get(name); if (node == null) { System.out.println("Node was null: \"" + name + "\""); return; } for (String child : childList) { DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child); node.add(childNode); nodes.put(child, childNode); if (children.containsKey(child)) { loadChildren(child); } } } public void refresh() { } public String getLevel(String name) { String level = levels.get(name); if ((level == null || level.equals("")) && parents.containsKey(name)) { return getLevel(parents.get(name)); } else { return level; } } public class LoggerInfoTreeTableModel extends DefaultTreeTableModel { private String[] COLUMN_NAMES = {"Logger", "Level"}; public Class getColumnClass(int i) { return super.getColumnClass(i); //To change body of overridden methods use File | Settings | File Templates. } public Object getValueAt(Object object, int i) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) object; switch (i) { case 0: return node.getUserObject(); case 1: return getLevel((String) node.getUserObject()); default: return null; } } public String getColumnName(int i) { return COLUMN_NAMES[i]; } public int getColumnCount() { return COLUMN_NAMES.length; } } } Index: ThreadMBeanThreadBrowserComponent.java =================================================================== RCS file: /cvsroot/mc4j/mc4j/src/org/mc4j/jre15/components/ThreadMBeanThreadBrowserComponent.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ThreadMBeanThreadBrowserComponent.java 12 Apr 2006 19:14:04 -0000 1.5 --- ThreadMBeanThreadBrowserComponent.java 22 May 2006 02:38:52 -0000 1.6 *************** *** 86,100 **** } - public void setContext(Map context) { - - } - - public synchronized void refresh() { - try { // TODO GH: the added set is not being used and right now i'm firing --- 86,94 ---- *************** *** 139,145 **** } this.treeModel.nodeStructureChanged(threadNode); - - - } --- 133,136 ---- *************** *** 230,235 **** - - /** Returns an ImageIcon, or null if the path was invalid. */ protected static ImageIcon createImageIcon(String path) { --- 221,224 ---- *************** *** 244,247 **** } ! ! } --- 233,235 ---- } ! } \ No newline at end of file Index: ThreadsViewComponent.java =================================================================== RCS file: /cvsroot/mc4j/mc4j/src/org/mc4j/jre15/components/ThreadsViewComponent.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ThreadsViewComponent.java 17 Apr 2006 12:01:27 -0000 1.3 --- ThreadsViewComponent.java 22 May 2006 02:38:52 -0000 1.4 *************** *** 22,27 **** import org.mc4j.console.dashboard.DashboardComponent; import org.mc4j.console.dashboard.components.BeanComponent; - import org.mc4j.console.swing.graph.GlassWindow; import org.mc4j.ems.connection.bean.EmsBean; import javax.swing.*; --- 22,27 ---- import org.mc4j.console.dashboard.DashboardComponent; import org.mc4j.console.dashboard.components.BeanComponent; import org.mc4j.ems.connection.bean.EmsBean; + import sun.swing.table.DefaultTableCellHeaderRenderer; import javax.swing.*; *************** *** 30,48 **** import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; ! import java.awt.BorderLayout; ! import java.awt.Color; ! import java.awt.Component; ! import java.awt.Dimension; ! import java.awt.Graphics; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.text.DecimalFormat; import java.text.NumberFormat; ! import java.util.ArrayList; ! import java.util.HashSet; ! import java.util.LinkedHashMap; ! import java.util.LinkedList; import java.util.List; - import java.util.Map; /** --- 30,43 ---- import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; ! import java.awt.*; ! import java.awt.geom.Rectangle2D; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; + import java.text.DateFormat; import java.text.DecimalFormat; import java.text.NumberFormat; ! import java.text.SimpleDateFormat; ! import java.util.*; import java.util.List; /** *************** *** 52,63 **** public class ThreadsViewComponent extends JPanel implements DashboardComponent, BeanComponent { ! EmsBean emsThreadBean; ! ThreadMXBean threadBean; ! JXTable table; ! ThreadsTableModel model; private static final int TIME_HISTORY = 100 * 1000; public void setContext(Map context) { model = new ThreadsTableModel(threadBean); table = new JXTable(model); --- 47,69 ---- public class ThreadsViewComponent extends JPanel implements DashboardComponent, BeanComponent { ! private EmsBean emsThreadBean; ! private ThreadMXBean threadBean; ! private JXTable table; ! private ThreadsTableModel model; ! ! private JPanel detail; ! private JEditorPane threadInfo; ! private JTextPane threadStack; ! private JSplitPane splitPane; ! private static final int TIME_HISTORY = 100 * 1000; + // A hack to track the list of vertical time lines we're drawing + private int[] lineLocations = {0, 0}; + public void setContext(Map context) { + + model = new ThreadsTableModel(threadBean); table = new JXTable(model); *************** *** 67,73 **** table.getColumnExt(2).setCellRenderer(new ThreadStateCellRenderer()); table.getColumnExt(3).setCellRenderer(new ThreadDataGraphRenderer()); table.getColumnExt(5).setCellRenderer(new PercentageCellRenderer()); setLayout(new BorderLayout()); - add(new JScrollPane(table), BorderLayout.CENTER); table.getColumnExt(0).setPreferredWidth(35); // Id --- 73,79 ---- table.getColumnExt(2).setCellRenderer(new ThreadStateCellRenderer()); table.getColumnExt(3).setCellRenderer(new ThreadDataGraphRenderer()); + table.getColumnExt(3).setHeaderRenderer(new ThreadDataGraphCellHeaderRenderer()); table.getColumnExt(5).setCellRenderer(new PercentageCellRenderer()); setLayout(new BorderLayout()); table.getColumnExt(0).setPreferredWidth(35); // Id *************** *** 84,113 **** - table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { ! ThreadsTableModel.ThreadData d = model.getData(e.getFirstIndex()); ! JTextPane textPane = new JTextPane(); ! StringBuilder b = new StringBuilder(); ! ThreadInfo ti = threadBean.getThreadInfo(d.getLastData().getThreadId(), Integer.MAX_VALUE); ! if (ti != null) { ! for (StackTraceElement el : ti.getStackTrace()) { ! b.append(el); ! b.append("\n"); } ! textPane.setEditable(false); ! textPane.setText(b.toString()); ! textPane.setPreferredSize(new Dimension(500,600)); ! GlassWindow.show(new JScrollPane(textPane),ThreadsViewComponent.this); } } }); - } public void refresh() { model.refresh(); ! model.fireTableDataChanged(); } --- 90,158 ---- table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { ! if (!table.getSelectionModel().isSelectionEmpty()) { ! ThreadsTableModel.ThreadData d = model.getData(table.convertRowIndexToModel(e.getFirstIndex())); ! StringBuilder b = new StringBuilder(); ! ThreadInfo ti = threadBean.getThreadInfo(d.getLastData().getThreadId(), Integer.MAX_VALUE); ! if (ti != null) { ! for (StackTraceElement el : ti.getStackTrace()) { ! b.append(el); ! b.append("\n"); ! } ! ! String threadInfoString = ! "<html><b>Name: </b> " + ti.getThreadName() + " (" + ti.getThreadId() + ")<br>" + ! "<b>State: </b> " + ti.getThreadState() + "<br>" + ! "<b>Total Blocked: </b>" + ti.getBlockedCount() + " (" + ti.getBlockedTime() + "ms)<br>" + ! "<b>Total Waits: </b> " + ti.getWaitedCount() + " (" + ti.getWaitedTime() + "ms)<br>" + ! "<b>Lock: </b> " + ti.getLockName() + "<br>" + ! "<b>Lock Owner: </b>" + ti.getLockOwnerName() + " (" + ti.getLockOwnerId() + ")" + ! "</html>"; ! ! ! threadInfo.setText(threadInfoString); ! threadStack.setText(b.toString()); ! splitPane.setDividerLocation(splitPane.getHeight() - 250); ! } else { ! threadStack.setText("<unknown>"); } ! } else { ! splitPane.setDividerLocation(splitPane.getHeight()); } } }); + detail = new JPanel(new GridLayout(1, 2)); + + threadInfo = new JEditorPane(); + threadInfo.setContentType("text/html"); + threadInfo.setEditable(false); + threadInfo.setOpaque(false); + threadInfo.setPreferredSize(new Dimension(250, 250)); + threadStack = new JTextPane(); + threadStack.setEditable(false); + + detail.add(threadInfo); + detail.add(new JScrollPane(threadStack)); + + splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, new JScrollPane(table), detail); + splitPane.setResizeWeight(1); + splitPane.setDividerLocation(1d); + + add(splitPane, BorderLayout.CENTER); + + } + public void refresh() { + int start = model.getRowCount(); model.refresh(); ! table.getTableHeader().repaint(); ! model.fireTableRowsUpdated(0, start); ! if (model.getRowCount() > start) { ! model.fireTableRowsInserted(start + 1, model.getRowCount()); ! } } *************** *** 122,136 **** } ! public static class ThreadDataGraphRenderer extends DefaultTableCellRenderer { ThreadsTableModel.ThreadData data; ! private static final Color blocked = new Color(205, 92, 92); ! private static final Color neww = new Color(135, 206, 250); ! private static final Color runnable = new Color(144, 238, 144); ! private static final Color terminated = new Color(112, 128, 244); ! private static final Color timed_waiting = new Color(240, 128, 128); ! private static final Color waiting = new Color(255, 239, 213); public ThreadDataGraphRenderer() { --- 167,238 ---- } + public class ThreadDataGraphCellHeaderRenderer extends DefaultTableCellHeaderRenderer { ! DateFormat sdf = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT); ! GregorianCalendar c = new GregorianCalendar(); ! ! protected void paintComponent(Graphics g) { ! ! super.paintComponent(g); ! ! ! lineLocations[0] = drawMinute(g, new Date()); ! c.setTime(new Date()); ! c.add(GregorianCalendar.MINUTE, -1); ! lineLocations[1] = drawMinute(g, c.getTime()); ! } ! ! private int drawMinute(Graphics g, Date d) { ! int w = getWidth(); ! ! c.setTime(d); ! c.set(GregorianCalendar.SECOND, 0); ! int s = (int) ((new Date().getTime() / 1000) - (c.getTime().getTime() / 1000)); ! int scale = (int) ((double) w) / (TIME_HISTORY / 1000); ! ! ! String t = sdf.format(c.getTime()); ! Rectangle2D b = g.getFontMetrics().getStringBounds(t, g); ! ! int timeLoc = (int) (w - (((double) scale) * s)); ! if (timeLoc < 0) ! return -1; ! ! int stringLoc; ! if (b.getWidth() > (getWidth() - timeLoc)) { ! // put it on the right ! stringLoc = (int) (timeLoc - b.getWidth() - 2); ! } else { ! // put it on the left ! stringLoc = (int) (timeLoc + 2); ! } ! ! // g.setColor(getBackground()); ! // g.drawRoundRect(); ! ! g.setColor(Color.darkGray); ! g.drawLine(timeLoc, 0, timeLoc, getHeight()); ! g.drawString(t, stringLoc, getHeight() - 2); ! return timeLoc; ! } ! ! ! public Component getTableCellRendererComponent(JTable jTable, Object object, boolean b, boolean b1, int i, int i1) { ! super.getTableCellRendererComponent(jTable, "", b, b1, i, i1); ! return this; ! } ! } ! ! ! public class ThreadDataGraphRenderer extends DefaultTableCellRenderer { ThreadsTableModel.ThreadData data; ! private final Color blocked = new Color(205, 92, 92); ! private final Color neww = new Color(135, 206, 250); ! private final Color runnable = new Color(144, 238, 144); ! private final Color terminated = new Color(112, 128, 244); ! private final Color timed_waiting = new Color(240, 128, 128); ! private final Color waiting = new Color(255, 239, 213); public ThreadDataGraphRenderer() { *************** *** 140,143 **** --- 242,246 ---- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { data = (ThreadsTableModel.ThreadData) value; + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); return this; } *************** *** 147,151 **** g.setColor(getBackground()); ! g.fillRect(0,0, getWidth(), getHeight()); Color c = null; --- 250,254 ---- g.setColor(getBackground()); ! g.fillRect(0, 0, getWidth(), getHeight()); Color c = null; *************** *** 184,187 **** --- 287,295 ---- last = d; } + g.setColor(Color.lightGray); + for (int l : lineLocations) { + if (l > 0) + g.drawLine(l, 0, l, getHeight()); + } } } *************** *** 189,196 **** --- 297,306 ---- public static class PercentageCellRenderer extends DefaultTableCellRenderer { static NumberFormat f; + static { f = DecimalFormat.getPercentInstance(); f.setMaximumFractionDigits(2); } + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { return super.getTableCellRendererComponent(table, f.format(value), isSelected, hasFocus, row, column); *************** *** 201,207 **** public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Icon icon = null; if (value instanceof Thread.State) { ! switch ((Thread.State)value) { case BLOCKED: icon = threadBlockedIcon; --- 311,319 ---- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); Icon icon = null; if (value instanceof Thread.State) { ! switch ((Thread.State) value) { case BLOCKED: icon = threadBlockedIcon; *************** *** 228,231 **** --- 340,344 ---- setHorizontalAlignment(CENTER); setIcon(icon); + setText(null); return this; } *************** *** 259,263 **** private static final String[] COLUMNS = new String[]{ ! "Id", "Name", "State", "History", "CPU Total","CPU %", "User Total", "Blocks", "Block Time", "Lock" }; --- 372,376 ---- private static final String[] COLUMNS = new String[]{ ! "Id", "Name", "State", "History", "CPU Total", "CPU %", "User Total", "Blocks", "Block Time", "Lock" }; |