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:
parent
c88c71b755
commit
134f15a93f
@ -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 {
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.*;
|
||||
|
@ -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.*;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.*;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.*;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.*;
|
||||
|
@ -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.*;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user