6655515: MBeans tab: operation return values of type Component displayed as String

6439590: MBeans tab: jconsole mbean tree not correctly refreshed
6446434: MBeans tab: Not possible to view MBean content before all MBeans have been initially loaded
6520144: Hard to find MBean Attributes, Operations, and Notifications in Java 6 jconsole
6522091: VMPanel.java contains non-ASCII character
6608334: JConsole fails to display MBean operation with <null> return type
6611445: MBeans tab: MBean tree algorithm wrongly removes intermediate nodes

Reviewed-by: dfuchs, jfdenise
This commit is contained in:
Luis Miguel Alventosa 2008-03-11 01:20:55 +01:00
parent c88c71b755
commit 134f15a93f
21 changed files with 1485 additions and 1312 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package sun.tools.jconsole; package sun.tools.jconsole;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
@ -42,7 +43,8 @@ import com.sun.tools.jconsole.JConsoleContext;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class MBeansTab extends Tab implements public class MBeansTab extends Tab implements
NotificationListener, PropertyChangeListener, TreeSelectionListener { NotificationListener, PropertyChangeListener,
TreeSelectionListener, TreeWillExpandListener {
private XTree tree; private XTree tree;
private XSheet sheet; private XSheet sheet;
@ -70,6 +72,7 @@ public class MBeansTab extends Tab implements
return sheet; return sheet;
} }
@Override
public void dispose() { public void dispose() {
super.dispose(); super.dispose();
sheet.dispose(); sheet.dispose();
@ -79,61 +82,79 @@ public class MBeansTab extends Tab implements
return vmPanel.getUpdateInterval(); return vmPanel.getUpdateInterval();
} }
void synchroniseMBeanServerView() { private void buildMBeanServerView() {
// Register listener for MBean registration/unregistration new SwingWorker<Set<ObjectName>, Void>() {
// @Override
try { public Set<ObjectName> doInBackground() {
getMBeanServerConnection().addNotificationListener( // Register listener for MBean registration/unregistration
MBeanServerDelegate.DELEGATE_NAME, //
this, try {
null, getMBeanServerConnection().addNotificationListener(
null); MBeanServerDelegate.DELEGATE_NAME,
} catch (InstanceNotFoundException e) { MBeansTab.this,
// Should never happen because the MBeanServerDelegate null,
// is always present in any standard MBeanServer null);
// } catch (InstanceNotFoundException e) {
if (JConsole.isDebug()) { // Should never happen because the MBeanServerDelegate
e.printStackTrace(); // is always present in any standard MBeanServer
//
if (JConsole.isDebug()) {
e.printStackTrace();
}
} catch (IOException e) {
if (JConsole.isDebug()) {
e.printStackTrace();
}
vmPanel.getProxyClient().markAsDead();
return null;
}
// Retrieve MBeans from MBeanServer
//
Set<ObjectName> mbeans = null;
try {
mbeans = getMBeanServerConnection().queryNames(null, null);
} catch (IOException e) {
if (JConsole.isDebug()) {
e.printStackTrace();
}
vmPanel.getProxyClient().markAsDead();
return null;
}
return mbeans;
} }
} catch (IOException e) { @Override
if (JConsole.isDebug()) { protected void done() {
e.printStackTrace(); try {
// Wait for mbsc.queryNames() result
Set<ObjectName> mbeans = get();
// Do not display anything until the new tree has been built
//
tree.setVisible(false);
// Cleanup current tree
//
tree.removeAll();
// Add MBeans to tree
//
tree.addMBeansToView(mbeans);
// Display the new tree
//
tree.setVisible(true);
} catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Problem at MBean tree construction");
t.printStackTrace();
}
}
} }
vmPanel.getProxyClient().markAsDead(); }.execute();
return;
}
// Retrieve MBeans from MBeanServer
//
Set<ObjectName> newSet = null;
try {
newSet = getMBeanServerConnection().queryNames(null,null);
} catch (IOException e) {
if (JConsole.isDebug()) {
e.printStackTrace();
}
vmPanel.getProxyClient().markAsDead();
return;
}
// Cleanup current tree
//
tree.removeAll();
// Do not display anything until the new tree has been built
//
tree.setVisible(false);
// Add MBeans to tree
//
for (ObjectName mbean : newSet) {
tree.addMBeanToView(mbean);
}
// Display the new tree
//
tree.setVisible(true);
} }
public MBeanServerConnection getMBeanServerConnection() { public MBeanServerConnection getMBeanServerConnection() {
return vmPanel.getProxyClient().getMBeanServerConnection(); return vmPanel.getProxyClient().getMBeanServerConnection();
} }
@Override
public void update() { public void update() {
// Ping the connection to see if it is still alive. At // Ping the connection to see if it is still alive. At
// some point the ProxyClient class should centralize // some point the ProxyClient class should centralize
@ -160,6 +181,7 @@ public class MBeansTab extends Tab implements
tree.getSelectionModel().setSelectionMode( tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION); TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.addTreeSelectionListener(this); tree.addTreeSelectionListener(this);
tree.addTreeWillExpandListener(this);
tree.addMouseListener(ml); tree.addMouseListener(ml);
JScrollPane theScrollPane = new JScrollPane( JScrollPane theScrollPane = new JScrollPane(
tree, tree,
@ -177,55 +199,55 @@ public class MBeansTab extends Tab implements
add(mainSplit); add(mainSplit);
} }
/* notification listener */ /* notification listener: handleNotification */
public void handleNotification(Notification notification, Object handback) { public void handleNotification(
if (notification instanceof MBeanServerNotification) { final Notification notification, Object handback) {
ObjectName mbean = EventQueue.invokeLater(new Runnable() {
((MBeanServerNotification) notification).getMBeanName(); public void run() {
if (notification.getType().equals( if (notification instanceof MBeanServerNotification) {
MBeanServerNotification.REGISTRATION_NOTIFICATION)) { ObjectName mbean =
tree.addMBeanToView(mbean); ((MBeanServerNotification) notification).getMBeanName();
} else if (notification.getType().equals( if (notification.getType().equals(
MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
tree.delMBeanFromView(mbean); tree.addMBeanToView(mbean);
} else if (notification.getType().equals(
MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
tree.removeMBeanFromView(mbean);
}
}
} }
} });
} }
/* property change listener */ /* property change listener: propertyChange */
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName() == JConsoleContext.CONNECTION_STATE_PROPERTY) { if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {
boolean connected = (Boolean) evt.getNewValue(); boolean connected = (Boolean) evt.getNewValue();
if (connected) { if (connected) {
workerAdd(new Runnable() { buildMBeanServerView();
public void run() {
synchroniseMBeanServerView();
}
});
} else { } else {
sheet.dispose(); sheet.dispose();
} }
} }
} }
/* tree selection listener */ /* tree selection listener: valueChanged */
public void valueChanged(TreeSelectionEvent e) { public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = DefaultMutableTreeNode node =
(DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
sheet.displayNode(node); sheet.displayNode(node);
} }
/* tree mouse listener: mousePressed */
/* tree mouse listener */
private MouseListener ml = new MouseAdapter() { private MouseListener ml = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 1) { if (e.getClickCount() == 1) {
int selRow = tree.getRowForLocation(e.getX(), e.getY()); int selRow = tree.getRowForLocation(e.getX(), e.getY());
if (selRow != -1) { if (selRow != -1) {
TreePath selPath = TreePath selPath =
tree.getPathForLocation(e.getX(), e.getY()); tree.getPathForLocation(e.getX(), e.getY());
DefaultMutableTreeNode node = (DefaultMutableTreeNode) DefaultMutableTreeNode node =
selPath.getLastPathComponent(); (DefaultMutableTreeNode) selPath.getLastPathComponent();
if (sheet.isMBeanNode(node)) { if (sheet.isMBeanNode(node)) {
tree.expandPath(selPath); tree.expandPath(selPath);
} }
@ -233,4 +255,22 @@ public class MBeansTab extends Tab implements
} }
} }
}; };
/* tree will expand listener: treeWillExpand */
public void treeWillExpand(TreeExpansionEvent e)
throws ExpandVetoException {
TreePath path = e.getPath();
if (!tree.hasBeenExpanded(path)) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) path.getLastPathComponent();
if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) {
tree.addMetadataNodes(node);
}
}
}
/* tree will expand listener: treeWillCollapse */
public void treeWillCollapse(TreeExpansionEvent e)
throws ExpandVetoException {
}
} }

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole; package sun.tools.jconsole;
import java.lang.management.MemoryUsage; import java.lang.management.MemoryUsage;

View File

@ -45,6 +45,7 @@ import static sun.tools.jconsole.ProxyClient.*;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class VMPanel extends JTabbedPane implements PropertyChangeListener { public class VMPanel extends JTabbedPane implements PropertyChangeListener {
private ProxyClient proxyClient; private ProxyClient proxyClient;
private Timer timer; private Timer timer;
private int updateInterval; private int updateInterval;
@ -55,12 +56,9 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
private String password; private String password;
private String url; private String url;
private VMInternalFrame vmIF = null; private VMInternalFrame vmIF = null;
private static final String windowsLaF = private static final String windowsLaF =
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
private static ArrayList<TabInfo> tabInfos = new ArrayList<TabInfo>(); private static ArrayList<TabInfo> tabInfos = new ArrayList<TabInfo>();
private boolean wasConnected = false; private boolean wasConnected = false;
// The everConnected flag keeps track of whether the window can be // The everConnected flag keeps track of whether the window can be
@ -76,7 +74,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
// Each VMPanel has its own instance of the JConsolePlugin // Each VMPanel has its own instance of the JConsolePlugin
// A map of JConsolePlugin to the previous SwingWorker // A map of JConsolePlugin to the previous SwingWorker
private Map<JConsolePlugin, SwingWorker<?,?>> plugins = null; private Map<JConsolePlugin, SwingWorker<?, ?>> plugins = null;
private boolean pluginTabsAdded = false; private boolean pluginTabsAdded = false;
// Update these only on the EDT // Update these only on the EDT
@ -86,11 +84,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
static { static {
tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true)); tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true));
tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true)); tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true));
tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true)); tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true));
tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true)); tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true));
tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true)); tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true));
tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true)); tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true));
} }
public static TabInfo[] getTabInfos() { public static TabInfo[] getTabInfos() {
@ -101,8 +99,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
this.proxyClient = proxyClient; this.proxyClient = proxyClient;
this.updateInterval = updateInterval; this.updateInterval = updateInterval;
this.hostName = proxyClient.getHostName(); this.hostName = proxyClient.getHostName();
this.port = proxyClient.getPort(); this.port = proxyClient.getPort();
this.vmid = proxyClient.getVmid(); this.vmid = proxyClient.getVmid();
this.userName = proxyClient.getUserName(); this.userName = proxyClient.getUserName();
this.password = proxyClient.getPassword(); this.password = proxyClient.getPassword();
this.url = proxyClient.getUrl(); this.url = proxyClient.getUrl();
@ -113,7 +111,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
} }
} }
plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?,?>>(); plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?, ?>>();
for (JConsolePlugin p : JConsole.getPlugins()) { for (JConsolePlugin p : JConsole.getPlugins()) {
p.setContext(proxyClient); p.setContext(proxyClient);
plugins.put(p, null); plugins.put(p, null);
@ -128,10 +126,9 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
proxyClient.addPropertyChangeListener(this); proxyClient.addPropertyChangeListener(this);
addMouseListener(new MouseAdapter() { addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
if (connectedIconBounds != null if (connectedIconBounds != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && connectedIconBounds.contains(e.getPoint())) {
&& (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0
&& connectedIconBounds.contains(e.getPoint())) {
if (isConnected()) { if (isConnected()) {
disconnect(); disconnect();
@ -145,23 +142,21 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
}); });
} }
private static Icon connectedIcon16 = private static Icon connectedIcon16 =
new ImageIcon(VMPanel.class.getResource("resources/connected16.png")); new ImageIcon(VMPanel.class.getResource("resources/connected16.png"));
private static Icon connectedIcon24 = private static Icon connectedIcon24 =
new ImageIcon(VMPanel.class.getResource("resources/connected24.png")); new ImageIcon(VMPanel.class.getResource("resources/connected24.png"));
private static Icon disconnectedIcon16 = private static Icon disconnectedIcon16 =
new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png")); new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png"));
private static Icon disconnectedIcon24 = private static Icon disconnectedIcon24 =
new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png")); new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png"));
private Rectangle connectedIconBounds; private Rectangle connectedIconBounds;
// Override to increase right inset for tab area, // Override to increase right inset for tab area,
// in order to reserve space for the connect toggle. // in order to reserve space for the connect toggle.
public void setUI(TabbedPaneUI ui) { public void setUI(TabbedPaneUI ui) {
Insets insets = (Insets)UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
insets = (Insets)insets.clone(); insets = (Insets) insets.clone();
insets.right += connectedIcon24.getIconWidth() + 8; insets.right += connectedIcon24.getIconWidth() + 8;
UIManager.put("TabbedPane.tabAreaInsets", insets); UIManager.put("TabbedPane.tabAreaInsets", insets);
super.setUI(ui); super.setUI(ui);
@ -225,7 +220,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
private Tab instantiate(TabInfo tabInfo) { private Tab instantiate(TabInfo tabInfo) {
try { try {
Constructor con = tabInfo.tabClass.getConstructor(VMPanel.class); Constructor con = tabInfo.tabClass.getConstructor(VMPanel.class);
return (Tab)con.newInstance(this); return (Tab) con.newInstance(this);
} catch (Exception ex) { } catch (Exception ex) {
System.err.println(ex); System.err.println(ex);
return null; return null;
@ -247,10 +242,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
* IT IS USED TO MAKE SOME LOCAL MANIPULATIONS. * IT IS USED TO MAKE SOME LOCAL MANIPULATIONS.
*/ */
ProxyClient getProxyClient(boolean assertThread) { ProxyClient getProxyClient(boolean assertThread) {
if(assertThread) if (assertThread) {
return getProxyClient(); return getProxyClient();
else } else {
return proxyClient; return proxyClient;
}
} }
public ProxyClient getProxyClient() { public ProxyClient getProxyClient() {
@ -294,6 +290,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
startUpdateTimer(); startUpdateTimer();
} else { } else {
new Thread("VMPanel.connect") { new Thread("VMPanel.connect") {
public void run() { public void run() {
proxyClient.connect(); proxyClient.connect();
} }
@ -301,68 +298,63 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
} }
} }
// Call on EDT // Call on EDT
public void disconnect() { public void disconnect() {
proxyClient.disconnect(); proxyClient.disconnect();
updateFrameTitle(); updateFrameTitle();
} }
// Called on EDT // Called on EDT
public void propertyChange(PropertyChangeEvent ev) { public void propertyChange(PropertyChangeEvent ev) {
String prop = ev.getPropertyName(); String prop = ev.getPropertyName();
if (prop == CONNECTION_STATE_PROPERTY) { if (prop == CONNECTION_STATE_PROPERTY) {
ConnectionState oldState = (ConnectionState)ev.getOldValue(); ConnectionState oldState = (ConnectionState) ev.getOldValue();
ConnectionState newState = (ConnectionState)ev.getNewValue(); ConnectionState newState = (ConnectionState) ev.getNewValue();
switch (newState) { switch (newState) {
case CONNECTING: case CONNECTING:
onConnecting(); onConnecting();
break; break;
case CONNECTED: case CONNECTED:
if (progressBar != null) { if (progressBar != null) {
progressBar.setIndeterminate(false); progressBar.setIndeterminate(false);
progressBar.setValue(100); progressBar.setValue(100);
} }
closeOptionPane();
updateFrameTitle();
// create tabs if not done
createPluginTabs();
repaint();
// Notify tabs
fireConnectedChange(true);
// Enable/disable tabs on initial update
initialUpdate = true;
// Start/Restart update timer on connect/reconnect
startUpdateTimer();
break;
case DISCONNECTED:
if (progressBar != null) {
progressBar.setIndeterminate(false);
progressBar.setValue(0);
closeOptionPane(); closeOptionPane();
} updateFrameTitle();
vmPanelDied(); // create tabs if not done
if (oldState == ConnectionState.CONNECTED) { createPluginTabs();
repaint();
// Notify tabs // Notify tabs
fireConnectedChange(false); fireConnectedChange(true);
} // Enable/disable tabs on initial update
break; initialUpdate = true;
// Start/Restart update timer on connect/reconnect
startUpdateTimer();
break;
case DISCONNECTED:
if (progressBar != null) {
progressBar.setIndeterminate(false);
progressBar.setValue(0);
closeOptionPane();
}
vmPanelDied();
if (oldState == ConnectionState.CONNECTED) {
// Notify tabs
fireConnectedChange(false);
}
break;
} }
} }
} }
// Called on EDT // Called on EDT
private void onConnecting() { private void onConnecting() {
time0 = System.currentTimeMillis(); time0 = System.currentTimeMillis();
final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this); final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this);
String connectionName = getConnectionName(); String connectionName = getConnectionName();
progressBar = new JProgressBar(); progressBar = new JProgressBar();
@ -373,17 +365,16 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
Object[] message = { Object[] message = {
"<html><h3>" + getText("connectingTo1", connectionName) + "</h3></html>", "<html><h3>" + getText("connectingTo1", connectionName) + "</h3></html>",
progressPanel, progressPanel,
"<html><b>" + getText("connectingTo2", connectionName) + "</b></html>" "<html><b>" + getText("connectingTo2", connectionName) + "</b></html>"
}; };
optionPane = optionPane =
SheetDialog.showOptionDialog(this, SheetDialog.showOptionDialog(this,
message, message,
JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE, null, JOptionPane.INFORMATION_MESSAGE, null,
new String[] { getText("Cancel") }, new String[]{getText("Cancel")},
0); 0);
} }
@ -398,10 +389,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
try { try {
sleep(2000 - elapsed); sleep(2000 - elapsed);
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
// Ignore // Ignore
} }
} }
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
optionPane.setVisible(false); optionPane.setVisible(false);
progressBar = null; progressBar = null;
@ -425,8 +417,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
private VMInternalFrame getFrame() { private VMInternalFrame getFrame() {
if (vmIF == null) { if (vmIF == null) {
vmIF = (VMInternalFrame)SwingUtilities.getAncestorOfClass(VMInternalFrame.class, vmIF = (VMInternalFrame) SwingUtilities.getAncestorOfClass(VMInternalFrame.class,
this); this);
} }
return vmIF; return vmIF;
} }
@ -452,27 +444,27 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
timer.cancel(); timer.cancel();
} }
TimerTask timerTask = new TimerTask() { TimerTask timerTask = new TimerTask() {
public void run() { public void run() {
update(); update();
} }
}; };
String timerName = "Timer-"+getConnectionName(); String timerName = "Timer-" + getConnectionName();
timer = new Timer(timerName, true); timer = new Timer(timerName, true);
timer.schedule(timerTask, 0, updateInterval); timer.schedule(timerTask, 0, updateInterval);
} }
// Call on EDT // Call on EDT
private void vmPanelDied() { private void vmPanelDied() {
disconnect(); disconnect();
final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this); final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this);
JOptionPane optionPane; JOptionPane optionPane;
final String connectStr = getText("Connect"); final String connectStr = getText("Connect");
final String reconnectStr = getText("Reconnect"); final String reconnectStr = getText("Reconnect");
final String cancelStr = getText("Cancel"); final String cancelStr = getText("Cancel");
String msgTitle, msgExplanation, buttonStr; String msgTitle, msgExplanation, buttonStr;
@ -488,15 +480,16 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
} }
optionPane = optionPane =
SheetDialog.showOptionDialog(this, SheetDialog.showOptionDialog(this,
"<html><h3>" + msgTitle + "</h3>" + "<html><h3>" + msgTitle + "</h3>" +
"<b>" + msgExplanation + "</b>", "<b>" + msgExplanation + "</b>",
JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE, null, JOptionPane.WARNING_MESSAGE, null,
new String[] { buttonStr, cancelStr }, new String[]{buttonStr, cancelStr},
0); 0);
optionPane.addPropertyChangeListener(new PropertyChangeListener() { optionPane.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) { if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
Object value = event.getNewValue(); Object value = event.getNewValue();
@ -507,7 +500,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
try { try {
getFrame().setClosed(true); getFrame().setClosed(true);
} catch (PropertyVetoException ex) { } catch (PropertyVetoException ex) {
// Should not happen, but can be ignored. // Should not happen, but can be ignored.
} }
} }
} }
@ -518,11 +511,13 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
// Note: This method is called on a TimerTask thread. Any GUI manipulation // Note: This method is called on a TimerTask thread. Any GUI manipulation
// must be performed with invokeLater() or invokeAndWait(). // must be performed with invokeLater() or invokeAndWait().
private Object lockObject = new Object(); private Object lockObject = new Object();
private void update() { private void update() {
synchronized(lockObject) { synchronized (lockObject) {
if (!isConnected()) { if (!isConnected()) {
if (wasConnected) { if (wasConnected) {
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
vmPanelDied(); vmPanelDied();
} }
@ -548,6 +543,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
// //
if (initialUpdate) { if (initialUpdate) {
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
setEnabledAt(index, true); setEnabledAt(index, true);
} }
@ -569,8 +565,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
// plugin GUI update // plugin GUI update
for (JConsolePlugin p : plugins.keySet()) { for (JConsolePlugin p : plugins.keySet()) {
SwingWorker<?,?> sw = p.newSwingWorker(); SwingWorker<?, ?> sw = p.newSwingWorker();
SwingWorker<?,?> prevSW = plugins.get(p); SwingWorker<?, ?> prevSW = plugins.get(p);
// schedule SwingWorker to run only if the previous // schedule SwingWorker to run only if the previous
// SwingWorker has finished its task and it hasn't started. // SwingWorker has finished its task and it hasn't started.
if (prevSW == null || prevSW.isDone()) { if (prevSW == null || prevSW.isDone()) {
@ -583,7 +579,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
} }
} }
// Set the first enabled tab in the tab´s list // Set the first enabled tab in the tab's list
// as the selected tab on initial update // as the selected tab on initial update
// //
if (initialUpdate) { if (initialUpdate) {
@ -622,7 +618,6 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
return url; return url;
} }
public String getPassword() { public String getPassword() {
return password; return password;
} }
@ -636,6 +631,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
} }
static class TabInfo { static class TabInfo {
Class<? extends Tab> tabClass; Class<? extends Tab> tabClass;
String name; String name;
boolean tabVisible; boolean tabVisible;

View File

@ -22,8 +22,8 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector;
package sun.tools.jconsole.inspector;
// java import // java import
import java.awt.*; import java.awt.*;

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import java.util.*; import java.util.*;

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
// java import // java import

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,55 +29,51 @@ import java.awt.event.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ExecutionException;
import javax.management.*; import javax.management.*;
import javax.management.openmbean.*; import javax.management.openmbean.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.*; import javax.swing.text.*;
import java.util.*;
public class Utils { public class Utils {
private Utils() { private Utils() {
} }
private static Set<Integer> tableNavigationKeys = private static Set<Integer> tableNavigationKeys =
new HashSet<Integer>(Arrays.asList(new Integer[] { new HashSet<Integer>(Arrays.asList(new Integer[]{
KeyEvent.VK_TAB, KeyEvent.VK_ENTER, KeyEvent.VK_TAB, KeyEvent.VK_ENTER,
KeyEvent.VK_HOME, KeyEvent.VK_END, KeyEvent.VK_HOME, KeyEvent.VK_END,
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_UP, KeyEvent.VK_DOWN,
KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN})); KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN
}));
private static final Set<Class<?>> primitiveWrappers = private static final Set<Class<?>> primitiveWrappers =
new HashSet<Class<?>>(Arrays.asList(new Class<?>[] { new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
Byte.class, Short.class, Integer.class, Long.class, Byte.class, Short.class, Integer.class, Long.class,
Float.class, Double.class, Character.class, Boolean.class})); Float.class, Double.class, Character.class, Boolean.class
}));
private static final Set<Class<?>> primitives = new HashSet<Class<?>>(); private static final Set<Class<?>> primitives = new HashSet<Class<?>>();
private static final Map<String, Class<?>> primitiveMap = private static final Map<String, Class<?>> primitiveMap =
new HashMap<String, Class<?>>(); new HashMap<String, Class<?>>();
private static final Map<String, Class<?>> primitiveToWrapper = private static final Map<String, Class<?>> primitiveToWrapper =
new HashMap<String, Class<?>>(); new HashMap<String, Class<?>>();
private static final Set<String> editableTypes = new HashSet<String>(); private static final Set<String> editableTypes = new HashSet<String>();
private static final Set<Class<?>> extraEditableClasses = private static final Set<Class<?>> extraEditableClasses =
new HashSet<Class<?>>(Arrays.asList(new Class<?>[] { new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
BigDecimal.class, BigInteger.class, Number.class, BigDecimal.class, BigInteger.class, Number.class,
String.class, ObjectName.class})); String.class, ObjectName.class
}));
private static final Set<String> numericalTypes = new HashSet<String>(); private static final Set<String> numericalTypes = new HashSet<String>();
private static final Set<String> extraNumericalTypes = private static final Set<String> extraNumericalTypes =
new HashSet<String>(Arrays.asList(new String[] { new HashSet<String>(Arrays.asList(new String[]{
BigDecimal.class.getName(), BigInteger.class.getName(), BigDecimal.class.getName(), BigInteger.class.getName(),
Number.class.getName()})); Number.class.getName()
}));
private static final Set<String> booleanTypes = private static final Set<String> booleanTypes =
new HashSet<String>(Arrays.asList(new String[] { new HashSet<String>(Arrays.asList(new String[]{
Boolean.TYPE.getName(), Boolean.class.getName()})); Boolean.TYPE.getName(), Boolean.class.getName()
}));
static { static {
// compute primitives/primitiveMap/primitiveToWrapper // compute primitives/primitiveMap/primitiveToWrapper
@ -122,10 +118,11 @@ public class Utils {
* It's used to cater for the primitive types. * It's used to cater for the primitive types.
*/ */
public static Class<?> getClass(String className) public static Class<?> getClass(String className)
throws ClassNotFoundException { throws ClassNotFoundException {
Class<?> c; Class<?> c;
if ((c = primitiveMap.get(className)) != null) if ((c = primitiveMap.get(className)) != null) {
return c; return c;
}
return Class.forName(className); return Class.forName(className);
} }
@ -155,7 +152,9 @@ public class Utils {
* structure, i.e. a data structure jconsole can render as an array. * structure, i.e. a data structure jconsole can render as an array.
*/ */
public static boolean canBeRenderedAsArray(Object elem) { public static boolean canBeRenderedAsArray(Object elem) {
if (isSupportedArray(elem)) return true; if (isSupportedArray(elem)) {
return true;
}
if (elem instanceof Collection) { if (elem instanceof Collection) {
Collection<?> c = (Collection<?>) elem; Collection<?> c = (Collection<?>) elem;
if (c.isEmpty()) { if (c.isEmpty()) {
@ -168,7 +167,7 @@ public class Utils {
// - Collections of other Java types are handled as arrays // - Collections of other Java types are handled as arrays
// //
return !isUniformCollection(c, CompositeData.class) && return !isUniformCollection(c, CompositeData.class) &&
!isUniformCollection(c, TabularData.class); !isUniformCollection(c, TabularData.class);
} }
} }
if (elem instanceof Map) { if (elem instanceof Map) {
@ -239,7 +238,9 @@ public class Utils {
*/ */
public static String getReadableClassName(String name) { public static String getReadableClassName(String name) {
String className = getArrayClassName(name); String className = getArrayClassName(name);
if (className == null) return name; if (className == null) {
return name;
}
int index = name.lastIndexOf("["); int index = name.lastIndexOf("[");
StringBuilder brackets = new StringBuilder(className); StringBuilder brackets = new StringBuilder(className);
for (int i = 0; i <= index; i++) { for (int i = 0; i <= index; i++) {
@ -282,7 +283,7 @@ public class Utils {
* Try to create a Java object using a one-string-param constructor. * Try to create a Java object using a one-string-param constructor.
*/ */
public static Object newStringConstructor(String type, String param) public static Object newStringConstructor(String type, String param)
throws Exception { throws Exception {
Constructor c = Utils.getClass(type).getConstructor(String.class); Constructor c = Utils.getClass(type).getConstructor(String.class);
try { try {
return c.newInstance(param); return c.newInstance(param);
@ -300,7 +301,7 @@ public class Utils {
* Try to convert a string value into a numerical value. * Try to convert a string value into a numerical value.
*/ */
private static Number createNumberFromStringValue(String value) private static Number createNumberFromStringValue(String value)
throws NumberFormatException { throws NumberFormatException {
final String suffix = value.substring(value.length() - 1); final String suffix = value.substring(value.length() - 1);
if ("L".equalsIgnoreCase(suffix)) { if ("L".equalsIgnoreCase(suffix)) {
return Long.valueOf(value.substring(0, value.length() - 1)); return Long.valueOf(value.substring(0, value.length() - 1));
@ -314,17 +315,17 @@ public class Utils {
try { try {
return Integer.valueOf(value); return Integer.valueOf(value);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// OK: Ignore exception... // OK: Ignore exception...
} }
try { try {
return Long.valueOf(value); return Long.valueOf(value);
} catch (NumberFormatException e1) { } catch (NumberFormatException e1) {
// OK: Ignore exception... // OK: Ignore exception...
} }
try { try {
return Double.valueOf(value); return Double.valueOf(value);
} catch (NumberFormatException e2) { } catch (NumberFormatException e2) {
// OK: Ignore exception... // OK: Ignore exception...
} }
throw new NumberFormatException("Cannot convert string value '" + throw new NumberFormatException("Cannot convert string value '" +
value + "' into a numerical value"); value + "' into a numerical value");
@ -337,7 +338,7 @@ public class Utils {
* will return an Integer object initialized to 10. * will return an Integer object initialized to 10.
*/ */
public static Object createObjectFromString(String type, String value) public static Object createObjectFromString(String type, String value)
throws Exception { throws Exception {
Object result; Object result;
if (primitiveToWrapper.containsKey(type)) { if (primitiveToWrapper.containsKey(type)) {
if (type.equals(Character.TYPE.getName())) { if (type.equals(Character.TYPE.getName())) {
@ -367,7 +368,7 @@ public class Utils {
* into a useful object array for passing into a parameter array. * into a useful object array for passing into a parameter array.
*/ */
public static Object[] getParameters(XTextField[] inputs, String[] params) public static Object[] getParameters(XTextField[] inputs, String[] params)
throws Exception { throws Exception {
Object result[] = new Object[inputs.length]; Object result[] = new Object[inputs.length];
Object userInput; Object userInput;
for (int i = 0; i < inputs.length; i++) { for (int i = 0; i < inputs.length; i++) {
@ -388,12 +389,17 @@ public class Utils {
* If the exception is wrapped, unwrap it. * If the exception is wrapped, unwrap it.
*/ */
public static Throwable getActualException(Throwable e) { public static Throwable getActualException(Throwable e) {
if (e instanceof ExecutionException) {
e = e.getCause();
}
if (e instanceof MBeanException || if (e instanceof MBeanException ||
e instanceof RuntimeMBeanException || e instanceof RuntimeMBeanException ||
e instanceof RuntimeOperationsException || e instanceof RuntimeOperationsException ||
e instanceof ReflectionException) { e instanceof ReflectionException) {
Throwable t = e.getCause(); Throwable t = e.getCause();
if (t != null) return t; if (t != null) {
return t;
}
} }
return e; return e;
} }
@ -401,6 +407,7 @@ public class Utils {
@SuppressWarnings("serial") @SuppressWarnings("serial")
public static class ReadOnlyTableCellEditor public static class ReadOnlyTableCellEditor
extends DefaultCellEditor { extends DefaultCellEditor {
public ReadOnlyTableCellEditor(JTextField tf) { public ReadOnlyTableCellEditor(JTextField tf) {
super(tf); super(tf);
tf.addFocusListener(new Utils.EditFocusAdapter(this)); tf.addFocusListener(new Utils.EditFocusAdapter(this));
@ -409,20 +416,25 @@ public class Utils {
} }
public static class EditFocusAdapter extends FocusAdapter { public static class EditFocusAdapter extends FocusAdapter {
private CellEditor editor; private CellEditor editor;
public EditFocusAdapter(CellEditor editor) { public EditFocusAdapter(CellEditor editor) {
this.editor = editor; this.editor = editor;
} }
@Override
public void focusLost(FocusEvent e) { public void focusLost(FocusEvent e) {
editor.stopCellEditing(); editor.stopCellEditing();
} }
}; }
public static class CopyKeyAdapter extends KeyAdapter { public static class CopyKeyAdapter extends KeyAdapter {
private static final String defaultEditorKitCopyActionName = private static final String defaultEditorKitCopyActionName =
DefaultEditorKit.copyAction; DefaultEditorKit.copyAction;
private static final String transferHandlerCopyActionName = private static final String transferHandlerCopyActionName =
(String) TransferHandler.getCopyAction().getValue(Action.NAME); (String) TransferHandler.getCopyAction().getValue(Action.NAME);
@Override
public void keyPressed(KeyEvent e) { public void keyPressed(KeyEvent e) {
// Accept "copy" key strokes // Accept "copy" key strokes
KeyStroke ks = KeyStroke.getKeyStroke( KeyStroke ks = KeyStroke.getKeyStroke(
@ -441,6 +453,8 @@ public class Utils {
e.consume(); e.consume();
} }
} }
@Override
public void keyTyped(KeyEvent e) { public void keyTyped(KeyEvent e) {
e.consume(); e.consume();
} }

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import javax.swing.JTable; import javax.swing.JTable;
@ -108,6 +109,7 @@ public class XDataViewer {
public Component createOperationViewer(Object value, public Component createOperationViewer(Object value,
XMBean mbean) { XMBean mbean) {
if(value instanceof Number) return null; if(value instanceof Number) return null;
if(value instanceof Component) return (Component) value;
return createAttributeViewer(value, mbean, null, null); return createAttributeViewer(value, mbean, null, null);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,47 +28,56 @@ package sun.tools.jconsole.inspector;
import java.io.IOException; import java.io.IOException;
import javax.management.*; import javax.management.*;
import javax.swing.Icon; import javax.swing.Icon;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.MBeansTab; import sun.tools.jconsole.MBeansTab;
public class XMBean extends Object { public class XMBean {
private ObjectName objectName;
private final MBeansTab mbeansTab;
private final ObjectName objectName;
private Icon icon; private Icon icon;
private String text; private String text;
private boolean broadcaster; private Boolean broadcaster;
private final Object broadcasterLock = new Object();
private MBeanInfo mbeanInfo; private MBeanInfo mbeanInfo;
private MBeansTab mbeansTab; private final Object mbeanInfoLock = new Object();
public XMBean(ObjectName objectName, MBeansTab mbeansTab) public XMBean(ObjectName objectName, MBeansTab mbeansTab) {
throws InstanceNotFoundException, IntrospectionException,
ReflectionException, IOException {
this.mbeansTab = mbeansTab; this.mbeansTab = mbeansTab;
setObjectName(objectName); this.objectName = objectName;
text = objectName.getKeyProperty("name");
if (text == null) {
text = objectName.getDomain();
}
if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) { if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) {
icon = IconManager.MBEANSERVERDELEGATE; icon = IconManager.MBEANSERVERDELEGATE;
} else { } else {
icon = IconManager.MBEAN; icon = IconManager.MBEAN;
} }
this.broadcaster = isBroadcaster(objectName);
this.mbeanInfo = getMBeanInfo(objectName);
} }
MBeanServerConnection getMBeanServerConnection() { MBeanServerConnection getMBeanServerConnection() {
return mbeansTab.getMBeanServerConnection(); return mbeansTab.getMBeanServerConnection();
} }
public boolean isBroadcaster() { public Boolean isBroadcaster() {
return broadcaster; synchronized (broadcasterLock) {
} if (broadcaster == null) {
try {
private boolean isBroadcaster(ObjectName name) { broadcaster = getMBeanServerConnection().isInstanceOf(
try { getObjectName(),
return getMBeanServerConnection().isInstanceOf( "javax.management.NotificationBroadcaster");
name, "javax.management.NotificationBroadcaster"); } catch (Exception e) {
} catch (Exception e) { if (JConsole.isDebug()) {
System.out.println("Error calling isBroadcaster: " + System.err.println("Couldn't check if MBean [" +
e.getMessage()); objectName + "] is a notification broadcaster");
e.printStackTrace();
}
return false;
}
}
return broadcaster;
} }
return false;
} }
public Object invoke(String operationName) throws Exception { public Object invoke(String operationName) throws Exception {
@ -78,35 +87,35 @@ public class XMBean extends Object {
} }
public Object invoke(String operationName, Object params[], String sig[]) public Object invoke(String operationName, Object params[], String sig[])
throws Exception { throws Exception {
Object result = getMBeanServerConnection().invoke( Object result = getMBeanServerConnection().invoke(
getObjectName(), operationName, params, sig); getObjectName(), operationName, params, sig);
return result; return result;
} }
public void setAttribute(Attribute attribute) public void setAttribute(Attribute attribute)
throws AttributeNotFoundException, InstanceNotFoundException, throws AttributeNotFoundException, InstanceNotFoundException,
InvalidAttributeValueException, MBeanException, InvalidAttributeValueException, MBeanException,
ReflectionException, IOException { ReflectionException, IOException {
getMBeanServerConnection().setAttribute(getObjectName(), attribute); getMBeanServerConnection().setAttribute(getObjectName(), attribute);
} }
public Object getAttribute(String attributeName) public Object getAttribute(String attributeName)
throws AttributeNotFoundException, InstanceNotFoundException, throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException { MBeanException, ReflectionException, IOException {
return getMBeanServerConnection().getAttribute( return getMBeanServerConnection().getAttribute(
getObjectName(), attributeName); getObjectName(), attributeName);
} }
public AttributeList getAttributes(String attributeNames[]) public AttributeList getAttributes(String attributeNames[])
throws AttributeNotFoundException, InstanceNotFoundException, throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException { MBeanException, ReflectionException, IOException {
return getMBeanServerConnection().getAttributes( return getMBeanServerConnection().getAttributes(
getObjectName(), attributeNames); getObjectName(), attributeNames);
} }
public AttributeList getAttributes(MBeanAttributeInfo attributeNames[]) public AttributeList getAttributes(MBeanAttributeInfo attributeNames[])
throws AttributeNotFoundException, InstanceNotFoundException, throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException { MBeanException, ReflectionException, IOException {
String attributeString[] = new String[attributeNames.length]; String attributeString[] = new String[attributeNames.length];
for (int i = 0; i < attributeNames.length; i++) { for (int i = 0; i < attributeNames.length; i++) {
@ -119,32 +128,34 @@ public class XMBean extends Object {
return objectName; return objectName;
} }
private void setObjectName(ObjectName objectName) { public MBeanInfo getMBeanInfo() throws InstanceNotFoundException,
this.objectName = objectName; IntrospectionException, ReflectionException, IOException {
// generate a readable name now synchronized (mbeanInfoLock) {
String name = getObjectName().getKeyProperty("name"); if (mbeanInfo == null) {
if (name == null) mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName);
setText(getObjectName().getDomain()); }
else return mbeanInfo;
setText(name);
}
public MBeanInfo getMBeanInfo() {
return mbeanInfo;
}
private MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException, IOException {
return getMBeanServerConnection().getMBeanInfo(name);
}
public boolean equals(Object o) {
if (o instanceof XMBean) {
XMBean mbean = (XMBean) o;
return getObjectName().equals((mbean).getObjectName());
} }
return false; }
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof XMBean)) {
return false;
}
XMBean that = (XMBean) obj;
return getObjectName().equals(that.getObjectName());
}
@Override
public int hashCode() {
return (objectName == null ? 0 : objectName.hashCode());
} }
public String getText() { public String getText() {
@ -163,6 +174,7 @@ public class XMBean extends Object {
this.icon = icon; this.icon = icon;
} }
@Override
public String toString() { public String toString() {
return getText(); return getText();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -35,10 +35,7 @@ import javax.swing.*;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import javax.swing.event.*; import javax.swing.event.*;
import javax.swing.table.*; import javax.swing.table.*;
import javax.swing.tree.*;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.Resources; import sun.tools.jconsole.Resources;
import sun.tools.jconsole.inspector.XNodeInfo.Type;
import static sun.tools.jconsole.Utilities.*; import static sun.tools.jconsole.Utilities.*;
@ -46,21 +43,20 @@ import static sun.tools.jconsole.Utilities.*;
public class XMBeanInfo extends JPanel { public class XMBeanInfo extends JPanel {
private static final Color lightYellow = new Color(255, 255, 128); private static final Color lightYellow = new Color(255, 255, 128);
private final int NAME_COLUMN = 0; private final int NAME_COLUMN = 0;
private final int VALUE_COLUMN = 1; private final int VALUE_COLUMN = 1;
private final String[] columnNames = { private final String[] columnNames = {
Resources.getText("Name"), Resources.getText("Name"),
Resources.getText("Value") Resources.getText("Value")
}; };
private JTable infoTable = new JTable(); private JTable infoTable = new JTable();
private JTable descTable = new JTable(); private JTable descTable = new JTable();
private JPanel infoBorderPanel = new JPanel(new BorderLayout()); private JPanel infoBorderPanel = new JPanel(new BorderLayout());
private JPanel descBorderPanel = new JPanel(new BorderLayout()); private JPanel descBorderPanel = new JPanel(new BorderLayout());
private static class ReadOnlyDefaultTableModel extends DefaultTableModel { private static class ReadOnlyDefaultTableModel extends DefaultTableModel {
@Override
public void setValueAt(Object value, int row, int col) { public void setValueAt(Object value, int row, int col) {
} }
} }
@ -73,17 +69,18 @@ public class XMBeanInfo extends JPanel {
this.tableRowDividerText = tableRowDividerText; this.tableRowDividerText = tableRowDividerText;
} }
@Override
public String toString() { public String toString() {
return tableRowDividerText; return tableRowDividerText;
} }
} }
private static MBeanInfoTableCellRenderer renderer = private static MBeanInfoTableCellRenderer renderer =
new MBeanInfoTableCellRenderer(); new MBeanInfoTableCellRenderer();
private static class MBeanInfoTableCellRenderer private static class MBeanInfoTableCellRenderer
extends DefaultTableCellRenderer { extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent( public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) { boolean hasFocus, int row, int column) {
@ -92,22 +89,24 @@ public class XMBeanInfo extends JPanel {
if (value instanceof TableRowDivider) { if (value instanceof TableRowDivider) {
JLabel label = new JLabel(value.toString()); JLabel label = new JLabel(value.toString());
label.setBackground(ensureContrast(lightYellow, label.setBackground(ensureContrast(lightYellow,
label.getForeground())); label.getForeground()));
label.setOpaque(true); label.setOpaque(true);
return label; return label;
} }
return comp; return comp;
} }
} }
private static TableCellEditor editor = private static TableCellEditor editor =
new MBeanInfoTableCellEditor(new JTextField()); new MBeanInfoTableCellEditor(new JTextField());
private static class MBeanInfoTableCellEditor private static class MBeanInfoTableCellEditor
extends Utils.ReadOnlyTableCellEditor { extends Utils.ReadOnlyTableCellEditor {
public MBeanInfoTableCellEditor(JTextField tf) { public MBeanInfoTableCellEditor(JTextField tf) {
super(tf); super(tf);
} }
@Override
public Component getTableCellEditorComponent( public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, JTable table, Object value, boolean isSelected,
int row, int column) { int row, int column) {
@ -116,7 +115,7 @@ public class XMBeanInfo extends JPanel {
if (value instanceof TableRowDivider) { if (value instanceof TableRowDivider) {
JLabel label = new JLabel(value.toString()); JLabel label = new JLabel(value.toString());
label.setBackground(ensureContrast(lightYellow, label.setBackground(ensureContrast(lightYellow,
label.getForeground())); label.getForeground()));
label.setOpaque(true); label.setOpaque(true);
return label; return label;
} }
@ -172,6 +171,7 @@ public class XMBeanInfo extends JPanel {
add(descBorderPanel); add(descBorderPanel);
} }
// Call on EDT
public void emptyInfoTable() { public void emptyInfoTable() {
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
while (tableModel.getRowCount() > 0) { while (tableModel.getRowCount() > 0) {
@ -179,6 +179,7 @@ public class XMBeanInfo extends JPanel {
} }
} }
// Call on EDT
public void emptyDescTable() { public void emptyDescTable() {
DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel(); DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
while (tableModel.getRowCount() > 0) { while (tableModel.getRowCount() > 0) {
@ -186,6 +187,7 @@ public class XMBeanInfo extends JPanel {
} }
} }
// Call on EDT
private void addDescriptor(Descriptor desc, String text) { private void addDescriptor(Descriptor desc, String text) {
if (desc != null && desc.getFieldNames().length > 0) { if (desc != null && desc.getFieldNames().length > 0) {
DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel(); DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
@ -223,6 +225,7 @@ public class XMBeanInfo extends JPanel {
} }
} }
// Call on EDT
public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) { public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {
emptyInfoTable(); emptyInfoTable();
emptyDescTable(); emptyDescTable();
@ -263,6 +266,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel)); tableModel.newDataAvailable(new TableModelEvent(tableModel));
} }
// Call on EDT
public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) { public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {
emptyInfoTable(); emptyInfoTable();
emptyDescTable(); emptyDescTable();
@ -296,6 +300,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel)); tableModel.newDataAvailable(new TableModelEvent(tableModel));
} }
// Call on EDT
public void addMBeanOperationInfo(MBeanOperationInfo mboi) { public void addMBeanOperationInfo(MBeanOperationInfo mboi) {
emptyInfoTable(); emptyInfoTable();
emptyDescTable(); emptyDescTable();
@ -343,6 +348,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel)); tableModel.newDataAvailable(new TableModelEvent(tableModel));
} }
// Call on EDT
public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) { public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {
emptyInfoTable(); emptyInfoTable();
emptyDescTable(); emptyDescTable();
@ -367,6 +373,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel)); tableModel.newDataAvailable(new TableModelEvent(tableModel));
} }
// Call on EDT
private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) { private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
Object rowData[] = new Object[2]; Object rowData[] = new Object[2];
@ -383,6 +390,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel)); tableModel.newDataAvailable(new TableModelEvent(tableModel));
} }
// Call on EDT
private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) { private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
Object rowData[] = new Object[2]; Object rowData[] = new Object[2];
@ -401,91 +409,4 @@ public class XMBeanInfo extends JPanel {
addDescriptor(mbpi.getDescriptor(), text); addDescriptor(mbpi.getDescriptor(), text);
tableModel.newDataAvailable(new TableModelEvent(tableModel)); tableModel.newDataAvailable(new TableModelEvent(tableModel));
} }
public static void loadInfo(DefaultMutableTreeNode root) {
// Retrieve XMBean from XNodeInfo
//
XMBean mbean = (XMBean) ((XNodeInfo) root.getUserObject()).getData();
// Initialize MBean*Info
//
final MBeanInfo mbeanInfo;
try {
mbeanInfo = mbean.getMBeanInfo();
} catch (Exception e) {
if (JConsole.isDebug()) {
e.printStackTrace();
}
return;
}
MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
MBeanOperationInfo[] oi = mbeanInfo.getOperations();
MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();
// MBeanAttributeInfo node
//
if (ai != null && ai.length > 0) {
DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
Resources.getText("Attributes"), null);
attributes.setUserObject(attributesUO);
root.add(attributes);
for (MBeanAttributeInfo mbai : ai) {
DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
new Object[] {mbean, mbai}, mbai.getName(), null);
attribute.setUserObject(attributeUO);
attributes.add(attribute);
}
}
// MBeanOperationInfo node
//
if (oi != null && oi.length > 0) {
DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
Resources.getText("Operations"), null);
operations.setUserObject(operationsUO);
root.add(operations);
for (MBeanOperationInfo mboi : oi) {
// Compute the operation's tool tip text:
// "operationname(param1type,param2type,...)"
//
StringBuilder sb = new StringBuilder();
for (MBeanParameterInfo mbpi : mboi.getSignature()) {
sb.append(mbpi.getType() + ",");
}
String signature = sb.toString();
if (signature.length() > 0) {
// Remove the trailing ','
//
signature = signature.substring(0, signature.length() - 1);
}
String toolTipText = mboi.getName() + "(" + signature + ")";
// Create operation node
//
DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
new Object[] {mbean, mboi}, mboi.getName(), toolTipText);
operation.setUserObject(operationUO);
operations.add(operation);
}
}
// MBeanNotificationInfo node
//
if (mbean.isBroadcaster()) {
DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
Resources.getText("Notifications"), null);
notifications.setUserObject(notificationsUO);
root.add(notifications);
if (ni != null && ni.length > 0) {
for (MBeanNotificationInfo mbni : ni) {
DefaultMutableTreeNode notification =
new DefaultMutableTreeNode();
XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
mbni, mbni.getName(), null);
notification.setUserObject(notificationUO);
notifications.add(notification);
}
}
}
}
} }

View File

@ -29,17 +29,13 @@ import javax.swing.*;
import javax.swing.event.*; import javax.swing.event.*;
import javax.swing.table.*; import javax.swing.table.*;
import javax.swing.tree.*; import javax.swing.tree.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Font; import java.awt.Font;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.awt.FlowLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.event.*; import java.awt.event.*;
import java.awt.Insets;
import java.awt.Dimension; import java.awt.Dimension;
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
@ -49,45 +45,44 @@ import javax.management.*;
import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularData;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.Resources; import sun.tools.jconsole.Resources;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class XMBeanNotifications extends JTable implements NotificationListener { public class XMBeanNotifications extends JTable implements NotificationListener {
private final static String[] columnNames = { private final static String[] columnNames = {
Resources.getText("TimeStamp"), Resources.getText("TimeStamp"),
Resources.getText("Type"), Resources.getText("Type"),
Resources.getText("UserData"), Resources.getText("UserData"),
Resources.getText("SeqNum"), Resources.getText("SeqNum"),
Resources.getText("Message"), Resources.getText("Message"),
Resources.getText("Event"), Resources.getText("Event"),
Resources.getText("Source")}; Resources.getText("Source")
};
private HashMap<ObjectName, XMBeanNotificationsListener> listeners = private HashMap<ObjectName, XMBeanNotificationsListener> listeners =
new HashMap<ObjectName, XMBeanNotificationsListener>(); new HashMap<ObjectName, XMBeanNotificationsListener>();
private boolean subscribed; private volatile boolean subscribed;
private XMBeanNotificationsListener currentListener; private XMBeanNotificationsListener currentListener;
public final static String NOTIFICATION_RECEIVED_EVENT = public final static String NOTIFICATION_RECEIVED_EVENT =
"jconsole.xnotification.received"; "jconsole.xnotification.received";
private List<NotificationListener> notificationListenersList; private List<NotificationListener> notificationListenersList;
private boolean enabled; private volatile boolean enabled;
private Font normalFont, boldFont; private Font normalFont, boldFont;
private int rowMinHeight = -1; private int rowMinHeight = -1;
private TableCellEditor userDataEditor = new UserDataCellEditor(); private TableCellEditor userDataEditor = new UserDataCellEditor();
private NotifMouseListener mouseListener = new NotifMouseListener(); private NotifMouseListener mouseListener = new NotifMouseListener();
private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS"); private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS");
private static TableCellEditor editor = private static TableCellEditor editor =
new Utils.ReadOnlyTableCellEditor(new JTextField()); new Utils.ReadOnlyTableCellEditor(new JTextField());
public XMBeanNotifications() { public XMBeanNotifications() {
super(new TableSorter(columnNames,0)); super(new TableSorter(columnNames, 0));
setColumnSelectionAllowed(false); setColumnSelectionAllowed(false);
setRowSelectionAllowed(false); setRowSelectionAllowed(false);
getTableHeader().setReorderingAllowed(false); getTableHeader().setReorderingAllowed(false);
ArrayList<NotificationListener> l = ArrayList<NotificationListener> l =
new ArrayList<NotificationListener>(1); new ArrayList<NotificationListener>(1);
notificationListenersList = Collections.synchronizedList(l); notificationListenersList = Collections.synchronizedList(l);
addMouseListener(mouseListener); addMouseListener(mouseListener);
@ -103,20 +98,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener
addKeyListener(new Utils.CopyKeyAdapter()); addKeyListener(new Utils.CopyKeyAdapter());
} }
// Call on EDT
public void cancelCellEditing() { public void cancelCellEditing() {
TableCellEditor editor = getCellEditor(); TableCellEditor tce = getCellEditor();
if (editor != null) { if (tce != null) {
editor.cancelCellEditing(); tce.cancelCellEditing();
} }
} }
// Call on EDT
public void stopCellEditing() { public void stopCellEditing() {
TableCellEditor editor = getCellEditor(); TableCellEditor tce = getCellEditor();
if (editor != null) { if (tce != null) {
editor.stopCellEditing(); tce.stopCellEditing();
} }
} }
// Call on EDT
@Override
public boolean isCellEditable(int row, int col) { public boolean isCellEditable(int row, int col) {
UserDataCell cell = getUserDataCell(row, col); UserDataCell cell = getUserDataCell(row, col);
if (cell != null) { if (cell != null) {
@ -125,16 +124,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return true; return true;
} }
// Call on EDT
@Override
public void setValueAt(Object value, int row, int column) { public void setValueAt(Object value, int row, int column) {
} }
public synchronized Component prepareRenderer(TableCellRenderer renderer, // Call on EDT
int row, int column) { @Override
public synchronized Component prepareRenderer(
TableCellRenderer renderer, int row, int column) {
//In case we have a repaint thread that is in the process of //In case we have a repaint thread that is in the process of
//repainting an obsolete table, just ignore the call. //repainting an obsolete table, just ignore the call.
//It can happen when MBean selection is switched at a very quick rate //It can happen when MBean selection is switched at a very quick rate
if(row >= getRowCount()) if (row >= getRowCount()) {
return null; return null;
}
Component comp = super.prepareRenderer(renderer, row, column); Component comp = super.prepareRenderer(renderer, row, column);
@ -146,9 +150,10 @@ public class XMBeanNotifications extends JTable implements NotificationListener
if (column == 2 && cell != null) { if (column == 2 && cell != null) {
comp.setFont(boldFont); comp.setFont(boldFont);
int size = cell.getHeight(); int size = cell.getHeight();
if(size > 0) { if (size > 0) {
if(getRowHeight(row) != size) if (getRowHeight(row) != size) {
setRowHeight(row, size); setRowHeight(row, size);
}
} }
} else { } else {
comp.setFont(normalFont); comp.setFont(normalFont);
@ -157,34 +162,35 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return comp; return comp;
} }
public synchronized TableCellRenderer getCellRenderer(int row, // Call on EDT
int column) { @Override
public synchronized TableCellRenderer getCellRenderer(int row, int column) {
//In case we have a repaint thread that is in the process of //In case we have a repaint thread that is in the process of
//repainting an obsolete table, just ignore the call. //repainting an obsolete table, just ignore the call.
//It can happen when MBean selection is switched at a very quick rate //It can happen when MBean selection is switched at a very quick rate
if(row >= getRowCount()) if (row >= getRowCount()) {
return null; return null;
}
DefaultTableCellRenderer renderer; DefaultTableCellRenderer renderer;
String toolTip = null; String toolTip = null;
UserDataCell cell = getUserDataCell(row, column); UserDataCell cell = getUserDataCell(row, column);
if(cell != null && cell.isInited()) { if (cell != null && cell.isInited()) {
renderer = (DefaultTableCellRenderer) cell.getRenderer(); renderer = (DefaultTableCellRenderer) cell.getRenderer();
} } else {
else { renderer =
renderer = (DefaultTableCellRenderer) (DefaultTableCellRenderer) super.getCellRenderer(row, column);
super.getCellRenderer(row,
column);
} }
if(cell != null) if (cell != null) {
toolTip = Resources.getText("Double click to expand/collapse")+". " toolTip = Resources.getText("Double click to expand/collapse") +
+ cell.toString(); ". " + cell.toString();
else { } else {
Object val = Object val =
((DefaultTableModel) getModel()).getValueAt(row,column); ((DefaultTableModel) getModel()).getValueAt(row, column);
if(val != null) if (val != null) {
toolTip = val.toString(); toolTip = val.toString();
}
} }
renderer.setToolTipText(toolTip); renderer.setToolTipText(toolTip);
@ -192,9 +198,12 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return renderer; return renderer;
} }
// Call on EDT
private UserDataCell getUserDataCell(int row, int column) { private UserDataCell getUserDataCell(int row, int column) {
Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column); Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column);
if(obj instanceof UserDataCell) return (UserDataCell) obj; if (obj instanceof UserDataCell) {
return (UserDataCell) obj;
}
return null; return null;
} }
@ -204,19 +213,22 @@ public class XMBeanNotifications extends JTable implements NotificationListener
public long getReceivedNotifications(XMBean mbean) { public long getReceivedNotifications(XMBean mbean) {
XMBeanNotificationsListener listener = XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName()); listeners.get(mbean.getObjectName());
if(listener == null) return 0; if (listener == null) {
else return 0;
} else {
return listener.getReceivedNotifications(); return listener.getReceivedNotifications();
}
} }
public synchronized boolean clearCurrentNotifications() { public synchronized boolean clearCurrentNotifications() {
emptyTable(); emptyTable();
if(currentListener != null) { if (currentListener != null) {
currentListener.clear(); currentListener.clear();
return true; return true;
} else } else {
return false; return false;
}
} }
public synchronized boolean unregisterListener(DefaultMutableTreeNode node) { public synchronized boolean unregisterListener(DefaultMutableTreeNode node) {
@ -225,29 +237,25 @@ public class XMBeanNotifications extends JTable implements NotificationListener
} }
public synchronized void registerListener(DefaultMutableTreeNode node) public synchronized void registerListener(DefaultMutableTreeNode node)
throws InstanceNotFoundException, IOException { throws InstanceNotFoundException, IOException {
XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
if(!subscribed) { if (!subscribed) {
try { try {
mbean.getMBeanServerConnection(). mbean.getMBeanServerConnection().addNotificationListener(
addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"), MBeanServerDelegate.DELEGATE_NAME, this, null, null);
this,
null,
null);
subscribed = true; subscribed = true;
}catch(Exception e) { } catch (Exception e) {
System.out.println("Error adding listener for delegate :"+ if (JConsole.isDebug()) {
e.getMessage()); System.err.println("Error adding listener for delegate:");
e.printStackTrace();
}
} }
} }
XMBeanNotificationsListener listener = XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName()); listeners.get(mbean.getObjectName());
if (listener == null) { if (listener == null) {
listener = new XMBeanNotificationsListener(this, listener = new XMBeanNotificationsListener(
mbean, this, mbean, node, columnNames);
node,
columnNames);
listeners.put(mbean.getObjectName(), listener); listeners.put(mbean.getObjectName(), listener);
} else { } else {
if (!listener.isRegistered()) { if (!listener.isRegistered()) {
@ -259,19 +267,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener
currentListener = listener; currentListener = listener;
} }
public synchronized void handleNotification(Notification notif, public synchronized void handleNotification(
Object handback) { Notification notif, Object handback) {
try { try {
if (notif instanceof MBeanServerNotification) { if (notif instanceof MBeanServerNotification) {
ObjectName mbean = ObjectName mbean =
((MBeanServerNotification)notif).getMBeanName(); ((MBeanServerNotification) notif).getMBeanName();
if (notif.getType().indexOf("JMX.mbean.unregistered")>=0){ if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) {
unregister(mbean); unregister(mbean);
} }
} }
} catch(Exception e) { } catch (Exception e) {
System.out.println("Error unregistering notification:"+ if (JConsole.isDebug()) {
e.getMessage()); System.err.println("Error unregistering notification:");
e.printStackTrace();
}
} }
} }
@ -283,75 +293,77 @@ public class XMBeanNotifications extends JTable implements NotificationListener
private synchronized boolean unregister(ObjectName mbean) { private synchronized boolean unregister(ObjectName mbean) {
XMBeanNotificationsListener listener = listeners.get(mbean); XMBeanNotificationsListener listener = listeners.get(mbean);
if(listener != null && listener.isRegistered()) { if (listener != null && listener.isRegistered()) {
listener.unregister(); listener.unregister();
return true; return true;
} else } else {
return false; return false;
}
} }
public void addNotificationsListener(NotificationListener nl) { public void addNotificationsListener(NotificationListener nl) {
notificationListenersList.add(nl); notificationListenersList.add(nl);
} }
public void removeNotificationsListener(NotificationListener nl) { public void removeNotificationsListener(NotificationListener nl) {
notificationListenersList.remove(nl); notificationListenersList.remove(nl);
} }
void fireNotificationReceived(XMBeanNotificationsListener listener, // Call on EDT
XMBean mbean, void fireNotificationReceived(
DefaultMutableTreeNode node, XMBeanNotificationsListener listener, XMBean mbean,
Object[] rowData, DefaultMutableTreeNode node, Object[] rowData, long received) {
long received) { if (enabled) {
if(enabled) {
DefaultTableModel tableModel = (DefaultTableModel) getModel(); DefaultTableModel tableModel = (DefaultTableModel) getModel();
if(listener == currentListener) { if (listener == currentListener) {
//tableModel.addRow(rowData);
tableModel.insertRow(0, rowData); tableModel.insertRow(0, rowData);
//tableModel.newDataAvailable(new TableModelEvent(tableModel));
repaint(); repaint();
} }
} }
Notification notif =
Notification notif = new Notification(NOTIFICATION_RECEIVED_EVENT, new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0);
this, notif.setUserData(received);
0); for (NotificationListener nl : notificationListenersList) {
notif.setUserData(new Long(received)); nl.handleNotification(notif, node);
for(NotificationListener nl : notificationListenersList) }
nl.handleNotification(notif,node);
} }
// Call on EDT
private void updateModel(List<Object[]> data) { private void updateModel(List<Object[]> data) {
emptyTable(); emptyTable();
DefaultTableModel tableModel = (DefaultTableModel) getModel(); DefaultTableModel tableModel = (DefaultTableModel) getModel();
for(Object[] rowData : data) for (Object[] rowData : data) {
tableModel.addRow(rowData); tableModel.addRow(rowData);
}
} }
public synchronized boolean isListenerRegistered(XMBean mbean) { public synchronized boolean isListenerRegistered(XMBean mbean) {
XMBeanNotificationsListener listener = XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName()); listeners.get(mbean.getObjectName());
if(listener == null) return false; if (listener == null) {
return false;
}
return listener.isRegistered(); return listener.isRegistered();
} }
// Call on EDT
public synchronized void loadNotifications(XMBean mbean) { public synchronized void loadNotifications(XMBean mbean) {
XMBeanNotificationsListener listener = XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName()); listeners.get(mbean.getObjectName());
emptyTable(); emptyTable();
if(listener != null ) { if (listener != null) {
enabled = true; enabled = true;
List<Object[]> data = listener.getData(); List<Object[]> data = listener.getData();
updateModel(data); updateModel(data);
currentListener = listener; currentListener = listener;
validate(); validate();
repaint(); repaint();
} else } else {
enabled = false; enabled = false;
}
} }
// Call on EDT
private void setColumnEditors() { private void setColumnEditors() {
TableColumnModel tcm = getColumnModel(); TableColumnModel tcm = getColumnModel();
for (int i = 0; i < columnNames.length; i++) { for (int i = 0; i < columnNames.length; i++) {
@ -364,40 +376,40 @@ public class XMBeanNotifications extends JTable implements NotificationListener
} }
} }
// Call on EDT
public boolean isTableEditable() { public boolean isTableEditable() {
return true; return true;
} }
// Call on EDT
public synchronized void emptyTable() { public synchronized void emptyTable() {
DefaultTableModel model = (DefaultTableModel)getModel(); DefaultTableModel model = (DefaultTableModel) getModel();
//invalidate(); //invalidate();
while (model.getRowCount()>0) while (model.getRowCount() > 0) {
model.removeRow(0); model.removeRow(0);
}
validate(); validate();
} }
synchronized void updateUserDataCell(int row, // Call on EDT
int col) { synchronized void updateUserDataCell(int row, int col) {
Object obj = getModel().getValueAt(row, 2); Object obj = getModel().getValueAt(row, 2);
if(obj instanceof UserDataCell) { if (obj instanceof UserDataCell) {
UserDataCell cell = (UserDataCell) obj; UserDataCell cell = (UserDataCell) obj;
if(!cell.isInited()) { if (!cell.isInited()) {
if(rowMinHeight == -1) if (rowMinHeight == -1) {
rowMinHeight = getRowHeight(row); rowMinHeight = getRowHeight(row);
}
cell.init(super.getCellRenderer(row, col), cell.init(super.getCellRenderer(row, col), rowMinHeight);
rowMinHeight);
} }
cell.switchState(); cell.switchState();
setRowHeight(row, setRowHeight(row, cell.getHeight());
cell.getHeight());
if(!cell.isMaximized()) { if (!cell.isMaximized()) {
cancelCellEditing(); cancelCellEditing();
//Back to simple editor. //Back to simple editor.
editCellAt(row, editCellAt(row, 2);
2);
} }
invalidate(); invalidate();
@ -406,7 +418,9 @@ public class XMBeanNotifications extends JTable implements NotificationListener
} }
class UserDataCellRenderer extends DefaultTableCellRenderer { class UserDataCellRenderer extends DefaultTableCellRenderer {
Component comp; Component comp;
UserDataCellRenderer(Component comp) { UserDataCellRenderer(Component comp) {
this.comp = comp; this.comp = comp;
Dimension d = comp.getPreferredSize(); Dimension d = comp.getPreferredSize();
@ -415,56 +429,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener
} }
} }
public Component getTableCellRendererComponent(JTable table, @Override
Object value, public Component getTableCellRendererComponent(
boolean isSelected, JTable table,
boolean hasFocus, Object value,
int row, boolean isSelected,
int column) { boolean hasFocus,
int row,
int column) {
return comp; return comp;
} }
public Component getComponent() { public Component getComponent() {
return comp; return comp;
} }
} }
class UserDataCell { class UserDataCell {
TableCellRenderer minRenderer; TableCellRenderer minRenderer;
UserDataCellRenderer maxRenderer; UserDataCellRenderer maxRenderer;
int minHeight; int minHeight;
boolean minimized = true; boolean minimized = true;
boolean init = false; boolean init = false;
Object userData; Object userData;
UserDataCell(Object userData, Component max) {
this.userData = userData;
this.maxRenderer = new UserDataCellRenderer(max);
} UserDataCell(Object userData, Component max) {
this.userData = userData;
this.maxRenderer = new UserDataCellRenderer(max);
public String toString() { }
if(userData == null) return null;
if(userData.getClass().isArray()) {
String name =
Utils.getArrayClassName(userData.getClass().getName());
int length = Array.getLength(userData);
return name + "[" + length +"]";
}
if(userData instanceof CompositeData || @Override
userData instanceof TabularData) public String toString() {
if (userData == null) {
return null;
}
if (userData.getClass().isArray()) {
String name =
Utils.getArrayClassName(userData.getClass().getName());
int length = Array.getLength(userData);
return name + "[" + length + "]";
}
if (userData instanceof CompositeData ||
userData instanceof TabularData) {
return userData.getClass().getName(); return userData.getClass().getName();
}
return userData.toString(); return userData.toString();
} }
boolean isInited() { boolean isInited() {
return init; return init;
} }
void init(TableCellRenderer minRenderer, void init(TableCellRenderer minRenderer, int minHeight) {
int minHeight) {
this.minRenderer = minRenderer; this.minRenderer = minRenderer;
this.minHeight = minHeight; this.minHeight = minHeight;
init = true; init = true;
@ -473,9 +493,11 @@ public class XMBeanNotifications extends JTable implements NotificationListener
void switchState() { void switchState() {
minimized = !minimized; minimized = !minimized;
} }
boolean isMaximized() { boolean isMaximized() {
return !minimized; return !minimized;
} }
void minimize() { void minimize() {
minimized = true; minimized = true;
} }
@ -485,30 +507,39 @@ public class XMBeanNotifications extends JTable implements NotificationListener
} }
int getHeight() { int getHeight() {
if(minimized) return minHeight; if (minimized) {
else return minHeight;
} else {
return (int) maxRenderer.getComponent(). return (int) maxRenderer.getComponent().
getPreferredSize().getHeight() ; getPreferredSize().getHeight();
}
} }
TableCellRenderer getRenderer() { TableCellRenderer getRenderer() {
if(minimized) return minRenderer; if (minimized) {
else return maxRenderer; return minRenderer;
} else {
return maxRenderer;
}
} }
} }
class NotifMouseListener extends MouseAdapter { class NotifMouseListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) { if (e.getButton() == MouseEvent.BUTTON1) {
if(e.getClickCount() >= 2) { if (e.getClickCount() >= 2) {
int row = XMBeanNotifications.this.getSelectedRow(); int row = XMBeanNotifications.this.getSelectedRow();
int col = XMBeanNotifications.this.getSelectedColumn(); int col = XMBeanNotifications.this.getSelectedColumn();
if(col != 2) return; if (col != 2) {
if(col == -1 || row == -1) return; return;
}
if (col == -1 || row == -1) {
return;
}
XMBeanNotifications.this.updateUserDataCell(row, XMBeanNotifications.this.updateUserDataCell(row, col);
col);
} }
} }
} }
@ -516,20 +547,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener
class UserDataCellEditor extends XTextFieldEditor { class UserDataCellEditor extends XTextFieldEditor {
// implements javax.swing.table.TableCellEditor // implements javax.swing.table.TableCellEditor
public Component getTableCellEditorComponent(JTable table, @Override
Object value, public Component getTableCellEditorComponent(
boolean isSelected, JTable table,
int row, Object value,
int column) { boolean isSelected,
int row,
int column) {
Object val = value; Object val = value;
if(column == 2) { if (column == 2) {
Object obj = getModel().getValueAt(row, Object obj = getModel().getValueAt(row, column);
column); if (obj instanceof UserDataCell) {
if(obj instanceof UserDataCell) {
UserDataCell cell = (UserDataCell) obj; UserDataCell cell = (UserDataCell) obj;
if(cell.getRenderer() instanceof UserDataCellRenderer) { if (cell.getRenderer() instanceof UserDataCellRenderer) {
UserDataCellRenderer zr = UserDataCellRenderer zr =
(UserDataCellRenderer) cell.getRenderer(); (UserDataCellRenderer) cell.getRenderer();
return zr.getComponent(); return zr.getComponent();
} }
} else { } else {
@ -539,12 +571,14 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return comp; return comp;
} }
} }
return super.getTableCellEditorComponent(table, return super.getTableCellEditorComponent(
val, table,
isSelected, val,
row, isSelected,
column); row,
column);
} }
@Override @Override
public boolean stopCellEditing() { public boolean stopCellEditing() {
int editingRow = getEditingRow(); int editingRow = getEditingRow();
@ -554,7 +588,7 @@ public class XMBeanNotifications extends JTable implements NotificationListener
if (obj instanceof UserDataCell) { if (obj instanceof UserDataCell) {
UserDataCell cell = (UserDataCell) obj; UserDataCell cell = (UserDataCell) obj;
if (cell.isMaximized()) { if (cell.isMaximized()) {
this.cancelCellEditing(); cancelCellEditing();
return true; return true;
} }
} }
@ -564,17 +598,20 @@ public class XMBeanNotifications extends JTable implements NotificationListener
} }
class XMBeanNotificationsListener implements NotificationListener { class XMBeanNotificationsListener implements NotificationListener {
private String[] columnNames; private String[] columnNames;
private XMBean xmbean; private XMBean xmbean;
private DefaultMutableTreeNode node; private DefaultMutableTreeNode node;
private long received; private volatile long received;
private XMBeanNotifications notifications; private XMBeanNotifications notifications;
private boolean unregistered; private volatile boolean unregistered;
private ArrayList<Object[]> data = new ArrayList<Object[]>(); private ArrayList<Object[]> data = new ArrayList<Object[]>();
public XMBeanNotificationsListener(XMBeanNotifications notifications,
XMBean xmbean, public XMBeanNotificationsListener(
DefaultMutableTreeNode node, XMBeanNotifications notifications,
String[] columnNames) { XMBean xmbean,
DefaultMutableTreeNode node,
String[] columnNames) {
this.notifications = notifications; this.notifications = notifications;
this.xmbean = xmbean; this.xmbean = xmbean;
this.node = node; this.node = node;
@ -591,22 +628,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener
received = 0; received = 0;
} }
public boolean isRegistered() { public synchronized boolean isRegistered() {
return !unregistered; return !unregistered;
} }
public synchronized void unregister() { public synchronized void unregister() {
try { try {
xmbean.getMBeanServerConnection(). xmbean.getMBeanServerConnection().removeNotificationListener(
removeNotificationListener(xmbean.getObjectName(),this,null,null); xmbean.getObjectName(), this, null, null);
}catch(Exception e) { } catch (Exception e) {
System.out.println("Error removing listener :"+ if (JConsole.isDebug()) {
e.getMessage()); System.err.println("Error removing listener:");
e.printStackTrace();
}
} }
unregistered = true; unregistered = true;
} }
public long getReceivedNotifications() { public synchronized long getReceivedNotifications() {
return received; return received;
} }
@ -614,52 +653,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener
clear(); clear();
this.node = node; this.node = node;
try { try {
xmbean.getMBeanServerConnection(). xmbean.getMBeanServerConnection().addNotificationListener(
addNotificationListener(xmbean.getObjectName(),this,null,null); xmbean.getObjectName(), this, null, null);
unregistered = false; unregistered = false;
}catch(Exception e) { } catch (Exception e) {
System.out.println("Error adding listener :"+ if (JConsole.isDebug()) {
e.getMessage()); System.err.println("Error adding listener:");
e.printStackTrace();
}
} }
} }
public synchronized void handleNotification(Notification e, public synchronized void handleNotification(
Object handback) { final Notification n, Object hb) {
try { EventQueue.invokeLater(new Runnable() {
if(unregistered) return;
Date receivedDate = new Date(e.getTimeStamp());
String time = timeFormater.format(receivedDate);
Object userData = e.getUserData(); public void run() {
Component comp = null; synchronized (XMBeanNotificationsListener.this) {
UserDataCell cell = null; try {
if((comp = XDataViewer.createNotificationViewer(userData)) if (unregistered) {
!= null) { return;
XDataViewer.registerForMouseEvent(comp, mouseListener); }
cell = new UserDataCell(userData, comp); Date receivedDate = new Date(n.getTimeStamp());
String time = timeFormater.format(receivedDate);
Object userData = n.getUserData();
Component comp = null;
UserDataCell cell = null;
if ((comp = XDataViewer.createNotificationViewer(userData)) != null) {
XDataViewer.registerForMouseEvent(comp, mouseListener);
cell = new UserDataCell(userData, comp);
}
Object[] rowData = {
time,
n.getType(),
(cell == null ? userData : cell),
n.getSequenceNumber(),
n.getMessage(),
n,
n.getSource()
};
received++;
data.add(0, rowData);
notifications.fireNotificationReceived(
XMBeanNotificationsListener.this,
xmbean, node, rowData, received);
} catch (Exception e) {
if (JConsole.isDebug()) {
System.err.println("Error handling notification:");
e.printStackTrace();
}
}
}
} }
});
Object[] rowData = {time,
e.getType(),
(cell == null ? userData : cell),
new Long(e.getSequenceNumber()),
e.getMessage(),
e,
e.getSource()};
received++;
data.add(0, rowData);
notifications.fireNotificationReceived(this,
xmbean,
node,
rowData,
received);
}
catch (Exception ex) {
ex.printStackTrace();
System.out.println("Error when handling notification :"+
ex.toString());
}
} }
} }
} }

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import javax.management.*; import javax.management.*;

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
// java import // java import

View File

@ -33,10 +33,7 @@ import java.awt.BorderLayout;
import java.awt.GridLayout; import java.awt.GridLayout;
import java.awt.FlowLayout; import java.awt.FlowLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.*; import java.awt.event.*;
import java.awt.Insets;
import java.awt.Dimension;
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
@ -49,29 +46,30 @@ import sun.tools.jconsole.JConsole;
public abstract class XOperations extends JPanel implements ActionListener { public abstract class XOperations extends JPanel implements ActionListener {
public final static String OPERATION_INVOCATION_EVENT = public final static String OPERATION_INVOCATION_EVENT =
"jam.xoperations.invoke.result"; "jam.xoperations.invoke.result";
private java.util.List<NotificationListener> notificationListenersList; private java.util.List<NotificationListener> notificationListenersList;
private Hashtable<JButton, OperationEntry> operationEntryTable; private Hashtable<JButton, OperationEntry> operationEntryTable;
private XMBean mbean; private XMBean mbean;
private MBeanInfo mbeanInfo; private MBeanInfo mbeanInfo;
private MBeansTab mbeansTab; private MBeansTab mbeansTab;
public XOperations(MBeansTab mbeansTab) { public XOperations(MBeansTab mbeansTab) {
super(new GridLayout(1,1)); super(new GridLayout(1, 1));
this.mbeansTab = mbeansTab; this.mbeansTab = mbeansTab;
operationEntryTable = new Hashtable<JButton, OperationEntry>(); operationEntryTable = new Hashtable<JButton, OperationEntry>();
ArrayList<NotificationListener> l = ArrayList<NotificationListener> l =
new ArrayList<NotificationListener>(1); new ArrayList<NotificationListener>(1);
notificationListenersList = notificationListenersList =
Collections.synchronizedList(l); Collections.synchronizedList(l);
} }
// Call on EDT
public void removeOperations() { public void removeOperations() {
removeAll(); removeAll();
} }
public void loadOperations(XMBean mbean,MBeanInfo mbeanInfo) { // Call on EDT
public void loadOperations(XMBean mbean, MBeanInfo mbeanInfo) {
this.mbean = mbean; this.mbean = mbean;
this.mbeanInfo = mbeanInfo; this.mbeanInfo = mbeanInfo;
// add operations information // add operations information
@ -80,131 +78,149 @@ public abstract class XOperations extends JPanel implements ActionListener {
// remove listeners, if any // remove listeners, if any
Component listeners[] = getComponents(); Component listeners[] = getComponents();
for (int i = 0; i < listeners.length; i++) for (int i = 0; i < listeners.length; i++) {
if (listeners[i] instanceof JButton) if (listeners[i] instanceof JButton) {
((JButton)listeners[i]).removeActionListener(this); ((JButton) listeners[i]).removeActionListener(this);
}
}
removeAll(); removeAll();
setLayout(new BorderLayout()); setLayout(new BorderLayout());
JButton methodButton; JButton methodButton;
JLabel methodLabel; JLabel methodLabel;
JPanel innerPanelLeft,innerPanelRight; JPanel innerPanelLeft, innerPanelRight;
JPanel outerPanelLeft,outerPanelRight; JPanel outerPanelLeft, outerPanelRight;
outerPanelLeft = new JPanel(new GridLayout(operations.length,1)); outerPanelLeft = new JPanel(new GridLayout(operations.length, 1));
outerPanelRight = new JPanel(new GridLayout(operations.length,1)); outerPanelRight = new JPanel(new GridLayout(operations.length, 1));
for (int i=0;i<operations.length;i++) { for (int i = 0; i < operations.length; i++) {
innerPanelLeft = new JPanel(new FlowLayout(FlowLayout.RIGHT)); innerPanelLeft = new JPanel(new FlowLayout(FlowLayout.RIGHT));
innerPanelRight = new JPanel(new FlowLayout(FlowLayout.LEFT)); innerPanelRight = new JPanel(new FlowLayout(FlowLayout.LEFT));
innerPanelLeft.add(methodLabel = String returnType = operations[i].getReturnType();
new JLabel(Utils. if (returnType == null) {
getReadableClassName(operations[i]. methodLabel = new JLabel("null", JLabel.RIGHT);
getReturnType()), if (JConsole.isDebug()) {
JLabel.RIGHT)); System.err.println(
if (methodLabel.getText().length()>20) { "WARNING: The operation's return type " +
"shouldn't be \"null\". Check how the " +
"MBeanOperationInfo for the \"" +
operations[i].getName() + "\" operation has " +
"been defined in the MBean's implementation code.");
}
} else {
methodLabel = new JLabel(
Utils.getReadableClassName(returnType), JLabel.RIGHT);
}
innerPanelLeft.add(methodLabel);
if (methodLabel.getText().length() > 20) {
methodLabel.setText(methodLabel.getText(). methodLabel.setText(methodLabel.getText().
substring(methodLabel.getText(). substring(methodLabel.getText().
lastIndexOf(".")+1, lastIndexOf(".") + 1,
methodLabel.getText().length())); methodLabel.getText().length()));
} }
methodButton = new JButton(operations[i].getName()); methodButton = new JButton(operations[i].getName());
methodButton.setToolTipText(operations[i].getDescription()); methodButton.setToolTipText(operations[i].getDescription());
boolean callable = isCallable(operations[i].getSignature()); boolean callable = isCallable(operations[i].getSignature());
if(callable) if (callable) {
methodButton.addActionListener(this); methodButton.addActionListener(this);
else } else {
methodButton.setEnabled(false); methodButton.setEnabled(false);
}
MBeanParameterInfo[] signature = operations[i].getSignature(); MBeanParameterInfo[] signature = operations[i].getSignature();
OperationEntry paramEntry = new OperationEntry(operations[i], OperationEntry paramEntry = new OperationEntry(operations[i],
callable, callable,
methodButton, methodButton,
this); this);
operationEntryTable.put(methodButton, paramEntry); operationEntryTable.put(methodButton, paramEntry);
innerPanelRight.add(methodButton); innerPanelRight.add(methodButton);
if(signature.length==0) if (signature.length == 0) {
innerPanelRight.add(new JLabel("( )",JLabel.CENTER)); innerPanelRight.add(new JLabel("( )", JLabel.CENTER));
else } else {
innerPanelRight.add(paramEntry); innerPanelRight.add(paramEntry);
}
outerPanelLeft.add(innerPanelLeft,BorderLayout.WEST); outerPanelLeft.add(innerPanelLeft, BorderLayout.WEST);
outerPanelRight.add(innerPanelRight,BorderLayout.CENTER); outerPanelRight.add(innerPanelRight, BorderLayout.CENTER);
} }
add(outerPanelLeft,BorderLayout.WEST); add(outerPanelLeft, BorderLayout.WEST);
add(outerPanelRight,BorderLayout.CENTER); add(outerPanelRight, BorderLayout.CENTER);
validate(); validate();
} }
private boolean isCallable(MBeanParameterInfo[] signature) { private boolean isCallable(MBeanParameterInfo[] signature) {
for(int i = 0; i < signature.length; i++) { for (int i = 0; i < signature.length; i++) {
if(!Utils.isEditableType(signature[i].getType())) if (!Utils.isEditableType(signature[i].getType())) {
return false; return false;
}
} }
return true; return true;
} }
// Call on EDT
public void actionPerformed(final ActionEvent e) { public void actionPerformed(final ActionEvent e) {
performInvokeRequest((JButton)e.getSource()); performInvokeRequest((JButton) e.getSource());
} }
void performInvokeRequest(final JButton button) { void performInvokeRequest(final JButton button) {
mbeansTab.workerAdd(new Runnable() { final OperationEntry entryIf = operationEntryTable.get(button);
public void run() { new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() throws Exception {
return mbean.invoke(button.getText(),
entryIf.getParameters(), entryIf.getSignature());
}
@Override
protected void done() {
try { try {
OperationEntry entryIf = operationEntryTable.get(button); Object result = get();
Object result = null;
result = mbean.invoke(button.getText(),
entryIf.getParameters(),
entryIf.getSignature());
// sends result notification to upper level if // sends result notification to upper level if
// there is a return value // there is a return value
if (entryIf.getReturnType() != null && if (entryIf.getReturnType() != null &&
!entryIf.getReturnType().equals(Void.TYPE.getName()) && !entryIf.getReturnType().equals(Void.TYPE.getName()) &&
!entryIf.getReturnType().equals(Void.class.getName())) !entryIf.getReturnType().equals(Void.class.getName())) {
fireChangedNotification(OPERATION_INVOCATION_EVENT, fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
button, } else {
result); new ThreadDialog(
else button,
EventQueue.invokeLater(new ThreadDialog( Resources.getText("Method successfully invoked"),
button, Resources.getText("Info"),
Resources.getText("Method successfully invoked"), JOptionPane.INFORMATION_MESSAGE).run();
Resources.getText("Info"),
JOptionPane.INFORMATION_MESSAGE));
} catch (Throwable ex) {
if (JConsole.isDebug()) {
ex.printStackTrace();
} }
ex = Utils.getActualException(ex); } catch (Throwable t) {
String message = ex.toString(); t = Utils.getActualException(t);
EventQueue.invokeLater(new ThreadDialog( if (JConsole.isDebug()) {
button, t.printStackTrace();
Resources.getText("Problem invoking") + " " + }
button.getText() + " : " + message, new ThreadDialog(
Resources.getText("Error"), button,
JOptionPane.ERROR_MESSAGE)); Resources.getText("Problem invoking") + " " +
button.getText() + " : " + t.toString(),
Resources.getText("Error"),
JOptionPane.ERROR_MESSAGE).run();
} }
} }
}); }.execute();
} }
public void addOperationsListener(NotificationListener nl) { public void addOperationsListener(NotificationListener nl) {
notificationListenersList.add(nl); notificationListenersList.add(nl);
} }
public void removeOperationsListener(NotificationListener nl) { public void removeOperationsListener(NotificationListener nl) {
notificationListenersList.remove(nl); notificationListenersList.remove(nl);
} }
private void fireChangedNotification(String type, // Call on EDT
Object source, private void fireChangedNotification(
Object handback) { String type, Object source, Object handback) {
Notification e = new Notification(type,source,0); Notification n = new Notification(type, source, 0);
for(NotificationListener nl : notificationListenersList) for (NotificationListener nl : notificationListenersList) {
nl.handleNotification(e,handback); nl.handleNotification(n, handback);
}
} }
protected abstract MBeanOperationInfo[] protected abstract MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations);
updateOperations(MBeanOperationInfo[] operations);
} }

View File

@ -22,7 +22,9 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import sun.tools.jconsole.Plotter; import sun.tools.jconsole.Plotter;
import javax.swing.JTable; import javax.swing.JTable;
import java.awt.Graphics; import java.awt.Graphics;

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import java.awt.*; import java.awt.*;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@ package sun.tools.jconsole.inspector;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.io.*; import java.io.*;
import java.util.Enumeration;
import javax.management.*; import javax.management.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.*; import javax.swing.border.*;
@ -45,31 +44,22 @@ public class XSheet extends JPanel
private JPanel mainPanel; private JPanel mainPanel;
private JPanel southPanel; private JPanel southPanel;
// Node being currently displayed // Node being currently displayed
private DefaultMutableTreeNode node; private volatile DefaultMutableTreeNode currentNode;
// MBean being currently displayed // MBean being currently displayed
private XMBean mbean; private volatile XMBean mbean;
// XMBeanAttributes container // XMBeanAttributes container
private XMBeanAttributes mbeanAttributes; private XMBeanAttributes mbeanAttributes;
// XMBeanOperations container // XMBeanOperations container
private XMBeanOperations mbeanOperations; private XMBeanOperations mbeanOperations;
// XMBeanNotifications container // XMBeanNotifications container
private XMBeanNotifications mbeanNotifications; private XMBeanNotifications mbeanNotifications;
// XMBeanInfo container // XMBeanInfo container
private XMBeanInfo mbeanInfo; private XMBeanInfo mbeanInfo;
// Refresh JButton (mbean attributes case) // Refresh JButton (mbean attributes case)
private JButton refreshButton; private JButton refreshButton;
// Subscribe/Unsubscribe/Clear JButton (mbean notifications case) // Subscribe/Unsubscribe/Clear JButton (mbean notifications case)
private JButton clearButton, subscribeButton, unsubscribeButton; private JButton clearButton, subscribeButton, unsubscribeButton;
// Reference to MBeans tab // Reference to MBeans tab
private MBeansTab mbeansTab; private MBeansTab mbeansTab;
@ -86,6 +76,7 @@ public class XSheet extends JPanel
private void setupScreen() { private void setupScreen() {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setBorder(BorderFactory.createLineBorder(Color.GRAY));
// add main panel to XSheet // add main panel to XSheet
mainPanel = new JPanel(); mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout()); mainPanel.setLayout(new BorderLayout());
@ -129,17 +120,32 @@ public class XSheet extends JPanel
mbeanInfo = new XMBeanInfo(); mbeanInfo = new XMBeanInfo();
} }
public boolean isMBeanNode(DefaultMutableTreeNode node) { private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {
XNodeInfo uo = (XNodeInfo) node.getUserObject(); return (cn == n);
return uo.getType().equals(Type.MBEAN);
} }
public void displayNode(DefaultMutableTreeNode node) { // Call on EDT
private void showErrorDialog(Object message, String title) {
new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run();
}
public boolean isMBeanNode(DefaultMutableTreeNode node) {
Object userObject = node.getUserObject();
if (userObject instanceof XNodeInfo) {
XNodeInfo uo = (XNodeInfo) userObject;
return uo.getType().equals(Type.MBEAN);
}
return false;
}
// Call on EDT
public synchronized void displayNode(DefaultMutableTreeNode node) {
clear(); clear();
displayEmptyNode();
if (node == null) { if (node == null) {
displayEmptyNode();
return; return;
} }
currentNode = node;
Object userObject = node.getUserObject(); Object userObject = node.getUserObject();
if (userObject instanceof XNodeInfo) { if (userObject instanceof XNodeInfo) {
XNodeInfo uo = (XNodeInfo) userObject; XNodeInfo uo = (XNodeInfo) userObject;
@ -173,27 +179,28 @@ public class XSheet extends JPanel
} }
} }
// Call on EDT
private void displayMBeanNode(final DefaultMutableTreeNode node) { private void displayMBeanNode(final DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject(); final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.MBEAN)) { if (!uo.getType().equals(Type.MBEAN)) {
return; return;
} }
mbeansTab.workerAdd(new Runnable() { mbean = (XMBean) uo.getData();
public void run() { SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
@Override
public MBeanInfo doInBackground() throws InstanceNotFoundException,
IntrospectionException, ReflectionException, IOException {
return mbean.getMBeanInfo();
}
@Override
protected void done() {
try { try {
XSheet.this.node = node; MBeanInfo mbi = get();
XSheet.this.mbean = (XMBean) uo.getData(); if (mbi != null) {
mbeanInfo.addMBeanInfo(mbean, mbean.getMBeanInfo()); if (!isSelectedNode(node, currentNode)) {
} catch (Throwable ex) { return;
EventQueue.invokeLater(new ThreadDialog( }
XSheet.this, mbeanInfo.addMBeanInfo(mbean, mbi);
ex.getMessage(),
Resources.getText("Problem displaying MBean"),
JOptionPane.ERROR_MESSAGE));
return;
}
EventQueue.invokeLater(new Runnable() {
public void run() {
invalidate(); invalidate();
mainPanel.removeAll(); mainPanel.removeAll();
mainPanel.add(mbeanInfo, BorderLayout.CENTER); mainPanel.add(mbeanInfo, BorderLayout.CENTER);
@ -202,9 +209,19 @@ public class XSheet extends JPanel
validate(); validate();
repaint(); repaint();
} }
}); } catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Couldn't get MBeanInfo for MBean [" +
mbean.getObjectName() + "]");
t.printStackTrace();
}
showErrorDialog(t.toString(),
Resources.getText("Problem displaying MBean"));
}
} }
}); };
sw.execute();
} }
// Call on EDT // Call on EDT
@ -213,90 +230,90 @@ public class XSheet extends JPanel
final XMBeanInfo mbi = mbeanInfo; final XMBeanInfo mbi = mbeanInfo;
switch (uo.getType()) { switch (uo.getType()) {
case ATTRIBUTE: case ATTRIBUTE:
mbeansTab.workerAdd(new Runnable() { SwingWorker<MBeanAttributeInfo, Void> sw =
public void run() { new SwingWorker<MBeanAttributeInfo, Void>() {
Object attrData = uo.getData(); @Override
XSheet.this.mbean = (XMBean) ((Object[]) attrData)[0]; public MBeanAttributeInfo doInBackground() {
final MBeanAttributeInfo mbai = Object attrData = uo.getData();
(MBeanAttributeInfo) ((Object[]) attrData)[1]; mbean = (XMBean) ((Object[]) attrData)[0];
final XMBeanAttributes mba = mbeanAttributes; MBeanAttributeInfo mbai =
try { (MBeanAttributeInfo) ((Object[]) attrData)[1];
mba.loadAttributes(mbean, new MBeanInfo( mbeanAttributes.loadAttributes(mbean, new MBeanInfo(
null, null, new MBeanAttributeInfo[] {mbai}, null, null, new MBeanAttributeInfo[]{mbai},
null, null, null)); null, null, null));
} catch (Exception e) { return mbai;
EventQueue.invokeLater(new ThreadDialog(
XSheet.this,
e.getMessage(),
Resources.getText("Problem displaying MBean"),
JOptionPane.ERROR_MESSAGE));
return;
}
EventQueue.invokeLater(new Runnable() {
public void run() {
invalidate();
mainPanel.removeAll();
JPanel attributePanel =
new JPanel(new BorderLayout());
JPanel attributeBorderPanel =
new JPanel(new BorderLayout());
attributeBorderPanel.setBorder(
BorderFactory.createTitledBorder(
Resources.getText("Attribute value")));
JPanel attributeValuePanel =
new JPanel(new BorderLayout());
attributeValuePanel.setBorder(
LineBorder.createGrayLineBorder());
attributeValuePanel.add(mba.getTableHeader(),
BorderLayout.PAGE_START);
attributeValuePanel.add(mba,
BorderLayout.CENTER);
attributeBorderPanel.add(attributeValuePanel,
BorderLayout.CENTER);
JPanel refreshButtonPanel = new JPanel();
refreshButtonPanel.add(refreshButton);
attributeBorderPanel.add(refreshButtonPanel,
BorderLayout.SOUTH);
refreshButton.setEnabled(true);
attributePanel.add(attributeBorderPanel,
BorderLayout.NORTH);
mbi.addMBeanAttributeInfo(mbai);
attributePanel.add(mbi, BorderLayout.CENTER);
mainPanel.add(attributePanel,
BorderLayout.CENTER);
southPanel.setVisible(false);
southPanel.removeAll();
validate();
repaint();
} }
}); @Override
} protected void done() {
}); try {
MBeanAttributeInfo mbai = get();
if (!isSelectedNode(node, currentNode)) {
return;
}
invalidate();
mainPanel.removeAll();
JPanel attributePanel =
new JPanel(new BorderLayout());
JPanel attributeBorderPanel =
new JPanel(new BorderLayout());
attributeBorderPanel.setBorder(
BorderFactory.createTitledBorder(
Resources.getText("Attribute value")));
JPanel attributeValuePanel =
new JPanel(new BorderLayout());
attributeValuePanel.setBorder(
LineBorder.createGrayLineBorder());
attributeValuePanel.add(mbeanAttributes.getTableHeader(),
BorderLayout.PAGE_START);
attributeValuePanel.add(mbeanAttributes,
BorderLayout.CENTER);
attributeBorderPanel.add(attributeValuePanel,
BorderLayout.CENTER);
JPanel refreshButtonPanel = new JPanel();
refreshButtonPanel.add(refreshButton);
attributeBorderPanel.add(refreshButtonPanel,
BorderLayout.SOUTH);
refreshButton.setEnabled(true);
attributePanel.add(attributeBorderPanel,
BorderLayout.NORTH);
mbi.addMBeanAttributeInfo(mbai);
attributePanel.add(mbi, BorderLayout.CENTER);
mainPanel.add(attributePanel,
BorderLayout.CENTER);
southPanel.setVisible(false);
southPanel.removeAll();
validate();
repaint();
} catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Problem displaying MBean " +
"attribute for MBean [" +
mbean.getObjectName() + "]");
t.printStackTrace();
}
showErrorDialog(t.toString(),
Resources.getText("Problem displaying MBean"));
}
}
};
sw.execute();
break; break;
case OPERATION: case OPERATION:
Object operData = uo.getData(); Object operData = uo.getData();
XSheet.this.mbean = (XMBean) ((Object[]) operData)[0]; mbean = (XMBean) ((Object[]) operData)[0];
MBeanOperationInfo mboi = MBeanOperationInfo mboi =
(MBeanOperationInfo) ((Object[]) operData)[1]; (MBeanOperationInfo) ((Object[]) operData)[1];
XMBeanOperations mbo = mbeanOperations; mbeanOperations.loadOperations(mbean,
try { new MBeanInfo(null, null, null, null,
mbo.loadOperations(mbean, new MBeanInfo(null, null, null, new MBeanOperationInfo[]{mboi}, null));
null, new MBeanOperationInfo[] {mboi}, null));
} catch (Exception e) {
EventQueue.invokeLater(new ThreadDialog(
XSheet.this,
e.getMessage(),
Resources.getText("Problem displaying MBean"),
JOptionPane.ERROR_MESSAGE));
return;
}
invalidate(); invalidate();
mainPanel.removeAll(); mainPanel.removeAll();
JPanel operationPanel = new JPanel(new BorderLayout()); JPanel operationPanel = new JPanel(new BorderLayout());
JPanel operationBorderPanel = new JPanel(new BorderLayout()); JPanel operationBorderPanel = new JPanel(new BorderLayout());
operationBorderPanel.setBorder(BorderFactory.createTitledBorder( operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Operation invocation"))); Resources.getText("Operation invocation")));
operationBorderPanel.add(new JScrollPane(mbo)); operationBorderPanel.add(new JScrollPane(mbeanOperations));
operationPanel.add(operationBorderPanel, BorderLayout.NORTH); operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
mbi.addMBeanOperationInfo(mboi); mbi.addMBeanOperationInfo(mboi);
operationPanel.add(mbi, BorderLayout.CENTER); operationPanel.add(mbi, BorderLayout.CENTER);
@ -320,134 +337,134 @@ public class XSheet extends JPanel
} }
} }
// Call on EDT
private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) { private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject(); final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.ATTRIBUTES)) { if (!uo.getType().equals(Type.ATTRIBUTES)) {
return; return;
} }
final XMBeanAttributes mba = mbeanAttributes; mbean = (XMBean) uo.getData();
mbeansTab.workerAdd(new Runnable() { SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
public void run() { @Override
try { public Void doInBackground() throws InstanceNotFoundException,
XSheet.this.node = node; IntrospectionException, ReflectionException, IOException {
XSheet.this.mbean = (XMBean) uo.getData(); mbeanAttributes.loadAttributes(mbean, mbean.getMBeanInfo());
mba.loadAttributes(mbean, mbean.getMBeanInfo()); return null;
} catch (Throwable ex) {
EventQueue.invokeLater(new ThreadDialog(
XSheet.this,
ex.getMessage(),
Resources.getText("Problem displaying MBean"),
JOptionPane.ERROR_MESSAGE));
return;
}
EventQueue.invokeLater(new Runnable() {
public void run() {
invalidate();
mainPanel.removeAll();
JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Attribute values")));
borderPanel.add(new JScrollPane(mba));
mainPanel.add(borderPanel, BorderLayout.CENTER);
// add the refresh button to the south panel
southPanel.removeAll();
southPanel.add(refreshButton, BorderLayout.SOUTH);
southPanel.setVisible(true);
refreshButton.setEnabled(true);
validate();
repaint();
}
});
} }
}); @Override
protected void done() {
try {
get();
if (!isSelectedNode(node, currentNode)) {
return;
}
invalidate();
mainPanel.removeAll();
JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Attribute values")));
borderPanel.add(new JScrollPane(mbeanAttributes));
mainPanel.add(borderPanel, BorderLayout.CENTER);
// add the refresh button to the south panel
southPanel.removeAll();
southPanel.add(refreshButton, BorderLayout.SOUTH);
southPanel.setVisible(true);
refreshButton.setEnabled(true);
validate();
repaint();
} catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Problem displaying MBean " +
"attributes for MBean [" +
mbean.getObjectName() + "]");
t.printStackTrace();
}
showErrorDialog(t.toString(),
Resources.getText("Problem displaying MBean"));
}
}
};
sw.execute();
} }
// Call on EDT
private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) { private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject(); final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.OPERATIONS)) { if (!uo.getType().equals(Type.OPERATIONS)) {
return; return;
} }
final XMBeanOperations mbo = mbeanOperations; mbean = (XMBean) uo.getData();
mbeansTab.workerAdd(new Runnable() { SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
public void run() { @Override
public MBeanInfo doInBackground() throws InstanceNotFoundException,
IntrospectionException, ReflectionException, IOException {
return mbean.getMBeanInfo();
}
@Override
protected void done() {
try { try {
XSheet.this.node = node; MBeanInfo mbi = get();
XSheet.this.mbean = (XMBean) uo.getData(); if (mbi != null) {
mbo.loadOperations(mbean, mbean.getMBeanInfo()); if (!isSelectedNode(node, currentNode)) {
} catch (Throwable ex) { return;
EventQueue.invokeLater(new ThreadDialog( }
XSheet.this, mbeanOperations.loadOperations(mbean, mbi);
ex.getMessage(),
Resources.getText("Problem displaying MBean"),
JOptionPane.ERROR_MESSAGE));
return;
}
EventQueue.invokeLater(new Runnable() {
public void run() {
invalidate(); invalidate();
mainPanel.removeAll(); mainPanel.removeAll();
JPanel borderPanel = new JPanel(new BorderLayout()); JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.setBorder(BorderFactory.createTitledBorder( borderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Operation invocation"))); Resources.getText("Operation invocation")));
borderPanel.add(new JScrollPane(mbo)); borderPanel.add(new JScrollPane(mbeanOperations));
mainPanel.add(borderPanel, BorderLayout.CENTER); mainPanel.add(borderPanel, BorderLayout.CENTER);
southPanel.setVisible(false); southPanel.setVisible(false);
southPanel.removeAll(); southPanel.removeAll();
validate(); validate();
repaint(); repaint();
} }
}); } catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Problem displaying MBean " +
"operations for MBean [" +
mbean.getObjectName() + "]");
t.printStackTrace();
}
showErrorDialog(t.toString(),
Resources.getText("Problem displaying MBean"));
}
} }
}); };
sw.execute();
} }
private void displayMBeanNotificationsNode( // Call on EDT
final DefaultMutableTreeNode node) { private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject(); final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.NOTIFICATIONS)) { if (!uo.getType().equals(Type.NOTIFICATIONS)) {
return; return;
} }
final XMBeanNotifications mbn = mbeanNotifications; mbean = (XMBean) uo.getData();
mbeansTab.workerAdd(new Runnable() { mbeanNotifications.loadNotifications(mbean);
public void run() { updateNotifications();
try { invalidate();
XSheet.this.node = node; mainPanel.removeAll();
XSheet.this.mbean = (XMBean) uo.getData(); JPanel borderPanel = new JPanel(new BorderLayout());
mbn.loadNotifications(mbean); borderPanel.setBorder(BorderFactory.createTitledBorder(
updateNotifications(); Resources.getText("Notification buffer")));
} catch (Throwable ex) { borderPanel.add(new JScrollPane(mbeanNotifications));
EventQueue.invokeLater(new ThreadDialog( mainPanel.add(borderPanel, BorderLayout.CENTER);
XSheet.this, // add the subscribe/unsubscribe/clear buttons to the south panel
ex.getMessage(), southPanel.removeAll();
Resources.getText("Problem displaying MBean"), southPanel.add(subscribeButton, BorderLayout.WEST);
JOptionPane.ERROR_MESSAGE)); southPanel.add(unsubscribeButton, BorderLayout.CENTER);
return; southPanel.add(clearButton, BorderLayout.EAST);
} southPanel.setVisible(true);
EventQueue.invokeLater(new Runnable() { subscribeButton.setEnabled(true);
public void run() { unsubscribeButton.setEnabled(true);
invalidate(); clearButton.setEnabled(true);
mainPanel.removeAll(); validate();
JPanel borderPanel = new JPanel(new BorderLayout()); repaint();
borderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Notification buffer")));
borderPanel.add(new JScrollPane(mbn));
mainPanel.add(borderPanel, BorderLayout.CENTER);
// add the subscribe/unsubscribe/clear buttons to
// the south panel
southPanel.removeAll();
southPanel.add(subscribeButton, BorderLayout.WEST);
southPanel.add(unsubscribeButton, BorderLayout.CENTER);
southPanel.add(clearButton, BorderLayout.EAST);
southPanel.setVisible(true);
subscribeButton.setEnabled(true);
unsubscribeButton.setEnabled(true);
clearButton.setEnabled(true);
validate();
repaint();
}
});
}
});
} }
// Call on EDT // Call on EDT
@ -462,21 +479,60 @@ public class XSheet extends JPanel
/** /**
* Subscribe button action. * Subscribe button action.
*/ */
private void registerListener() throws InstanceNotFoundException, private void registerListener() {
IOException { new SwingWorker<Void, Void>() {
mbeanNotifications.registerListener(node); @Override
updateNotifications(); public Void doInBackground()
validate(); throws InstanceNotFoundException, IOException {
mbeanNotifications.registerListener(currentNode);
return null;
}
@Override
protected void done() {
try {
get();
updateNotifications();
validate();
} catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Problem adding listener");
t.printStackTrace();
}
showErrorDialog(t.getMessage(),
Resources.getText("Problem adding listener"));
}
}
}.execute();
} }
/** /**
* Unsubscribe button action. * Unsubscribe button action.
*/ */
private void unregisterListener() { private void unregisterListener() {
if (mbeanNotifications.unregisterListener(node)) { new SwingWorker<Boolean, Void>() {
clearNotifications(); @Override
validate(); public Boolean doInBackground() {
} return mbeanNotifications.unregisterListener(currentNode);
}
@Override
protected void done() {
try {
if (get()) {
updateNotifications();
validate();
}
} catch (Exception e) {
Throwable t = Utils.getActualException(e);
if (JConsole.isDebug()) {
System.err.println("Problem removing listener");
t.printStackTrace();
}
showErrorDialog(t.getMessage(),
Resources.getText("Problem removing listener"));
}
}
}.execute();
} }
/** /**
@ -486,15 +542,11 @@ public class XSheet extends JPanel
mbeanAttributes.refreshAttributes(); mbeanAttributes.refreshAttributes();
} }
// Call on EDT
private void updateNotifications() { private void updateNotifications() {
if (mbean.isBroadcaster()) { if (mbeanNotifications.isListenerRegistered(mbean)) {
if (mbeanNotifications.isListenerRegistered(mbean)) { long received = mbeanNotifications.getReceivedNotifications(mbean);
long received = updateReceivedNotifications(currentNode, received, false);
mbeanNotifications.getReceivedNotifications(mbean);
updateReceivedNotifications(node, received, false);
} else {
clearNotifications();
}
} else { } else {
clearNotifications(); clearNotifications();
} }
@ -503,11 +555,11 @@ public class XSheet extends JPanel
/** /**
* Update notification node label in MBean tree: "Notifications[received]". * Update notification node label in MBean tree: "Notifications[received]".
*/ */
// Call on EDT
private void updateReceivedNotifications( private void updateReceivedNotifications(
DefaultMutableTreeNode emitter, long received, boolean bold) { DefaultMutableTreeNode emitter, long received, boolean bold) {
String text = Resources.getText("Notifications") + "[" + received + "]"; String text = Resources.getText("Notifications") + "[" + received + "]";
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
mbeansTab.getTree().getLastSelectedPathComponent();
if (bold && emitter != selectedNode) { if (bold && emitter != selectedNode) {
text = "<html><b>" + text + "</b></html>"; text = "<html><b>" + text + "</b></html>";
} }
@ -517,41 +569,40 @@ public class XSheet extends JPanel
/** /**
* Update notification node label in MBean tree: "Notifications". * Update notification node label in MBean tree: "Notifications".
*/ */
// Call on EDT
private void clearNotifications() { private void clearNotifications() {
updateNotificationsNodeLabel(node, updateNotificationsNodeLabel(currentNode,
Resources.getText("Notifications")); Resources.getText("Notifications"));
} }
/** /**
* Update notification node label in MBean tree: "Notifications[0]". * Update notification node label in MBean tree: "Notifications[0]".
*/ */
// Call on EDT
private void clearNotifications0() { private void clearNotifications0() {
updateNotificationsNodeLabel(node, updateNotificationsNodeLabel(currentNode,
Resources.getText("Notifications") + "[0]"); Resources.getText("Notifications") + "[0]");
} }
/** /**
* Update the label of the supplied MBean tree node. * Update the label of the supplied MBean tree node.
*/ */
// Call on EDT
private void updateNotificationsNodeLabel( private void updateNotificationsNodeLabel(
final DefaultMutableTreeNode node, final String label) { DefaultMutableTreeNode node, String label) {
EventQueue.invokeLater(new Runnable() { synchronized (mbeansTab.getTree()) {
public void run() { invalidate();
synchronized (mbeansTab.getTree()) { XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
invalidate(); XNodeInfo newUserObject = new XNodeInfo(
XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject(); oldUserObject.getType(), oldUserObject.getData(),
XNodeInfo newUserObject = new XNodeInfo( label, oldUserObject.getToolTipText());
oldUserObject.getType(), oldUserObject.getData(), node.setUserObject(newUserObject);
label, oldUserObject.getToolTipText()); DefaultTreeModel model =
node.setUserObject(newUserObject); (DefaultTreeModel) mbeansTab.getTree().getModel();
DefaultTreeModel model = model.nodeChanged(node);
(DefaultTreeModel) mbeansTab.getTree().getModel(); validate();
model.nodeChanged(node); repaint();
validate(); }
repaint();
}
}
});
} }
/** /**
@ -577,6 +628,7 @@ public class XSheet extends JPanel
} }
} }
// Call on EDT
private void clear() { private void clear() {
mbeanAttributes.stopCellEditing(); mbeanAttributes.stopCellEditing();
mbeanAttributes.emptyTable(); mbeanAttributes.emptyTable();
@ -586,13 +638,14 @@ public class XSheet extends JPanel
mbeanNotifications.emptyTable(); mbeanNotifications.emptyTable();
mbeanNotifications.disableNotifications(); mbeanNotifications.disableNotifications();
mbean = null; mbean = null;
node = null; currentNode = null;
} }
/** /**
* Notification listener: handles asynchronous reception * Notification listener: handles asynchronous reception
* of MBean operation results and MBean notifications. * of MBean operation results and MBean notifications.
*/ */
// Call on EDT
public void handleNotification(Notification e, Object handback) { public void handleNotification(Notification e, Object handback) {
// Operation result // Operation result
if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) { if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) {
@ -628,13 +681,12 @@ public class XSheet extends JPanel
message = comp; message = comp;
} }
} }
EventQueue.invokeLater(new ThreadDialog( new ThreadDialog(
(Component) e.getSource(), (Component) e.getSource(),
message, message,
Resources.getText("Operation return value"), Resources.getText("Operation return value"),
JOptionPane.INFORMATION_MESSAGE)); JOptionPane.INFORMATION_MESSAGE).run();
} } // Got notification
// Got notification
else if (e.getType().equals( else if (e.getType().equals(
XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) { XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {
DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback; DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;
@ -646,16 +698,19 @@ public class XSheet extends JPanel
/** /**
* Action listener: handles actions in panel buttons * Action listener: handles actions in panel buttons
*/ */
// Call on EDT
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) { if (e.getSource() instanceof JButton) {
JButton button = (JButton) e.getSource(); JButton button = (JButton) e.getSource();
// Refresh button // Refresh button
if (button == refreshButton) { if (button == refreshButton) {
mbeansTab.workerAdd(new Runnable() { new SwingWorker<Void, Void>() {
public void run() { @Override
public Void doInBackground() {
refreshAttributes(); refreshAttributes();
return null;
} }
}); }.execute();
return; return;
} }
// Clear button // Clear button
@ -665,38 +720,12 @@ public class XSheet extends JPanel
} }
// Subscribe button // Subscribe button
if (button == subscribeButton) { if (button == subscribeButton) {
mbeansTab.workerAdd(new Runnable() { registerListener();
public void run() {
try {
registerListener();
} catch (Throwable ex) {
ex = Utils.getActualException(ex);
EventQueue.invokeLater(new ThreadDialog(
XSheet.this,
ex.getMessage(),
Resources.getText("Problem adding listener"),
JOptionPane.ERROR_MESSAGE));
}
}
});
return; return;
} }
// Unsubscribe button // Unsubscribe button
if (button == unsubscribeButton) { if (button == unsubscribeButton) {
mbeansTab.workerAdd(new Runnable() { unregisterListener();
public void run() {
try {
unregisterListener();
} catch (Throwable ex) {
ex = Utils.getActualException(ex);
EventQueue.invokeLater(new ThreadDialog(
XSheet.this,
ex.getMessage(),
Resources.getText("Problem removing listener"),
JOptionPane.ERROR_MESSAGE));
}
}
});
return; return;
} }
} }

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import javax.swing.*; import javax.swing.*;

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import java.awt.*; import java.awt.*;

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or * CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions. * have any questions.
*/ */
package sun.tools.jconsole.inspector; package sun.tools.jconsole.inspector;
import java.awt.Component; import java.awt.Component;

File diff suppressed because it is too large Load Diff