提交 412459e2 编写于 作者: L lmalvent

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
上级 ab1229d1
/*
* 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();
}
} catch (IOException e) {
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;
}
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();
@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;
}
// 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 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 CONNECTING:
onConnecting();
break;
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 tabs 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
......
/*
* 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);
}
......
/*
* 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;
public MBeanInfo getMBeanInfo() throws InstanceNotFoundException,
IntrospectionException, ReflectionException, IOException {
synchronized (mbeanInfoLock) {
if (mbeanInfo == null) {
mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName);
}
return mbeanInfo;
}
}
private MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException, IOException {
return getMBeanServerConnection().getMBeanInfo(name);
@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());
}
public boolean equals(Object o) {
if (o instanceof XMBean) {
XMBean mbean = (XMBean) o;
return getObjectName().equals((mbean).getObjectName());
}
return false;
@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();
}
......
/*
* 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);
}
}
}
}
}
......@@ -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) {
!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();
}
} catch (Throwable t) {
t = Utils.getActualException(t);
if (JConsole.isDebug()) {
ex.printStackTrace();
t.printStackTrace();
}
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));
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.*;
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册