src/share/classes/sun/tools/jconsole/inspector/XSheet.java

Print this page
rev 5340 : 7017818: NLS: JConsoleResources.java cannot be handled by translation team
Reviewed-by: duke


  39 import javax.management.MBeanInfo;
  40 import javax.management.InstanceNotFoundException;
  41 import javax.management.ReflectionException;
  42 import javax.management.MBeanAttributeInfo;
  43 import javax.management.MBeanOperationInfo;
  44 import javax.management.MBeanNotificationInfo;
  45 import javax.management.Notification;
  46 import javax.swing.BorderFactory;
  47 import javax.swing.JButton;
  48 import javax.swing.JOptionPane;
  49 import javax.swing.JPanel;
  50 import javax.swing.JScrollPane;
  51 import javax.swing.JTextArea;
  52 import javax.swing.SwingWorker;
  53 import javax.swing.border.LineBorder;
  54 import javax.swing.tree.DefaultMutableTreeNode;
  55 import javax.swing.tree.DefaultTreeModel;
  56 
  57 import sun.tools.jconsole.*;
  58 import sun.tools.jconsole.inspector.XNodeInfo.Type;
  59 
  60 import static sun.tools.jconsole.Resources.*;
  61 
  62 @SuppressWarnings("serial")
  63 public class XSheet extends JPanel
  64         implements ActionListener, NotificationListener {
  65 
  66     private JPanel mainPanel;
  67     private JPanel southPanel;
  68     // Node being currently displayed
  69     private volatile DefaultMutableTreeNode currentNode;
  70     // MBean being currently displayed
  71     private volatile XMBean mbean;
  72     // XMBeanAttributes container
  73     private XMBeanAttributes mbeanAttributes;
  74     // XMBeanOperations container
  75     private XMBeanOperations mbeanOperations;
  76     // XMBeanNotifications container
  77     private XMBeanNotifications mbeanNotifications;
  78     // XMBeanInfo container
  79     private XMBeanInfo mbeanInfo;
  80     // Refresh JButton (mbean attributes case)


  89         setupScreen();
  90     }
  91 
  92     public void dispose() {
  93         clear();
  94         XDataViewer.dispose(mbeansTab);
  95         mbeanNotifications.dispose();
  96     }
  97 
  98     private void setupScreen() {
  99         setLayout(new BorderLayout());
 100         setBorder(BorderFactory.createLineBorder(Color.GRAY));
 101         // add main panel to XSheet
 102         mainPanel = new JPanel();
 103         mainPanel.setLayout(new BorderLayout());
 104         add(mainPanel, BorderLayout.CENTER);
 105         // add south panel to XSheet
 106         southPanel = new JPanel();
 107         add(southPanel, BorderLayout.SOUTH);
 108         // create the refresh button
 109         String refreshButtonKey = "MBeansTab.refreshAttributesButton";
 110         refreshButton = new JButton(getText(refreshButtonKey));
 111         refreshButton.setMnemonic(getMnemonicInt(refreshButtonKey));
 112         refreshButton.setToolTipText(getText(refreshButtonKey + ".toolTip"));
 113         refreshButton.addActionListener(this);
 114         // create the clear button
 115         String clearButtonKey = "MBeansTab.clearNotificationsButton";
 116         clearButton = new JButton(getText(clearButtonKey));
 117         clearButton.setMnemonic(getMnemonicInt(clearButtonKey));
 118         clearButton.setToolTipText(getText(clearButtonKey + ".toolTip"));
 119         clearButton.addActionListener(this);
 120         // create the subscribe button
 121         String subscribeButtonKey = "MBeansTab.subscribeNotificationsButton";
 122         subscribeButton = new JButton(getText(subscribeButtonKey));
 123         subscribeButton.setMnemonic(getMnemonicInt(subscribeButtonKey));
 124         subscribeButton.setToolTipText(getText(subscribeButtonKey + ".toolTip"));
 125         subscribeButton.addActionListener(this);
 126         // create the unsubscribe button
 127         String unsubscribeButtonKey = "MBeansTab.unsubscribeNotificationsButton";
 128         unsubscribeButton = new JButton(getText(unsubscribeButtonKey));
 129         unsubscribeButton.setMnemonic(getMnemonicInt(unsubscribeButtonKey));
 130         unsubscribeButton.setToolTipText(getText(unsubscribeButtonKey + ".toolTip"));
 131         unsubscribeButton.addActionListener(this);
 132         // create XMBeanAttributes container
 133         mbeanAttributes = new XMBeanAttributes(mbeansTab);
 134         // create XMBeanOperations container
 135         mbeanOperations = new XMBeanOperations(mbeansTab);
 136         mbeanOperations.addOperationsListener(this);
 137         // create XMBeanNotifications container
 138         mbeanNotifications = new XMBeanNotifications();
 139         mbeanNotifications.addNotificationsListener(this);
 140         // create XMBeanInfo container
 141         mbeanInfo = new XMBeanInfo();
 142     }
 143 
 144     private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {
 145         return (cn == n);
 146     }
 147 
 148     // Call on EDT
 149     private void showErrorDialog(Object message, String title) {
 150         new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run();


 221                         if (!isSelectedNode(node, currentNode)) {
 222                             return;
 223                         }
 224                         mbeanInfo.addMBeanInfo(mbean, mbi);
 225                         invalidate();
 226                         mainPanel.removeAll();
 227                         mainPanel.add(mbeanInfo, BorderLayout.CENTER);
 228                         southPanel.setVisible(false);
 229                         southPanel.removeAll();
 230                         validate();
 231                         repaint();
 232                     }
 233                 } catch (Exception e) {
 234                     Throwable t = Utils.getActualException(e);
 235                     if (JConsole.isDebug()) {
 236                         System.err.println("Couldn't get MBeanInfo for MBean [" +
 237                                 mbean.getObjectName() + "]");
 238                         t.printStackTrace();
 239                     }
 240                     showErrorDialog(t.toString(),
 241                             Resources.getText("Problem displaying MBean"));
 242                 }
 243             }
 244         };
 245         sw.execute();
 246     }
 247 
 248     // Call on EDT
 249     private void displayMetadataNode(final DefaultMutableTreeNode node) {
 250         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
 251         final XMBeanInfo mbi = mbeanInfo;
 252         switch (uo.getType()) {
 253             case ATTRIBUTE:
 254                 SwingWorker<MBeanAttributeInfo, Void> sw =
 255                         new SwingWorker<MBeanAttributeInfo, Void>() {
 256                             @Override
 257                             public MBeanAttributeInfo doInBackground() {
 258                                 Object attrData = uo.getData();
 259                                 mbean = (XMBean) ((Object[]) attrData)[0];
 260                                 MBeanAttributeInfo mbai =
 261                                         (MBeanAttributeInfo) ((Object[]) attrData)[1];
 262                                 mbeanAttributes.loadAttributes(mbean, new MBeanInfo(
 263                                         null, null, new MBeanAttributeInfo[]{mbai},
 264                                         null, null, null));
 265                                 return mbai;
 266                             }
 267                             @Override
 268                             protected void done() {
 269                                 try {
 270                                     MBeanAttributeInfo mbai = get();
 271                                     if (!isSelectedNode(node, currentNode)) {
 272                                         return;
 273                                     }
 274                                     invalidate();
 275                                     mainPanel.removeAll();
 276                                     JPanel attributePanel =
 277                                             new JPanel(new BorderLayout());
 278                                     JPanel attributeBorderPanel =
 279                                             new JPanel(new BorderLayout());
 280                                     attributeBorderPanel.setBorder(
 281                                             BorderFactory.createTitledBorder(
 282                                             Resources.getText("Attribute value")));
 283                                     JPanel attributeValuePanel =
 284                                             new JPanel(new BorderLayout());
 285                                     attributeValuePanel.setBorder(
 286                                             LineBorder.createGrayLineBorder());
 287                                     attributeValuePanel.add(mbeanAttributes.getTableHeader(),
 288                                             BorderLayout.PAGE_START);
 289                                     attributeValuePanel.add(mbeanAttributes,
 290                                             BorderLayout.CENTER);
 291                                     attributeBorderPanel.add(attributeValuePanel,
 292                                             BorderLayout.CENTER);
 293                                     JPanel refreshButtonPanel = new JPanel();
 294                                     refreshButtonPanel.add(refreshButton);
 295                                     attributeBorderPanel.add(refreshButtonPanel,
 296                                             BorderLayout.SOUTH);
 297                                     refreshButton.setEnabled(true);
 298                                     attributePanel.add(attributeBorderPanel,
 299                                             BorderLayout.NORTH);
 300                                     mbi.addMBeanAttributeInfo(mbai);
 301                                     attributePanel.add(mbi, BorderLayout.CENTER);
 302                                     mainPanel.add(attributePanel,
 303                                             BorderLayout.CENTER);
 304                                     southPanel.setVisible(false);
 305                                     southPanel.removeAll();
 306                                     validate();
 307                                     repaint();
 308                                 } catch (Exception e) {
 309                                     Throwable t = Utils.getActualException(e);
 310                                     if (JConsole.isDebug()) {
 311                                         System.err.println("Problem displaying MBean " +
 312                                                 "attribute for MBean [" +
 313                                                 mbean.getObjectName() + "]");
 314                                         t.printStackTrace();
 315                                     }
 316                                     showErrorDialog(t.toString(),
 317                                             Resources.getText("Problem displaying MBean"));
 318                                 }
 319                             }
 320                         };
 321                 sw.execute();
 322                 break;
 323             case OPERATION:
 324                 Object operData = uo.getData();
 325                 mbean = (XMBean) ((Object[]) operData)[0];
 326                 MBeanOperationInfo mboi =
 327                         (MBeanOperationInfo) ((Object[]) operData)[1];
 328                 mbeanOperations.loadOperations(mbean,
 329                         new MBeanInfo(null, null, null, null,
 330                         new MBeanOperationInfo[]{mboi}, null));
 331                 invalidate();
 332                 mainPanel.removeAll();
 333                 JPanel operationPanel = new JPanel(new BorderLayout());
 334                 JPanel operationBorderPanel = new JPanel(new BorderLayout());
 335                 operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
 336                         Resources.getText("Operation invocation")));
 337                 operationBorderPanel.add(new JScrollPane(mbeanOperations));
 338                 operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
 339                 mbi.addMBeanOperationInfo(mboi);
 340                 operationPanel.add(mbi, BorderLayout.CENTER);
 341                 mainPanel.add(operationPanel, BorderLayout.CENTER);
 342                 southPanel.setVisible(false);
 343                 southPanel.removeAll();
 344                 validate();
 345                 repaint();
 346                 break;
 347             case NOTIFICATION:
 348                 Object notifData = uo.getData();
 349                 invalidate();
 350                 mainPanel.removeAll();
 351                 mbi.addMBeanNotificationInfo((MBeanNotificationInfo) notifData);
 352                 mainPanel.add(mbi, BorderLayout.CENTER);
 353                 southPanel.setVisible(false);
 354                 southPanel.removeAll();
 355                 validate();
 356                 repaint();


 372                     IntrospectionException, ReflectionException, IOException {
 373                 MBeanInfo mbi = xmb.getMBeanInfo();
 374                 return mbi;
 375             }
 376             @Override
 377             protected void done() {
 378                 try {
 379                     MBeanInfo mbi = get();
 380                     if (mbi != null && mbi.getAttributes() != null &&
 381                             mbi.getAttributes().length > 0) {
 382 
 383                         mbeanAttributes.loadAttributes(xmb, mbi);
 384 
 385                         if (!isSelectedNode(node, currentNode)) {
 386                             return;
 387                         }
 388                         invalidate();
 389                         mainPanel.removeAll();
 390                         JPanel borderPanel = new JPanel(new BorderLayout());
 391                         borderPanel.setBorder(BorderFactory.createTitledBorder(
 392                                 Resources.getText("Attribute values")));
 393                         borderPanel.add(new JScrollPane(mbeanAttributes));
 394                         mainPanel.add(borderPanel, BorderLayout.CENTER);
 395                         // add the refresh button to the south panel
 396                         southPanel.removeAll();
 397                         southPanel.add(refreshButton, BorderLayout.SOUTH);
 398                         southPanel.setVisible(true);
 399                         refreshButton.setEnabled(true);
 400                         validate();
 401                         repaint();
 402                     }
 403                 } catch (Exception e) {
 404                     Throwable t = Utils.getActualException(e);
 405                     if (JConsole.isDebug()) {
 406                         System.err.println("Problem displaying MBean " +
 407                                 "attributes for MBean [" +
 408                                 mbean.getObjectName() + "]");
 409                         t.printStackTrace();
 410                     }
 411                     showErrorDialog(t.toString(),
 412                             Resources.getText("Problem displaying MBean"));
 413                 }
 414             }
 415         };
 416         sw.execute();
 417     }
 418 
 419     // Call on EDT
 420     private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) {
 421         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
 422         if (!uo.getType().equals(Type.OPERATIONS)) {
 423             return;
 424         }
 425         mbean = (XMBean) uo.getData();
 426         SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
 427             @Override
 428             public MBeanInfo doInBackground() throws InstanceNotFoundException,
 429                     IntrospectionException, ReflectionException, IOException {
 430                 return mbean.getMBeanInfo();
 431             }
 432             @Override
 433             protected void done() {
 434                 try {
 435                     MBeanInfo mbi = get();
 436                     if (mbi != null) {
 437                         if (!isSelectedNode(node, currentNode)) {
 438                             return;
 439                         }
 440                         mbeanOperations.loadOperations(mbean, mbi);
 441                         invalidate();
 442                         mainPanel.removeAll();
 443                         JPanel borderPanel = new JPanel(new BorderLayout());
 444                         borderPanel.setBorder(BorderFactory.createTitledBorder(
 445                                 Resources.getText("Operation invocation")));
 446                         borderPanel.add(new JScrollPane(mbeanOperations));
 447                         mainPanel.add(borderPanel, BorderLayout.CENTER);
 448                         southPanel.setVisible(false);
 449                         southPanel.removeAll();
 450                         validate();
 451                         repaint();
 452                     }
 453                 } catch (Exception e) {
 454                     Throwable t = Utils.getActualException(e);
 455                     if (JConsole.isDebug()) {
 456                         System.err.println("Problem displaying MBean " +
 457                                 "operations for MBean [" +
 458                                 mbean.getObjectName() + "]");
 459                         t.printStackTrace();
 460                     }
 461                     showErrorDialog(t.toString(),
 462                             Resources.getText("Problem displaying MBean"));
 463                 }
 464             }
 465         };
 466         sw.execute();
 467     }
 468 
 469     // Call on EDT
 470     private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) {
 471         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
 472         if (!uo.getType().equals(Type.NOTIFICATIONS)) {
 473             return;
 474         }
 475         mbean = (XMBean) uo.getData();
 476         mbeanNotifications.loadNotifications(mbean);
 477         updateNotifications();
 478         invalidate();
 479         mainPanel.removeAll();
 480         JPanel borderPanel = new JPanel(new BorderLayout());
 481         borderPanel.setBorder(BorderFactory.createTitledBorder(
 482                 Resources.getText("Notification buffer")));
 483         borderPanel.add(new JScrollPane(mbeanNotifications));
 484         mainPanel.add(borderPanel, BorderLayout.CENTER);
 485         // add the subscribe/unsubscribe/clear buttons to the south panel
 486         southPanel.removeAll();
 487         southPanel.add(subscribeButton, BorderLayout.WEST);
 488         southPanel.add(unsubscribeButton, BorderLayout.CENTER);
 489         southPanel.add(clearButton, BorderLayout.EAST);
 490         southPanel.setVisible(true);
 491         subscribeButton.setEnabled(true);
 492         unsubscribeButton.setEnabled(true);
 493         clearButton.setEnabled(true);
 494         validate();
 495         repaint();
 496     }
 497 
 498     // Call on EDT
 499     private void displayEmptyNode() {
 500         invalidate();
 501         mainPanel.removeAll();
 502         southPanel.removeAll();


 511         new SwingWorker<Void, Void>() {
 512             @Override
 513             public Void doInBackground()
 514                     throws InstanceNotFoundException, IOException {
 515                 mbeanNotifications.registerListener(currentNode);
 516                 return null;
 517             }
 518             @Override
 519             protected void done() {
 520                 try {
 521                     get();
 522                     updateNotifications();
 523                     validate();
 524                 } catch (Exception e) {
 525                     Throwable t = Utils.getActualException(e);
 526                     if (JConsole.isDebug()) {
 527                         System.err.println("Problem adding listener");
 528                         t.printStackTrace();
 529                     }
 530                     showErrorDialog(t.getMessage(),
 531                             Resources.getText("Problem adding listener"));
 532                 }
 533             }
 534         }.execute();
 535     }
 536 
 537     /**
 538      * Unsubscribe button action.
 539      */
 540     private void unregisterListener() {
 541         new SwingWorker<Boolean, Void>() {
 542             @Override
 543             public Boolean doInBackground() {
 544                 return mbeanNotifications.unregisterListener(currentNode);
 545             }
 546             @Override
 547             protected void done() {
 548                 try {
 549                     if (get()) {
 550                         updateNotifications();
 551                         validate();
 552                     }
 553                 } catch (Exception e) {
 554                     Throwable t = Utils.getActualException(e);
 555                     if (JConsole.isDebug()) {
 556                         System.err.println("Problem removing listener");
 557                         t.printStackTrace();
 558                     }
 559                     showErrorDialog(t.getMessage(),
 560                             Resources.getText("Problem removing listener"));
 561                 }
 562             }
 563         }.execute();
 564     }
 565 
 566     /**
 567      * Refresh button action.
 568      */
 569     private void refreshAttributes() {
 570         mbeanAttributes.refreshAttributes();
 571     }
 572 
 573     // Call on EDT
 574     private void updateNotifications() {
 575         if (mbeanNotifications.isListenerRegistered(mbean)) {
 576             long received = mbeanNotifications.getReceivedNotifications(mbean);
 577             updateReceivedNotifications(currentNode, received, false);
 578         } else {
 579             clearNotifications();
 580         }
 581     }
 582 
 583     /**
 584      * Update notification node label in MBean tree: "Notifications[received]".
 585      */
 586     // Call on EDT
 587     private void updateReceivedNotifications(
 588             DefaultMutableTreeNode emitter, long received, boolean bold) {
 589         String text = Resources.getText("Notifications") + "[" + received + "]";
 590         DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
 591         if (bold && emitter != selectedNode) {
 592             text = "<html><b>" + text + "</b></html>";
 593         }
 594         updateNotificationsNodeLabel(emitter, text);
 595     }
 596 
 597     /**
 598      * Update notification node label in MBean tree: "Notifications".
 599      */
 600     // Call on EDT
 601     private void clearNotifications() {
 602         updateNotificationsNodeLabel(currentNode,
 603                 Resources.getText("Notifications"));
 604     }
 605 
 606     /**
 607      * Update notification node label in MBean tree: "Notifications[0]".
 608      */
 609     // Call on EDT
 610     private void clearNotifications0() {
 611         updateNotificationsNodeLabel(currentNode,
 612                 Resources.getText("Notifications") + "[0]");
 613     }
 614 
 615     /**
 616      * Update the label of the supplied MBean tree node.
 617      */
 618     // Call on EDT
 619     private void updateNotificationsNodeLabel(
 620             DefaultMutableTreeNode node, String label) {
 621         synchronized (mbeansTab.getTree()) {
 622             invalidate();
 623             XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
 624             XNodeInfo newUserObject = new XNodeInfo(
 625                     oldUserObject.getType(), oldUserObject.getData(),
 626                     label, oldUserObject.getToolTipText());
 627             node.setUserObject(newUserObject);
 628             DefaultTreeModel model =
 629                     (DefaultTreeModel) mbeansTab.getTree().getModel();
 630             model.nodeChanged(node);
 631             validate();
 632             repaint();


 695                     JScrollPane scrollPane = new JScrollPane(textArea);
 696                     Dimension d = scrollPane.getPreferredSize();
 697                     if (d.getWidth() > 400 || d.getHeight() > 250) {
 698                         scrollPane.setPreferredSize(new Dimension(400, 250));
 699                     }
 700                     message = scrollPane;
 701                 } else {
 702                     if (!(comp instanceof JScrollPane)) {
 703                         comp = new JScrollPane(comp);
 704                     }
 705                     Dimension d = comp.getPreferredSize();
 706                     if (d.getWidth() > 400 || d.getHeight() > 250) {
 707                         comp.setPreferredSize(new Dimension(400, 250));
 708                     }
 709                     message = comp;
 710                 }
 711             }
 712             new ThreadDialog(
 713                     (Component) e.getSource(),
 714                     message,
 715                     Resources.getText("Operation return value"),
 716                     JOptionPane.INFORMATION_MESSAGE).run();
 717         } // Got notification
 718         else if (e.getType().equals(
 719                 XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {
 720             DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;
 721             Long received = (Long) e.getUserData();
 722             updateReceivedNotifications(emitter, received.longValue(), true);
 723         }
 724     }
 725 
 726     /**
 727      * Action listener: handles actions in panel buttons
 728      */
 729     // Call on EDT
 730     public void actionPerformed(ActionEvent e) {
 731         if (e.getSource() instanceof JButton) {
 732             JButton button = (JButton) e.getSource();
 733             // Refresh button
 734             if (button == refreshButton) {
 735                 refreshAttributes();


  39 import javax.management.MBeanInfo;
  40 import javax.management.InstanceNotFoundException;
  41 import javax.management.ReflectionException;
  42 import javax.management.MBeanAttributeInfo;
  43 import javax.management.MBeanOperationInfo;
  44 import javax.management.MBeanNotificationInfo;
  45 import javax.management.Notification;
  46 import javax.swing.BorderFactory;
  47 import javax.swing.JButton;
  48 import javax.swing.JOptionPane;
  49 import javax.swing.JPanel;
  50 import javax.swing.JScrollPane;
  51 import javax.swing.JTextArea;
  52 import javax.swing.SwingWorker;
  53 import javax.swing.border.LineBorder;
  54 import javax.swing.tree.DefaultMutableTreeNode;
  55 import javax.swing.tree.DefaultTreeModel;
  56 
  57 import sun.tools.jconsole.*;
  58 import sun.tools.jconsole.inspector.XNodeInfo.Type;
  59 import sun.tools.jconsole.resources.Messages;

  60 
  61 @SuppressWarnings("serial")
  62 public class XSheet extends JPanel
  63         implements ActionListener, NotificationListener {
  64 
  65     private JPanel mainPanel;
  66     private JPanel southPanel;
  67     // Node being currently displayed
  68     private volatile DefaultMutableTreeNode currentNode;
  69     // MBean being currently displayed
  70     private volatile XMBean mbean;
  71     // XMBeanAttributes container
  72     private XMBeanAttributes mbeanAttributes;
  73     // XMBeanOperations container
  74     private XMBeanOperations mbeanOperations;
  75     // XMBeanNotifications container
  76     private XMBeanNotifications mbeanNotifications;
  77     // XMBeanInfo container
  78     private XMBeanInfo mbeanInfo;
  79     // Refresh JButton (mbean attributes case)


  88         setupScreen();
  89     }
  90 
  91     public void dispose() {
  92         clear();
  93         XDataViewer.dispose(mbeansTab);
  94         mbeanNotifications.dispose();
  95     }
  96 
  97     private void setupScreen() {
  98         setLayout(new BorderLayout());
  99         setBorder(BorderFactory.createLineBorder(Color.GRAY));
 100         // add main panel to XSheet
 101         mainPanel = new JPanel();
 102         mainPanel.setLayout(new BorderLayout());
 103         add(mainPanel, BorderLayout.CENTER);
 104         // add south panel to XSheet
 105         southPanel = new JPanel();
 106         add(southPanel, BorderLayout.SOUTH);
 107         // create the refresh button
 108         refreshButton = new JButton(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON);
 109         refreshButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON));
 110         refreshButton.setToolTipText(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP);

 111         refreshButton.addActionListener(this);
 112         // create the clear button
 113         clearButton = new JButton(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON);
 114         clearButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON));
 115         clearButton.setToolTipText(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP);

 116         clearButton.addActionListener(this);
 117         // create the subscribe button
 118         subscribeButton = new JButton(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON);
 119         subscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON));
 120         subscribeButton.setToolTipText(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP);

 121         subscribeButton.addActionListener(this);
 122         // create the unsubscribe button
 123        unsubscribeButton = new JButton(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON);
 124         unsubscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON));
 125         unsubscribeButton.setToolTipText(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP);

 126         unsubscribeButton.addActionListener(this);
 127         // create XMBeanAttributes container
 128         mbeanAttributes = new XMBeanAttributes(mbeansTab);
 129         // create XMBeanOperations container
 130         mbeanOperations = new XMBeanOperations(mbeansTab);
 131         mbeanOperations.addOperationsListener(this);
 132         // create XMBeanNotifications container
 133         mbeanNotifications = new XMBeanNotifications();
 134         mbeanNotifications.addNotificationsListener(this);
 135         // create XMBeanInfo container
 136         mbeanInfo = new XMBeanInfo();
 137     }
 138 
 139     private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {
 140         return (cn == n);
 141     }
 142 
 143     // Call on EDT
 144     private void showErrorDialog(Object message, String title) {
 145         new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run();


 216                         if (!isSelectedNode(node, currentNode)) {
 217                             return;
 218                         }
 219                         mbeanInfo.addMBeanInfo(mbean, mbi);
 220                         invalidate();
 221                         mainPanel.removeAll();
 222                         mainPanel.add(mbeanInfo, BorderLayout.CENTER);
 223                         southPanel.setVisible(false);
 224                         southPanel.removeAll();
 225                         validate();
 226                         repaint();
 227                     }
 228                 } catch (Exception e) {
 229                     Throwable t = Utils.getActualException(e);
 230                     if (JConsole.isDebug()) {
 231                         System.err.println("Couldn't get MBeanInfo for MBean [" +
 232                                 mbean.getObjectName() + "]");
 233                         t.printStackTrace();
 234                     }
 235                     showErrorDialog(t.toString(),
 236                             Messages.PROBLEM_DISPLAYING_MBEAN);
 237                 }
 238             }
 239         };
 240         sw.execute();
 241     }
 242 
 243     // Call on EDT
 244     private void displayMetadataNode(final DefaultMutableTreeNode node) {
 245         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
 246         final XMBeanInfo mbi = mbeanInfo;
 247         switch (uo.getType()) {
 248             case ATTRIBUTE:
 249                 SwingWorker<MBeanAttributeInfo, Void> sw =
 250                         new SwingWorker<MBeanAttributeInfo, Void>() {
 251                             @Override
 252                             public MBeanAttributeInfo doInBackground() {
 253                                 Object attrData = uo.getData();
 254                                 mbean = (XMBean) ((Object[]) attrData)[0];
 255                                 MBeanAttributeInfo mbai =
 256                                         (MBeanAttributeInfo) ((Object[]) attrData)[1];
 257                                 mbeanAttributes.loadAttributes(mbean, new MBeanInfo(
 258                                         null, null, new MBeanAttributeInfo[]{mbai},
 259                                         null, null, null));
 260                                 return mbai;
 261                             }
 262                             @Override
 263                             protected void done() {
 264                                 try {
 265                                     MBeanAttributeInfo mbai = get();
 266                                     if (!isSelectedNode(node, currentNode)) {
 267                                         return;
 268                                     }
 269                                     invalidate();
 270                                     mainPanel.removeAll();
 271                                     JPanel attributePanel =
 272                                             new JPanel(new BorderLayout());
 273                                     JPanel attributeBorderPanel =
 274                                             new JPanel(new BorderLayout());
 275                                     attributeBorderPanel.setBorder(
 276                                             BorderFactory.createTitledBorder(
 277                                             Messages.ATTRIBUTE_VALUE));
 278                                     JPanel attributeValuePanel =
 279                                             new JPanel(new BorderLayout());
 280                                     attributeValuePanel.setBorder(
 281                                             LineBorder.createGrayLineBorder());
 282                                     attributeValuePanel.add(mbeanAttributes.getTableHeader(),
 283                                             BorderLayout.PAGE_START);
 284                                     attributeValuePanel.add(mbeanAttributes,
 285                                             BorderLayout.CENTER);
 286                                     attributeBorderPanel.add(attributeValuePanel,
 287                                             BorderLayout.CENTER);
 288                                     JPanel refreshButtonPanel = new JPanel();
 289                                     refreshButtonPanel.add(refreshButton);
 290                                     attributeBorderPanel.add(refreshButtonPanel,
 291                                             BorderLayout.SOUTH);
 292                                     refreshButton.setEnabled(true);
 293                                     attributePanel.add(attributeBorderPanel,
 294                                             BorderLayout.NORTH);
 295                                     mbi.addMBeanAttributeInfo(mbai);
 296                                     attributePanel.add(mbi, BorderLayout.CENTER);
 297                                     mainPanel.add(attributePanel,
 298                                             BorderLayout.CENTER);
 299                                     southPanel.setVisible(false);
 300                                     southPanel.removeAll();
 301                                     validate();
 302                                     repaint();
 303                                 } catch (Exception e) {
 304                                     Throwable t = Utils.getActualException(e);
 305                                     if (JConsole.isDebug()) {
 306                                         System.err.println("Problem displaying MBean " +
 307                                                 "attribute for MBean [" +
 308                                                 mbean.getObjectName() + "]");
 309                                         t.printStackTrace();
 310                                     }
 311                                     showErrorDialog(t.toString(),
 312                                             Messages.PROBLEM_DISPLAYING_MBEAN);
 313                                 }
 314                             }
 315                         };
 316                 sw.execute();
 317                 break;
 318             case OPERATION:
 319                 Object operData = uo.getData();
 320                 mbean = (XMBean) ((Object[]) operData)[0];
 321                 MBeanOperationInfo mboi =
 322                         (MBeanOperationInfo) ((Object[]) operData)[1];
 323                 mbeanOperations.loadOperations(mbean,
 324                         new MBeanInfo(null, null, null, null,
 325                         new MBeanOperationInfo[]{mboi}, null));
 326                 invalidate();
 327                 mainPanel.removeAll();
 328                 JPanel operationPanel = new JPanel(new BorderLayout());
 329                 JPanel operationBorderPanel = new JPanel(new BorderLayout());
 330                 operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
 331                         Messages.OPERATION_INVOCATION));
 332                 operationBorderPanel.add(new JScrollPane(mbeanOperations));
 333                 operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
 334                 mbi.addMBeanOperationInfo(mboi);
 335                 operationPanel.add(mbi, BorderLayout.CENTER);
 336                 mainPanel.add(operationPanel, BorderLayout.CENTER);
 337                 southPanel.setVisible(false);
 338                 southPanel.removeAll();
 339                 validate();
 340                 repaint();
 341                 break;
 342             case NOTIFICATION:
 343                 Object notifData = uo.getData();
 344                 invalidate();
 345                 mainPanel.removeAll();
 346                 mbi.addMBeanNotificationInfo((MBeanNotificationInfo) notifData);
 347                 mainPanel.add(mbi, BorderLayout.CENTER);
 348                 southPanel.setVisible(false);
 349                 southPanel.removeAll();
 350                 validate();
 351                 repaint();


 367                     IntrospectionException, ReflectionException, IOException {
 368                 MBeanInfo mbi = xmb.getMBeanInfo();
 369                 return mbi;
 370             }
 371             @Override
 372             protected void done() {
 373                 try {
 374                     MBeanInfo mbi = get();
 375                     if (mbi != null && mbi.getAttributes() != null &&
 376                             mbi.getAttributes().length > 0) {
 377 
 378                         mbeanAttributes.loadAttributes(xmb, mbi);
 379 
 380                         if (!isSelectedNode(node, currentNode)) {
 381                             return;
 382                         }
 383                         invalidate();
 384                         mainPanel.removeAll();
 385                         JPanel borderPanel = new JPanel(new BorderLayout());
 386                         borderPanel.setBorder(BorderFactory.createTitledBorder(
 387                                 Messages.ATTRIBUTE_VALUES));
 388                         borderPanel.add(new JScrollPane(mbeanAttributes));
 389                         mainPanel.add(borderPanel, BorderLayout.CENTER);
 390                         // add the refresh button to the south panel
 391                         southPanel.removeAll();
 392                         southPanel.add(refreshButton, BorderLayout.SOUTH);
 393                         southPanel.setVisible(true);
 394                         refreshButton.setEnabled(true);
 395                         validate();
 396                         repaint();
 397                     }
 398                 } catch (Exception e) {
 399                     Throwable t = Utils.getActualException(e);
 400                     if (JConsole.isDebug()) {
 401                         System.err.println("Problem displaying MBean " +
 402                                 "attributes for MBean [" +
 403                                 mbean.getObjectName() + "]");
 404                         t.printStackTrace();
 405                     }
 406                     showErrorDialog(t.toString(),
 407                             Messages.PROBLEM_DISPLAYING_MBEAN);
 408                 }
 409             }
 410         };
 411         sw.execute();
 412     }
 413 
 414     // Call on EDT
 415     private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) {
 416         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
 417         if (!uo.getType().equals(Type.OPERATIONS)) {
 418             return;
 419         }
 420         mbean = (XMBean) uo.getData();
 421         SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
 422             @Override
 423             public MBeanInfo doInBackground() throws InstanceNotFoundException,
 424                     IntrospectionException, ReflectionException, IOException {
 425                 return mbean.getMBeanInfo();
 426             }
 427             @Override
 428             protected void done() {
 429                 try {
 430                     MBeanInfo mbi = get();
 431                     if (mbi != null) {
 432                         if (!isSelectedNode(node, currentNode)) {
 433                             return;
 434                         }
 435                         mbeanOperations.loadOperations(mbean, mbi);
 436                         invalidate();
 437                         mainPanel.removeAll();
 438                         JPanel borderPanel = new JPanel(new BorderLayout());
 439                         borderPanel.setBorder(BorderFactory.createTitledBorder(
 440                                 Messages.OPERATION_INVOCATION));
 441                         borderPanel.add(new JScrollPane(mbeanOperations));
 442                         mainPanel.add(borderPanel, BorderLayout.CENTER);
 443                         southPanel.setVisible(false);
 444                         southPanel.removeAll();
 445                         validate();
 446                         repaint();
 447                     }
 448                 } catch (Exception e) {
 449                     Throwable t = Utils.getActualException(e);
 450                     if (JConsole.isDebug()) {
 451                         System.err.println("Problem displaying MBean " +
 452                                 "operations for MBean [" +
 453                                 mbean.getObjectName() + "]");
 454                         t.printStackTrace();
 455                     }
 456                     showErrorDialog(t.toString(),
 457                             Messages.PROBLEM_DISPLAYING_MBEAN);
 458                 }
 459             }
 460         };
 461         sw.execute();
 462     }
 463 
 464     // Call on EDT
 465     private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) {
 466         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
 467         if (!uo.getType().equals(Type.NOTIFICATIONS)) {
 468             return;
 469         }
 470         mbean = (XMBean) uo.getData();
 471         mbeanNotifications.loadNotifications(mbean);
 472         updateNotifications();
 473         invalidate();
 474         mainPanel.removeAll();
 475         JPanel borderPanel = new JPanel(new BorderLayout());
 476         borderPanel.setBorder(BorderFactory.createTitledBorder(
 477                 Messages.NOTIFICATION_BUFFER));
 478         borderPanel.add(new JScrollPane(mbeanNotifications));
 479         mainPanel.add(borderPanel, BorderLayout.CENTER);
 480         // add the subscribe/unsubscribe/clear buttons to the south panel
 481         southPanel.removeAll();
 482         southPanel.add(subscribeButton, BorderLayout.WEST);
 483         southPanel.add(unsubscribeButton, BorderLayout.CENTER);
 484         southPanel.add(clearButton, BorderLayout.EAST);
 485         southPanel.setVisible(true);
 486         subscribeButton.setEnabled(true);
 487         unsubscribeButton.setEnabled(true);
 488         clearButton.setEnabled(true);
 489         validate();
 490         repaint();
 491     }
 492 
 493     // Call on EDT
 494     private void displayEmptyNode() {
 495         invalidate();
 496         mainPanel.removeAll();
 497         southPanel.removeAll();


 506         new SwingWorker<Void, Void>() {
 507             @Override
 508             public Void doInBackground()
 509                     throws InstanceNotFoundException, IOException {
 510                 mbeanNotifications.registerListener(currentNode);
 511                 return null;
 512             }
 513             @Override
 514             protected void done() {
 515                 try {
 516                     get();
 517                     updateNotifications();
 518                     validate();
 519                 } catch (Exception e) {
 520                     Throwable t = Utils.getActualException(e);
 521                     if (JConsole.isDebug()) {
 522                         System.err.println("Problem adding listener");
 523                         t.printStackTrace();
 524                     }
 525                     showErrorDialog(t.getMessage(),
 526                             Messages.PROBLEM_ADDING_LISTENER);
 527                 }
 528             }
 529         }.execute();
 530     }
 531 
 532     /**
 533      * Unsubscribe button action.
 534      */
 535     private void unregisterListener() {
 536         new SwingWorker<Boolean, Void>() {
 537             @Override
 538             public Boolean doInBackground() {
 539                 return mbeanNotifications.unregisterListener(currentNode);
 540             }
 541             @Override
 542             protected void done() {
 543                 try {
 544                     if (get()) {
 545                         updateNotifications();
 546                         validate();
 547                     }
 548                 } catch (Exception e) {
 549                     Throwable t = Utils.getActualException(e);
 550                     if (JConsole.isDebug()) {
 551                         System.err.println("Problem removing listener");
 552                         t.printStackTrace();
 553                     }
 554                     showErrorDialog(t.getMessage(),
 555                             Messages.PROBLEM_REMOVING_LISTENER);
 556                 }
 557             }
 558         }.execute();
 559     }
 560 
 561     /**
 562      * Refresh button action.
 563      */
 564     private void refreshAttributes() {
 565         mbeanAttributes.refreshAttributes();
 566     }
 567 
 568     // Call on EDT
 569     private void updateNotifications() {
 570         if (mbeanNotifications.isListenerRegistered(mbean)) {
 571             long received = mbeanNotifications.getReceivedNotifications(mbean);
 572             updateReceivedNotifications(currentNode, received, false);
 573         } else {
 574             clearNotifications();
 575         }
 576     }
 577 
 578     /**
 579      * Update notification node label in MBean tree: "Notifications[received]".
 580      */
 581     // Call on EDT
 582     private void updateReceivedNotifications(
 583             DefaultMutableTreeNode emitter, long received, boolean bold) {
 584         String text = Messages.NOTIFICATIONS + "[" + received + "]";
 585         DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
 586         if (bold && emitter != selectedNode) {
 587             text = "<html><b>" + text + "</b></html>";
 588         }
 589         updateNotificationsNodeLabel(emitter, text);
 590     }
 591 
 592     /**
 593      * Update notification node label in MBean tree: "Notifications".
 594      */
 595     // Call on EDT
 596     private void clearNotifications() {
 597         updateNotificationsNodeLabel(currentNode,
 598                 Messages.NOTIFICATIONS);
 599     }
 600 
 601     /**
 602      * Update notification node label in MBean tree: "Notifications[0]".
 603      */
 604     // Call on EDT
 605     private void clearNotifications0() {
 606         updateNotificationsNodeLabel(currentNode,
 607                 Messages.NOTIFICATIONS + "[0]");
 608     }
 609 
 610     /**
 611      * Update the label of the supplied MBean tree node.
 612      */
 613     // Call on EDT
 614     private void updateNotificationsNodeLabel(
 615             DefaultMutableTreeNode node, String label) {
 616         synchronized (mbeansTab.getTree()) {
 617             invalidate();
 618             XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
 619             XNodeInfo newUserObject = new XNodeInfo(
 620                     oldUserObject.getType(), oldUserObject.getData(),
 621                     label, oldUserObject.getToolTipText());
 622             node.setUserObject(newUserObject);
 623             DefaultTreeModel model =
 624                     (DefaultTreeModel) mbeansTab.getTree().getModel();
 625             model.nodeChanged(node);
 626             validate();
 627             repaint();


 690                     JScrollPane scrollPane = new JScrollPane(textArea);
 691                     Dimension d = scrollPane.getPreferredSize();
 692                     if (d.getWidth() > 400 || d.getHeight() > 250) {
 693                         scrollPane.setPreferredSize(new Dimension(400, 250));
 694                     }
 695                     message = scrollPane;
 696                 } else {
 697                     if (!(comp instanceof JScrollPane)) {
 698                         comp = new JScrollPane(comp);
 699                     }
 700                     Dimension d = comp.getPreferredSize();
 701                     if (d.getWidth() > 400 || d.getHeight() > 250) {
 702                         comp.setPreferredSize(new Dimension(400, 250));
 703                     }
 704                     message = comp;
 705                 }
 706             }
 707             new ThreadDialog(
 708                     (Component) e.getSource(),
 709                     message,
 710                     Messages.OPERATION_RETURN_VALUE,
 711                     JOptionPane.INFORMATION_MESSAGE).run();
 712         } // Got notification
 713         else if (e.getType().equals(
 714                 XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {
 715             DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;
 716             Long received = (Long) e.getUserData();
 717             updateReceivedNotifications(emitter, received.longValue(), true);
 718         }
 719     }
 720 
 721     /**
 722      * Action listener: handles actions in panel buttons
 723      */
 724     // Call on EDT
 725     public void actionPerformed(ActionEvent e) {
 726         if (e.getSource() instanceof JButton) {
 727             JButton button = (JButton) e.getSource();
 728             // Refresh button
 729             if (button == refreshButton) {
 730                 refreshAttributes();