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.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package sun.tools.jconsole;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
@ -42,7 +43,8 @@ import com.sun.tools.jconsole.JConsoleContext;
@SuppressWarnings("serial")
public class MBeansTab extends Tab implements
NotificationListener, PropertyChangeListener, TreeSelectionListener {
NotificationListener, PropertyChangeListener,
TreeSelectionListener, TreeWillExpandListener {
private XTree tree;
private XSheet sheet;
@ -70,6 +72,7 @@ public class MBeansTab extends Tab implements
return sheet;
}
@Override
public void dispose() {
super.dispose();
sheet.dispose();
@ -79,61 +82,79 @@ public class MBeansTab extends Tab implements
return vmPanel.getUpdateInterval();
}
void synchroniseMBeanServerView() {
// Register listener for MBean registration/unregistration
//
try {
getMBeanServerConnection().addNotificationListener(
MBeanServerDelegate.DELEGATE_NAME,
this,
null,
null);
} catch (InstanceNotFoundException e) {
// Should never happen because the MBeanServerDelegate
// is always present in any standard MBeanServer
//
if (JConsole.isDebug()) {
e.printStackTrace();
private void buildMBeanServerView() {
new SwingWorker<Set<ObjectName>, Void>() {
@Override
public Set<ObjectName> doInBackground() {
// Register listener for MBean registration/unregistration
//
try {
getMBeanServerConnection().addNotificationListener(
MBeanServerDelegate.DELEGATE_NAME,
MBeansTab.this,
null,
null);
} catch (InstanceNotFoundException e) {
// Should never happen because the MBeanServerDelegate
// 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) {
if (JConsole.isDebug()) {
e.printStackTrace();
@Override
protected void done() {
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();
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);
}.execute();
}
public MBeanServerConnection getMBeanServerConnection() {
return vmPanel.getProxyClient().getMBeanServerConnection();
}
@Override
public void update() {
// Ping the connection to see if it is still alive. At
// some point the ProxyClient class should centralize
@ -160,6 +181,7 @@ public class MBeansTab extends Tab implements
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.addTreeSelectionListener(this);
tree.addTreeWillExpandListener(this);
tree.addMouseListener(ml);
JScrollPane theScrollPane = new JScrollPane(
tree,
@ -177,55 +199,55 @@ public class MBeansTab extends Tab implements
add(mainSplit);
}
/* notification listener */
public void handleNotification(Notification notification, Object handback) {
if (notification instanceof MBeanServerNotification) {
ObjectName mbean =
((MBeanServerNotification) notification).getMBeanName();
if (notification.getType().equals(
MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
tree.addMBeanToView(mbean);
} else if (notification.getType().equals(
MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
tree.delMBeanFromView(mbean);
/* notification listener: handleNotification */
public void handleNotification(
final Notification notification, Object handback) {
EventQueue.invokeLater(new Runnable() {
public void run() {
if (notification instanceof MBeanServerNotification) {
ObjectName mbean =
((MBeanServerNotification) notification).getMBeanName();
if (notification.getType().equals(
MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
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) {
if (evt.getPropertyName() == JConsoleContext.CONNECTION_STATE_PROPERTY) {
if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {
boolean connected = (Boolean) evt.getNewValue();
if (connected) {
workerAdd(new Runnable() {
public void run() {
synchroniseMBeanServerView();
}
});
buildMBeanServerView();
} else {
sheet.dispose();
}
}
}
/* tree selection listener */
/* tree selection listener: valueChanged */
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
sheet.displayNode(node);
}
/* tree mouse listener */
/* tree mouse listener: mousePressed */
private MouseListener ml = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 1) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
if (selRow != -1) {
TreePath selPath =
tree.getPathForLocation(e.getX(), e.getY());
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
selPath.getLastPathComponent();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) selPath.getLastPathComponent();
if (sheet.isMBeanNode(node)) {
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
* have any questions.
*/
package sun.tools.jconsole;
import java.lang.management.MemoryUsage;

View File

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

View File

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

View File

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

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.tools.jconsole.inspector;
// 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.
*
* 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.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ExecutionException;
import javax.management.*;
import javax.management.openmbean.*;
import javax.swing.*;
import javax.swing.text.*;
import java.util.*;
public class Utils {
private Utils() {
}
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_HOME, KeyEvent.VK_END,
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
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 =
new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {
new HashSet<Class<?>>(Arrays.asList(new 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 Map<String, Class<?>> primitiveMap =
new HashMap<String, Class<?>>();
private static final Map<String, Class<?>> primitiveToWrapper =
new HashMap<String, Class<?>>();
private static final Set<String> editableTypes = new HashSet<String>();
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,
String.class, ObjectName.class}));
String.class, ObjectName.class
}));
private static final Set<String> numericalTypes = new HashSet<String>();
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(),
Number.class.getName()}));
Number.class.getName()
}));
private static final Set<String> booleanTypes =
new HashSet<String>(Arrays.asList(new String[] {
Boolean.TYPE.getName(), Boolean.class.getName()}));
new HashSet<String>(Arrays.asList(new String[]{
Boolean.TYPE.getName(), Boolean.class.getName()
}));
static {
// compute primitives/primitiveMap/primitiveToWrapper
@ -122,10 +118,11 @@ public class Utils {
* It's used to cater for the primitive types.
*/
public static Class<?> getClass(String className)
throws ClassNotFoundException {
throws ClassNotFoundException {
Class<?> c;
if ((c = primitiveMap.get(className)) != null)
if ((c = primitiveMap.get(className)) != null) {
return c;
}
return Class.forName(className);
}
@ -155,7 +152,9 @@ public class Utils {
* structure, i.e. a data structure jconsole can render as an array.
*/
public static boolean canBeRenderedAsArray(Object elem) {
if (isSupportedArray(elem)) return true;
if (isSupportedArray(elem)) {
return true;
}
if (elem instanceof Collection) {
Collection<?> c = (Collection<?>) elem;
if (c.isEmpty()) {
@ -168,7 +167,7 @@ public class Utils {
// - Collections of other Java types are handled as arrays
//
return !isUniformCollection(c, CompositeData.class) &&
!isUniformCollection(c, TabularData.class);
!isUniformCollection(c, TabularData.class);
}
}
if (elem instanceof Map) {
@ -239,7 +238,9 @@ public class Utils {
*/
public static String getReadableClassName(String name) {
String className = getArrayClassName(name);
if (className == null) return name;
if (className == null) {
return name;
}
int index = name.lastIndexOf("[");
StringBuilder brackets = new StringBuilder(className);
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.
*/
public static Object newStringConstructor(String type, String param)
throws Exception {
throws Exception {
Constructor c = Utils.getClass(type).getConstructor(String.class);
try {
return c.newInstance(param);
@ -300,7 +301,7 @@ public class Utils {
* Try to convert a string value into a numerical value.
*/
private static Number createNumberFromStringValue(String value)
throws NumberFormatException {
throws NumberFormatException {
final String suffix = value.substring(value.length() - 1);
if ("L".equalsIgnoreCase(suffix)) {
return Long.valueOf(value.substring(0, value.length() - 1));
@ -314,17 +315,17 @@ public class Utils {
try {
return Integer.valueOf(value);
} catch (NumberFormatException e) {
// OK: Ignore exception...
// OK: Ignore exception...
}
try {
return Long.valueOf(value);
} catch (NumberFormatException e1) {
// OK: Ignore exception...
// OK: Ignore exception...
}
try {
return Double.valueOf(value);
} catch (NumberFormatException e2) {
// OK: Ignore exception...
// OK: Ignore exception...
}
throw new NumberFormatException("Cannot convert string value '" +
value + "' into a numerical value");
@ -337,7 +338,7 @@ public class Utils {
* will return an Integer object initialized to 10.
*/
public static Object createObjectFromString(String type, String value)
throws Exception {
throws Exception {
Object result;
if (primitiveToWrapper.containsKey(type)) {
if (type.equals(Character.TYPE.getName())) {
@ -367,7 +368,7 @@ public class Utils {
* into a useful object array for passing into a parameter array.
*/
public static Object[] getParameters(XTextField[] inputs, String[] params)
throws Exception {
throws Exception {
Object result[] = new Object[inputs.length];
Object userInput;
for (int i = 0; i < inputs.length; i++) {
@ -388,12 +389,17 @@ public class Utils {
* If the exception is wrapped, unwrap it.
*/
public static Throwable getActualException(Throwable e) {
if (e instanceof ExecutionException) {
e = e.getCause();
}
if (e instanceof MBeanException ||
e instanceof RuntimeMBeanException ||
e instanceof RuntimeOperationsException ||
e instanceof ReflectionException) {
Throwable t = e.getCause();
if (t != null) return t;
if (t != null) {
return t;
}
}
return e;
}
@ -401,6 +407,7 @@ public class Utils {
@SuppressWarnings("serial")
public static class ReadOnlyTableCellEditor
extends DefaultCellEditor {
public ReadOnlyTableCellEditor(JTextField tf) {
super(tf);
tf.addFocusListener(new Utils.EditFocusAdapter(this));
@ -409,20 +416,25 @@ public class Utils {
}
public static class EditFocusAdapter extends FocusAdapter {
private CellEditor editor;
public EditFocusAdapter(CellEditor editor) {
this.editor = editor;
}
@Override
public void focusLost(FocusEvent e) {
editor.stopCellEditing();
}
};
}
public static class CopyKeyAdapter extends KeyAdapter {
private static final String defaultEditorKitCopyActionName =
DefaultEditorKit.copyAction;
private static final String transferHandlerCopyActionName =
(String) TransferHandler.getCopyAction().getValue(Action.NAME);
@Override
public void keyPressed(KeyEvent e) {
// Accept "copy" key strokes
KeyStroke ks = KeyStroke.getKeyStroke(
@ -441,6 +453,8 @@ public class Utils {
e.consume();
}
}
@Override
public void keyTyped(KeyEvent e) {
e.consume();
}

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.tools.jconsole.inspector;
import javax.swing.JTable;
@ -108,6 +109,7 @@ public class XDataViewer {
public Component createOperationViewer(Object value,
XMBean mbean) {
if(value instanceof Number) return null;
if(value instanceof Component) return (Component) value;
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.
*
* 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 javax.management.*;
import javax.swing.Icon;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.MBeansTab;
public class XMBean extends Object {
private ObjectName objectName;
public class XMBean {
private final MBeansTab mbeansTab;
private final ObjectName objectName;
private Icon icon;
private String text;
private boolean broadcaster;
private Boolean broadcaster;
private final Object broadcasterLock = new Object();
private MBeanInfo mbeanInfo;
private MBeansTab mbeansTab;
private final Object mbeanInfoLock = new Object();
public XMBean(ObjectName objectName, MBeansTab mbeansTab)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException, IOException {
public XMBean(ObjectName objectName, 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)) {
icon = IconManager.MBEANSERVERDELEGATE;
} else {
icon = IconManager.MBEAN;
}
this.broadcaster = isBroadcaster(objectName);
this.mbeanInfo = getMBeanInfo(objectName);
}
MBeanServerConnection getMBeanServerConnection() {
return mbeansTab.getMBeanServerConnection();
}
public boolean isBroadcaster() {
return broadcaster;
}
private boolean isBroadcaster(ObjectName name) {
try {
return getMBeanServerConnection().isInstanceOf(
name, "javax.management.NotificationBroadcaster");
} catch (Exception e) {
System.out.println("Error calling isBroadcaster: " +
e.getMessage());
public Boolean isBroadcaster() {
synchronized (broadcasterLock) {
if (broadcaster == null) {
try {
broadcaster = getMBeanServerConnection().isInstanceOf(
getObjectName(),
"javax.management.NotificationBroadcaster");
} catch (Exception e) {
if (JConsole.isDebug()) {
System.err.println("Couldn't check if MBean [" +
objectName + "] is a notification broadcaster");
e.printStackTrace();
}
return false;
}
}
return broadcaster;
}
return false;
}
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[])
throws Exception {
throws Exception {
Object result = getMBeanServerConnection().invoke(
getObjectName(), operationName, params, sig);
return result;
}
public void setAttribute(Attribute attribute)
throws AttributeNotFoundException, InstanceNotFoundException,
throws AttributeNotFoundException, InstanceNotFoundException,
InvalidAttributeValueException, MBeanException,
ReflectionException, IOException {
getMBeanServerConnection().setAttribute(getObjectName(), attribute);
}
public Object getAttribute(String attributeName)
throws AttributeNotFoundException, InstanceNotFoundException,
throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException {
return getMBeanServerConnection().getAttribute(
getObjectName(), attributeName);
}
public AttributeList getAttributes(String attributeNames[])
throws AttributeNotFoundException, InstanceNotFoundException,
throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException {
return getMBeanServerConnection().getAttributes(
getObjectName(), attributeNames);
}
public AttributeList getAttributes(MBeanAttributeInfo attributeNames[])
throws AttributeNotFoundException, InstanceNotFoundException,
throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException {
String attributeString[] = new String[attributeNames.length];
for (int i = 0; i < attributeNames.length; i++) {
@ -119,32 +128,34 @@ public class XMBean extends Object {
return objectName;
}
private void setObjectName(ObjectName objectName) {
this.objectName = objectName;
// generate a readable name now
String name = getObjectName().getKeyProperty("name");
if (name == null)
setText(getObjectName().getDomain());
else
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());
public MBeanInfo getMBeanInfo() throws InstanceNotFoundException,
IntrospectionException, ReflectionException, IOException {
synchronized (mbeanInfoLock) {
if (mbeanInfo == null) {
mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName);
}
return mbeanInfo;
}
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() {
@ -163,6 +174,7 @@ public class XMBean extends Object {
this.icon = icon;
}
@Override
public String toString() {
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.
*
* 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.event.*;
import javax.swing.table.*;
import javax.swing.tree.*;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.Resources;
import sun.tools.jconsole.inspector.XNodeInfo.Type;
import static sun.tools.jconsole.Utilities.*;
@ -46,21 +43,20 @@ import static sun.tools.jconsole.Utilities.*;
public class XMBeanInfo extends JPanel {
private static final Color lightYellow = new Color(255, 255, 128);
private final int NAME_COLUMN = 0;
private final int VALUE_COLUMN = 1;
private final String[] columnNames = {
Resources.getText("Name"),
Resources.getText("Value")
};
private JTable infoTable = new JTable();
private JTable descTable = new JTable();
private JPanel infoBorderPanel = new JPanel(new BorderLayout());
private JPanel descBorderPanel = new JPanel(new BorderLayout());
private static class ReadOnlyDefaultTableModel extends DefaultTableModel {
@Override
public void setValueAt(Object value, int row, int col) {
}
}
@ -73,17 +69,18 @@ public class XMBeanInfo extends JPanel {
this.tableRowDividerText = tableRowDividerText;
}
@Override
public String toString() {
return tableRowDividerText;
}
}
private static MBeanInfoTableCellRenderer renderer =
new MBeanInfoTableCellRenderer();
private static class MBeanInfoTableCellRenderer
extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
@ -92,22 +89,24 @@ public class XMBeanInfo extends JPanel {
if (value instanceof TableRowDivider) {
JLabel label = new JLabel(value.toString());
label.setBackground(ensureContrast(lightYellow,
label.getForeground()));
label.getForeground()));
label.setOpaque(true);
return label;
}
return comp;
}
}
private static TableCellEditor editor =
new MBeanInfoTableCellEditor(new JTextField());
private static class MBeanInfoTableCellEditor
extends Utils.ReadOnlyTableCellEditor {
public MBeanInfoTableCellEditor(JTextField tf) {
super(tf);
}
@Override
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected,
int row, int column) {
@ -116,7 +115,7 @@ public class XMBeanInfo extends JPanel {
if (value instanceof TableRowDivider) {
JLabel label = new JLabel(value.toString());
label.setBackground(ensureContrast(lightYellow,
label.getForeground()));
label.getForeground()));
label.setOpaque(true);
return label;
}
@ -172,6 +171,7 @@ public class XMBeanInfo extends JPanel {
add(descBorderPanel);
}
// Call on EDT
public void emptyInfoTable() {
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
while (tableModel.getRowCount() > 0) {
@ -179,6 +179,7 @@ public class XMBeanInfo extends JPanel {
}
}
// Call on EDT
public void emptyDescTable() {
DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
while (tableModel.getRowCount() > 0) {
@ -186,6 +187,7 @@ public class XMBeanInfo extends JPanel {
}
}
// Call on EDT
private void addDescriptor(Descriptor desc, String text) {
if (desc != null && desc.getFieldNames().length > 0) {
DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
@ -223,6 +225,7 @@ public class XMBeanInfo extends JPanel {
}
}
// Call on EDT
public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {
emptyInfoTable();
emptyDescTable();
@ -263,6 +266,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel));
}
// Call on EDT
public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {
emptyInfoTable();
emptyDescTable();
@ -296,6 +300,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel));
}
// Call on EDT
public void addMBeanOperationInfo(MBeanOperationInfo mboi) {
emptyInfoTable();
emptyDescTable();
@ -343,6 +348,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel));
}
// Call on EDT
public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {
emptyInfoTable();
emptyDescTable();
@ -367,6 +373,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel));
}
// Call on EDT
private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
Object rowData[] = new Object[2];
@ -383,6 +390,7 @@ public class XMBeanInfo extends JPanel {
tableModel.newDataAvailable(new TableModelEvent(tableModel));
}
// Call on EDT
private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {
DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
Object rowData[] = new Object[2];
@ -401,91 +409,4 @@ public class XMBeanInfo extends JPanel {
addDescriptor(mbpi.getDescriptor(), text);
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.table.*;
import javax.swing.tree.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Font;
import java.text.SimpleDateFormat;
import java.awt.FlowLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.*;
import java.awt.Insets;
import java.awt.Dimension;
import java.util.*;
import java.io.*;
@ -49,45 +45,44 @@ import javax.management.*;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.Resources;
@SuppressWarnings("serial")
public class XMBeanNotifications extends JTable implements NotificationListener {
private final static String[] columnNames = {
private final static String[] columnNames = {
Resources.getText("TimeStamp"),
Resources.getText("Type"),
Resources.getText("UserData"),
Resources.getText("SeqNum"),
Resources.getText("Message"),
Resources.getText("Event"),
Resources.getText("Source")};
Resources.getText("Source")
};
private HashMap<ObjectName, XMBeanNotificationsListener> listeners =
new HashMap<ObjectName, XMBeanNotificationsListener>();
private boolean subscribed;
new HashMap<ObjectName, XMBeanNotificationsListener>();
private volatile boolean subscribed;
private XMBeanNotificationsListener currentListener;
public final static String NOTIFICATION_RECEIVED_EVENT =
"jconsole.xnotification.received";
"jconsole.xnotification.received";
private List<NotificationListener> notificationListenersList;
private boolean enabled;
private Font normalFont, boldFont;
private volatile boolean enabled;
private Font normalFont, boldFont;
private int rowMinHeight = -1;
private TableCellEditor userDataEditor = new UserDataCellEditor();
private NotifMouseListener mouseListener = new NotifMouseListener();
private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS");
private static TableCellEditor editor =
new Utils.ReadOnlyTableCellEditor(new JTextField());
public XMBeanNotifications() {
super(new TableSorter(columnNames,0));
super(new TableSorter(columnNames, 0));
setColumnSelectionAllowed(false);
setRowSelectionAllowed(false);
getTableHeader().setReorderingAllowed(false);
ArrayList<NotificationListener> l =
new ArrayList<NotificationListener>(1);
new ArrayList<NotificationListener>(1);
notificationListenersList = Collections.synchronizedList(l);
addMouseListener(mouseListener);
@ -103,20 +98,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener
addKeyListener(new Utils.CopyKeyAdapter());
}
// Call on EDT
public void cancelCellEditing() {
TableCellEditor editor = getCellEditor();
if (editor != null) {
editor.cancelCellEditing();
TableCellEditor tce = getCellEditor();
if (tce != null) {
tce.cancelCellEditing();
}
}
// Call on EDT
public void stopCellEditing() {
TableCellEditor editor = getCellEditor();
if (editor != null) {
editor.stopCellEditing();
TableCellEditor tce = getCellEditor();
if (tce != null) {
tce.stopCellEditing();
}
}
// Call on EDT
@Override
public boolean isCellEditable(int row, int col) {
UserDataCell cell = getUserDataCell(row, col);
if (cell != null) {
@ -125,16 +124,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return true;
}
// Call on EDT
@Override
public void setValueAt(Object value, int row, int column) {
}
public synchronized Component prepareRenderer(TableCellRenderer renderer,
int row, int column) {
// Call on EDT
@Override
public synchronized Component prepareRenderer(
TableCellRenderer renderer, int row, int column) {
//In case we have a repaint thread that is in the process of
//repainting an obsolete table, just ignore the call.
//It can happen when MBean selection is switched at a very quick rate
if(row >= getRowCount())
if (row >= getRowCount()) {
return null;
}
Component comp = super.prepareRenderer(renderer, row, column);
@ -146,9 +150,10 @@ public class XMBeanNotifications extends JTable implements NotificationListener
if (column == 2 && cell != null) {
comp.setFont(boldFont);
int size = cell.getHeight();
if(size > 0) {
if(getRowHeight(row) != size)
if (size > 0) {
if (getRowHeight(row) != size) {
setRowHeight(row, size);
}
}
} else {
comp.setFont(normalFont);
@ -157,34 +162,35 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return comp;
}
public synchronized TableCellRenderer getCellRenderer(int row,
int column) {
// Call on EDT
@Override
public synchronized TableCellRenderer getCellRenderer(int row, int column) {
//In case we have a repaint thread that is in the process of
//repainting an obsolete table, just ignore the call.
//It can happen when MBean selection is switched at a very quick rate
if(row >= getRowCount())
if (row >= getRowCount()) {
return null;
}
DefaultTableCellRenderer renderer;
String toolTip = null;
UserDataCell cell = getUserDataCell(row, column);
if(cell != null && cell.isInited()) {
if (cell != null && cell.isInited()) {
renderer = (DefaultTableCellRenderer) cell.getRenderer();
}
else {
renderer = (DefaultTableCellRenderer)
super.getCellRenderer(row,
column);
} else {
renderer =
(DefaultTableCellRenderer) super.getCellRenderer(row, column);
}
if(cell != null)
toolTip = Resources.getText("Double click to expand/collapse")+". "
+ cell.toString();
else {
if (cell != null) {
toolTip = Resources.getText("Double click to expand/collapse") +
". " + cell.toString();
} else {
Object val =
((DefaultTableModel) getModel()).getValueAt(row,column);
if(val != null)
((DefaultTableModel) getModel()).getValueAt(row, column);
if (val != null) {
toolTip = val.toString();
}
}
renderer.setToolTipText(toolTip);
@ -192,9 +198,12 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return renderer;
}
// Call on EDT
private UserDataCell getUserDataCell(int row, int column) {
Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column);
if(obj instanceof UserDataCell) return (UserDataCell) obj;
Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column);
if (obj instanceof UserDataCell) {
return (UserDataCell) obj;
}
return null;
}
@ -204,19 +213,22 @@ public class XMBeanNotifications extends JTable implements NotificationListener
public long getReceivedNotifications(XMBean mbean) {
XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName());
if(listener == null) return 0;
else
listeners.get(mbean.getObjectName());
if (listener == null) {
return 0;
} else {
return listener.getReceivedNotifications();
}
}
public synchronized boolean clearCurrentNotifications() {
emptyTable();
if(currentListener != null) {
if (currentListener != null) {
currentListener.clear();
return true;
} else
} else {
return false;
}
}
public synchronized boolean unregisterListener(DefaultMutableTreeNode node) {
@ -225,29 +237,25 @@ public class XMBeanNotifications extends JTable implements NotificationListener
}
public synchronized void registerListener(DefaultMutableTreeNode node)
throws InstanceNotFoundException, IOException {
throws InstanceNotFoundException, IOException {
XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
if(!subscribed) {
if (!subscribed) {
try {
mbean.getMBeanServerConnection().
addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"),
this,
null,
null);
mbean.getMBeanServerConnection().addNotificationListener(
MBeanServerDelegate.DELEGATE_NAME, this, null, null);
subscribed = true;
}catch(Exception e) {
System.out.println("Error adding listener for delegate :"+
e.getMessage());
} catch (Exception e) {
if (JConsole.isDebug()) {
System.err.println("Error adding listener for delegate:");
e.printStackTrace();
}
}
}
XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName());
listeners.get(mbean.getObjectName());
if (listener == null) {
listener = new XMBeanNotificationsListener(this,
mbean,
node,
columnNames);
listener = new XMBeanNotificationsListener(
this, mbean, node, columnNames);
listeners.put(mbean.getObjectName(), listener);
} else {
if (!listener.isRegistered()) {
@ -259,19 +267,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener
currentListener = listener;
}
public synchronized void handleNotification(Notification notif,
Object handback) {
public synchronized void handleNotification(
Notification notif, Object handback) {
try {
if (notif instanceof MBeanServerNotification) {
ObjectName mbean =
((MBeanServerNotification)notif).getMBeanName();
if (notif.getType().indexOf("JMX.mbean.unregistered")>=0){
((MBeanServerNotification) notif).getMBeanName();
if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) {
unregister(mbean);
}
}
} catch(Exception e) {
System.out.println("Error unregistering notification:"+
e.getMessage());
} catch (Exception e) {
if (JConsole.isDebug()) {
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) {
XMBeanNotificationsListener listener = listeners.get(mbean);
if(listener != null && listener.isRegistered()) {
if (listener != null && listener.isRegistered()) {
listener.unregister();
return true;
} else
} else {
return false;
}
}
public void addNotificationsListener(NotificationListener nl) {
notificationListenersList.add(nl);
notificationListenersList.add(nl);
}
public void removeNotificationsListener(NotificationListener nl) {
notificationListenersList.remove(nl);
}
void fireNotificationReceived(XMBeanNotificationsListener listener,
XMBean mbean,
DefaultMutableTreeNode node,
Object[] rowData,
long received) {
if(enabled) {
// Call on EDT
void fireNotificationReceived(
XMBeanNotificationsListener listener, XMBean mbean,
DefaultMutableTreeNode node, Object[] rowData, long received) {
if (enabled) {
DefaultTableModel tableModel = (DefaultTableModel) getModel();
if(listener == currentListener) {
//tableModel.addRow(rowData);
if (listener == currentListener) {
tableModel.insertRow(0, rowData);
//tableModel.newDataAvailable(new TableModelEvent(tableModel));
repaint();
}
}
Notification notif = new Notification(NOTIFICATION_RECEIVED_EVENT,
this,
0);
notif.setUserData(new Long(received));
for(NotificationListener nl : notificationListenersList)
nl.handleNotification(notif,node);
Notification notif =
new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0);
notif.setUserData(received);
for (NotificationListener nl : notificationListenersList) {
nl.handleNotification(notif, node);
}
}
// Call on EDT
private void updateModel(List<Object[]> data) {
emptyTable();
DefaultTableModel tableModel = (DefaultTableModel) getModel();
for(Object[] rowData : data)
for (Object[] rowData : data) {
tableModel.addRow(rowData);
}
}
public synchronized boolean isListenerRegistered(XMBean mbean) {
XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName());
if(listener == null) return false;
listeners.get(mbean.getObjectName());
if (listener == null) {
return false;
}
return listener.isRegistered();
}
// Call on EDT
public synchronized void loadNotifications(XMBean mbean) {
XMBeanNotificationsListener listener =
listeners.get(mbean.getObjectName());
listeners.get(mbean.getObjectName());
emptyTable();
if(listener != null ) {
if (listener != null) {
enabled = true;
List<Object[]> data = listener.getData();
updateModel(data);
currentListener = listener;
validate();
repaint();
} else
} else {
enabled = false;
}
}
// Call on EDT
private void setColumnEditors() {
TableColumnModel tcm = getColumnModel();
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() {
return true;
}
// Call on EDT
public synchronized void emptyTable() {
DefaultTableModel model = (DefaultTableModel)getModel();
DefaultTableModel model = (DefaultTableModel) getModel();
//invalidate();
while (model.getRowCount()>0)
while (model.getRowCount() > 0) {
model.removeRow(0);
}
validate();
}
synchronized void updateUserDataCell(int row,
int col) {
// Call on EDT
synchronized void updateUserDataCell(int row, int col) {
Object obj = getModel().getValueAt(row, 2);
if(obj instanceof UserDataCell) {
if (obj instanceof UserDataCell) {
UserDataCell cell = (UserDataCell) obj;
if(!cell.isInited()) {
if(rowMinHeight == -1)
if (!cell.isInited()) {
if (rowMinHeight == -1) {
rowMinHeight = getRowHeight(row);
cell.init(super.getCellRenderer(row, col),
rowMinHeight);
}
cell.init(super.getCellRenderer(row, col), rowMinHeight);
}
cell.switchState();
setRowHeight(row,
cell.getHeight());
setRowHeight(row, cell.getHeight());
if(!cell.isMaximized()) {
if (!cell.isMaximized()) {
cancelCellEditing();
//Back to simple editor.
editCellAt(row,
2);
editCellAt(row, 2);
}
invalidate();
@ -406,7 +418,9 @@ public class XMBeanNotifications extends JTable implements NotificationListener
}
class UserDataCellRenderer extends DefaultTableCellRenderer {
Component comp;
UserDataCellRenderer(Component comp) {
this.comp = comp;
Dimension d = comp.getPreferredSize();
@ -415,56 +429,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener
}
}
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
return comp;
}
public Component getComponent() {
return comp;
}
}
class UserDataCell {
TableCellRenderer minRenderer;
UserDataCellRenderer maxRenderer;
int minHeight;
boolean minimized = true;
boolean init = false;
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 ||
userData instanceof TabularData)
@Override
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.toString();
}
}
boolean isInited() {
return init;
}
void init(TableCellRenderer minRenderer,
int minHeight) {
void init(TableCellRenderer minRenderer, int minHeight) {
this.minRenderer = minRenderer;
this.minHeight = minHeight;
init = true;
@ -473,9 +493,11 @@ public class XMBeanNotifications extends JTable implements NotificationListener
void switchState() {
minimized = !minimized;
}
boolean isMaximized() {
return !minimized;
}
void minimize() {
minimized = true;
}
@ -485,30 +507,39 @@ public class XMBeanNotifications extends JTable implements NotificationListener
}
int getHeight() {
if(minimized) return minHeight;
else
if (minimized) {
return minHeight;
} else {
return (int) maxRenderer.getComponent().
getPreferredSize().getHeight() ;
getPreferredSize().getHeight();
}
}
TableCellRenderer getRenderer() {
if(minimized) return minRenderer;
else return maxRenderer;
if (minimized) {
return minRenderer;
} else {
return maxRenderer;
}
}
}
class NotifMouseListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
if(e.getClickCount() >= 2) {
if (e.getButton() == MouseEvent.BUTTON1) {
if (e.getClickCount() >= 2) {
int row = XMBeanNotifications.this.getSelectedRow();
int col = XMBeanNotifications.this.getSelectedColumn();
if(col != 2) return;
if(col == -1 || row == -1) return;
if (col != 2) {
return;
}
if (col == -1 || row == -1) {
return;
}
XMBeanNotifications.this.updateUserDataCell(row,
col);
XMBeanNotifications.this.updateUserDataCell(row, col);
}
}
}
@ -516,20 +547,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener
class UserDataCellEditor extends XTextFieldEditor {
// implements javax.swing.table.TableCellEditor
public Component getTableCellEditorComponent(JTable table,
Object value,
boolean isSelected,
int row,
int column) {
@Override
public Component getTableCellEditorComponent(
JTable table,
Object value,
boolean isSelected,
int row,
int column) {
Object val = value;
if(column == 2) {
Object obj = getModel().getValueAt(row,
column);
if(obj instanceof UserDataCell) {
if (column == 2) {
Object obj = getModel().getValueAt(row, column);
if (obj instanceof UserDataCell) {
UserDataCell cell = (UserDataCell) obj;
if(cell.getRenderer() instanceof UserDataCellRenderer) {
if (cell.getRenderer() instanceof UserDataCellRenderer) {
UserDataCellRenderer zr =
(UserDataCellRenderer) cell.getRenderer();
(UserDataCellRenderer) cell.getRenderer();
return zr.getComponent();
}
} else {
@ -539,12 +571,14 @@ public class XMBeanNotifications extends JTable implements NotificationListener
return comp;
}
}
return super.getTableCellEditorComponent(table,
val,
isSelected,
row,
column);
return super.getTableCellEditorComponent(
table,
val,
isSelected,
row,
column);
}
@Override
public boolean stopCellEditing() {
int editingRow = getEditingRow();
@ -554,7 +588,7 @@ public class XMBeanNotifications extends JTable implements NotificationListener
if (obj instanceof UserDataCell) {
UserDataCell cell = (UserDataCell) obj;
if (cell.isMaximized()) {
this.cancelCellEditing();
cancelCellEditing();
return true;
}
}
@ -564,17 +598,20 @@ public class XMBeanNotifications extends JTable implements NotificationListener
}
class XMBeanNotificationsListener implements NotificationListener {
private String[] columnNames;
private XMBean xmbean;
private DefaultMutableTreeNode node;
private long received;
private volatile long received;
private XMBeanNotifications notifications;
private boolean unregistered;
private volatile boolean unregistered;
private ArrayList<Object[]> data = new ArrayList<Object[]>();
public XMBeanNotificationsListener(XMBeanNotifications notifications,
XMBean xmbean,
DefaultMutableTreeNode node,
String[] columnNames) {
public XMBeanNotificationsListener(
XMBeanNotifications notifications,
XMBean xmbean,
DefaultMutableTreeNode node,
String[] columnNames) {
this.notifications = notifications;
this.xmbean = xmbean;
this.node = node;
@ -591,22 +628,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener
received = 0;
}
public boolean isRegistered() {
public synchronized boolean isRegistered() {
return !unregistered;
}
public synchronized void unregister() {
try {
xmbean.getMBeanServerConnection().
removeNotificationListener(xmbean.getObjectName(),this,null,null);
}catch(Exception e) {
System.out.println("Error removing listener :"+
e.getMessage());
xmbean.getMBeanServerConnection().removeNotificationListener(
xmbean.getObjectName(), this, null, null);
} catch (Exception e) {
if (JConsole.isDebug()) {
System.err.println("Error removing listener:");
e.printStackTrace();
}
}
unregistered = true;
}
public long getReceivedNotifications() {
public synchronized long getReceivedNotifications() {
return received;
}
@ -614,52 +653,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener
clear();
this.node = node;
try {
xmbean.getMBeanServerConnection().
addNotificationListener(xmbean.getObjectName(),this,null,null);
xmbean.getMBeanServerConnection().addNotificationListener(
xmbean.getObjectName(), this, null, null);
unregistered = false;
}catch(Exception e) {
System.out.println("Error adding listener :"+
e.getMessage());
} catch (Exception e) {
if (JConsole.isDebug()) {
System.err.println("Error adding listener:");
e.printStackTrace();
}
}
}
public synchronized void handleNotification(Notification e,
Object handback) {
try {
if(unregistered) return;
Date receivedDate = new Date(e.getTimeStamp());
String time = timeFormater.format(receivedDate);
public synchronized void handleNotification(
final Notification n, Object hb) {
EventQueue.invokeLater(new Runnable() {
Object userData = e.getUserData();
Component comp = null;
UserDataCell cell = null;
if((comp = XDataViewer.createNotificationViewer(userData))
!= null) {
XDataViewer.registerForMouseEvent(comp, mouseListener);
cell = new UserDataCell(userData, comp);
public void run() {
synchronized (XMBeanNotificationsListener.this) {
try {
if (unregistered) {
return;
}
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
* have any questions.
*/
package sun.tools.jconsole.inspector;
import javax.management.*;

View File

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

View File

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

View File

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

View File

@ -22,6 +22,7 @@
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.tools.jconsole.inspector;
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.
*
* 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.event.*;
import java.io.*;
import java.util.Enumeration;
import javax.management.*;
import javax.swing.*;
import javax.swing.border.*;
@ -45,31 +44,22 @@ public class XSheet extends JPanel
private JPanel mainPanel;
private JPanel southPanel;
// Node being currently displayed
private DefaultMutableTreeNode node;
private volatile DefaultMutableTreeNode currentNode;
// MBean being currently displayed
private XMBean mbean;
private volatile XMBean mbean;
// XMBeanAttributes container
private XMBeanAttributes mbeanAttributes;
// XMBeanOperations container
private XMBeanOperations mbeanOperations;
// XMBeanNotifications container
private XMBeanNotifications mbeanNotifications;
// XMBeanInfo container
private XMBeanInfo mbeanInfo;
// Refresh JButton (mbean attributes case)
private JButton refreshButton;
// Subscribe/Unsubscribe/Clear JButton (mbean notifications case)
private JButton clearButton, subscribeButton, unsubscribeButton;
private JButton clearButton, subscribeButton, unsubscribeButton;
// Reference to MBeans tab
private MBeansTab mbeansTab;
@ -86,6 +76,7 @@ public class XSheet extends JPanel
private void setupScreen() {
setLayout(new BorderLayout());
setBorder(BorderFactory.createLineBorder(Color.GRAY));
// add main panel to XSheet
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
@ -129,17 +120,32 @@ public class XSheet extends JPanel
mbeanInfo = new XMBeanInfo();
}
public boolean isMBeanNode(DefaultMutableTreeNode node) {
XNodeInfo uo = (XNodeInfo) node.getUserObject();
return uo.getType().equals(Type.MBEAN);
private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {
return (cn == n);
}
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();
displayEmptyNode();
if (node == null) {
displayEmptyNode();
return;
}
currentNode = node;
Object userObject = node.getUserObject();
if (userObject instanceof XNodeInfo) {
XNodeInfo uo = (XNodeInfo) userObject;
@ -173,27 +179,28 @@ public class XSheet extends JPanel
}
}
// Call on EDT
private void displayMBeanNode(final DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.MBEAN)) {
return;
}
mbeansTab.workerAdd(new Runnable() {
public void run() {
mbean = (XMBean) uo.getData();
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 {
XSheet.this.node = node;
XSheet.this.mbean = (XMBean) uo.getData();
mbeanInfo.addMBeanInfo(mbean, mbean.getMBeanInfo());
} 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() {
MBeanInfo mbi = get();
if (mbi != null) {
if (!isSelectedNode(node, currentNode)) {
return;
}
mbeanInfo.addMBeanInfo(mbean, mbi);
invalidate();
mainPanel.removeAll();
mainPanel.add(mbeanInfo, BorderLayout.CENTER);
@ -202,9 +209,19 @@ public class XSheet extends JPanel
validate();
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
@ -213,90 +230,90 @@ public class XSheet extends JPanel
final XMBeanInfo mbi = mbeanInfo;
switch (uo.getType()) {
case ATTRIBUTE:
mbeansTab.workerAdd(new Runnable() {
public void run() {
Object attrData = uo.getData();
XSheet.this.mbean = (XMBean) ((Object[]) attrData)[0];
final MBeanAttributeInfo mbai =
(MBeanAttributeInfo) ((Object[]) attrData)[1];
final XMBeanAttributes mba = mbeanAttributes;
try {
mba.loadAttributes(mbean, new MBeanInfo(
null, null, new MBeanAttributeInfo[] {mbai},
null, null, null));
} catch (Exception e) {
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();
SwingWorker<MBeanAttributeInfo, Void> sw =
new SwingWorker<MBeanAttributeInfo, Void>() {
@Override
public MBeanAttributeInfo doInBackground() {
Object attrData = uo.getData();
mbean = (XMBean) ((Object[]) attrData)[0];
MBeanAttributeInfo mbai =
(MBeanAttributeInfo) ((Object[]) attrData)[1];
mbeanAttributes.loadAttributes(mbean, new MBeanInfo(
null, null, new MBeanAttributeInfo[]{mbai},
null, null, null));
return mbai;
}
});
}
});
@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;
case OPERATION:
Object operData = uo.getData();
XSheet.this.mbean = (XMBean) ((Object[]) operData)[0];
mbean = (XMBean) ((Object[]) operData)[0];
MBeanOperationInfo mboi =
(MBeanOperationInfo) ((Object[]) operData)[1];
XMBeanOperations mbo = mbeanOperations;
try {
mbo.loadOperations(mbean, new MBeanInfo(null, null, 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;
}
mbeanOperations.loadOperations(mbean,
new MBeanInfo(null, null, null, null,
new MBeanOperationInfo[]{mboi}, null));
invalidate();
mainPanel.removeAll();
JPanel operationPanel = new JPanel(new BorderLayout());
JPanel operationBorderPanel = new JPanel(new BorderLayout());
operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Operation invocation")));
operationBorderPanel.add(new JScrollPane(mbo));
operationBorderPanel.add(new JScrollPane(mbeanOperations));
operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
mbi.addMBeanOperationInfo(mboi);
operationPanel.add(mbi, BorderLayout.CENTER);
@ -320,134 +337,134 @@ public class XSheet extends JPanel
}
}
// Call on EDT
private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.ATTRIBUTES)) {
return;
}
final XMBeanAttributes mba = mbeanAttributes;
mbeansTab.workerAdd(new Runnable() {
public void run() {
try {
XSheet.this.node = node;
XSheet.this.mbean = (XMBean) uo.getData();
mba.loadAttributes(mbean, mbean.getMBeanInfo());
} 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();
}
});
mbean = (XMBean) uo.getData();
SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
@Override
public Void doInBackground() throws InstanceNotFoundException,
IntrospectionException, ReflectionException, IOException {
mbeanAttributes.loadAttributes(mbean, mbean.getMBeanInfo());
return null;
}
});
@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) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.OPERATIONS)) {
return;
}
final XMBeanOperations mbo = mbeanOperations;
mbeansTab.workerAdd(new Runnable() {
public void run() {
mbean = (XMBean) uo.getData();
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 {
XSheet.this.node = node;
XSheet.this.mbean = (XMBean) uo.getData();
mbo.loadOperations(mbean, mbean.getMBeanInfo());
} 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() {
MBeanInfo mbi = get();
if (mbi != null) {
if (!isSelectedNode(node, currentNode)) {
return;
}
mbeanOperations.loadOperations(mbean, mbi);
invalidate();
mainPanel.removeAll();
JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Operation invocation")));
borderPanel.add(new JScrollPane(mbo));
borderPanel.add(new JScrollPane(mbeanOperations));
mainPanel.add(borderPanel, 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 " +
"operations for MBean [" +
mbean.getObjectName() + "]");
t.printStackTrace();
}
showErrorDialog(t.toString(),
Resources.getText("Problem displaying MBean"));
}
}
});
};
sw.execute();
}
private void displayMBeanNotificationsNode(
final DefaultMutableTreeNode node) {
// Call on EDT
private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) {
final XNodeInfo uo = (XNodeInfo) node.getUserObject();
if (!uo.getType().equals(Type.NOTIFICATIONS)) {
return;
}
final XMBeanNotifications mbn = mbeanNotifications;
mbeansTab.workerAdd(new Runnable() {
public void run() {
try {
XSheet.this.node = node;
XSheet.this.mbean = (XMBean) uo.getData();
mbn.loadNotifications(mbean);
updateNotifications();
} 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("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();
}
});
}
});
mbean = (XMBean) uo.getData();
mbeanNotifications.loadNotifications(mbean);
updateNotifications();
invalidate();
mainPanel.removeAll();
JPanel borderPanel = new JPanel(new BorderLayout());
borderPanel.setBorder(BorderFactory.createTitledBorder(
Resources.getText("Notification buffer")));
borderPanel.add(new JScrollPane(mbeanNotifications));
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
@ -462,21 +479,60 @@ public class XSheet extends JPanel
/**
* Subscribe button action.
*/
private void registerListener() throws InstanceNotFoundException,
IOException {
mbeanNotifications.registerListener(node);
updateNotifications();
validate();
private void registerListener() {
new SwingWorker<Void, Void>() {
@Override
public Void doInBackground()
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.
*/
private void unregisterListener() {
if (mbeanNotifications.unregisterListener(node)) {
clearNotifications();
validate();
}
new SwingWorker<Boolean, Void>() {
@Override
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();
}
// Call on EDT
private void updateNotifications() {
if (mbean.isBroadcaster()) {
if (mbeanNotifications.isListenerRegistered(mbean)) {
long received =
mbeanNotifications.getReceivedNotifications(mbean);
updateReceivedNotifications(node, received, false);
} else {
clearNotifications();
}
if (mbeanNotifications.isListenerRegistered(mbean)) {
long received = mbeanNotifications.getReceivedNotifications(mbean);
updateReceivedNotifications(currentNode, received, false);
} else {
clearNotifications();
}
@ -503,11 +555,11 @@ public class XSheet extends JPanel
/**
* Update notification node label in MBean tree: "Notifications[received]".
*/
// Call on EDT
private void updateReceivedNotifications(
DefaultMutableTreeNode emitter, long received, boolean bold) {
String text = Resources.getText("Notifications") + "[" + received + "]";
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)
mbeansTab.getTree().getLastSelectedPathComponent();
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
if (bold && emitter != selectedNode) {
text = "<html><b>" + text + "</b></html>";
}
@ -517,41 +569,40 @@ public class XSheet extends JPanel
/**
* Update notification node label in MBean tree: "Notifications".
*/
// Call on EDT
private void clearNotifications() {
updateNotificationsNodeLabel(node,
updateNotificationsNodeLabel(currentNode,
Resources.getText("Notifications"));
}
/**
* Update notification node label in MBean tree: "Notifications[0]".
*/
// Call on EDT
private void clearNotifications0() {
updateNotificationsNodeLabel(node,
updateNotificationsNodeLabel(currentNode,
Resources.getText("Notifications") + "[0]");
}
/**
* Update the label of the supplied MBean tree node.
*/
// Call on EDT
private void updateNotificationsNodeLabel(
final DefaultMutableTreeNode node, final String label) {
EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized (mbeansTab.getTree()) {
invalidate();
XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
XNodeInfo newUserObject = new XNodeInfo(
oldUserObject.getType(), oldUserObject.getData(),
label, oldUserObject.getToolTipText());
node.setUserObject(newUserObject);
DefaultTreeModel model =
(DefaultTreeModel) mbeansTab.getTree().getModel();
model.nodeChanged(node);
validate();
repaint();
}
}
});
DefaultMutableTreeNode node, String label) {
synchronized (mbeansTab.getTree()) {
invalidate();
XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
XNodeInfo newUserObject = new XNodeInfo(
oldUserObject.getType(), oldUserObject.getData(),
label, oldUserObject.getToolTipText());
node.setUserObject(newUserObject);
DefaultTreeModel model =
(DefaultTreeModel) mbeansTab.getTree().getModel();
model.nodeChanged(node);
validate();
repaint();
}
}
/**
@ -577,6 +628,7 @@ public class XSheet extends JPanel
}
}
// Call on EDT
private void clear() {
mbeanAttributes.stopCellEditing();
mbeanAttributes.emptyTable();
@ -586,13 +638,14 @@ public class XSheet extends JPanel
mbeanNotifications.emptyTable();
mbeanNotifications.disableNotifications();
mbean = null;
node = null;
currentNode = null;
}
/**
* Notification listener: handles asynchronous reception
* of MBean operation results and MBean notifications.
*/
// Call on EDT
public void handleNotification(Notification e, Object handback) {
// Operation result
if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) {
@ -628,13 +681,12 @@ public class XSheet extends JPanel
message = comp;
}
}
EventQueue.invokeLater(new ThreadDialog(
new ThreadDialog(
(Component) e.getSource(),
message,
Resources.getText("Operation return value"),
JOptionPane.INFORMATION_MESSAGE));
}
// Got notification
JOptionPane.INFORMATION_MESSAGE).run();
} // Got notification
else if (e.getType().equals(
XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {
DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;
@ -646,16 +698,19 @@ public class XSheet extends JPanel
/**
* Action listener: handles actions in panel buttons
*/
// Call on EDT
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
JButton button = (JButton) e.getSource();
// Refresh button
if (button == refreshButton) {
mbeansTab.workerAdd(new Runnable() {
public void run() {
new SwingWorker<Void, Void>() {
@Override
public Void doInBackground() {
refreshAttributes();
return null;
}
});
}.execute();
return;
}
// Clear button
@ -665,38 +720,12 @@ public class XSheet extends JPanel
}
// Subscribe button
if (button == subscribeButton) {
mbeansTab.workerAdd(new Runnable() {
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));
}
}
});
registerListener();
return;
}
// Unsubscribe button
if (button == unsubscribeButton) {
mbeansTab.workerAdd(new Runnable() {
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));
}
}
});
unregisterListener();
return;
}
}

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff