1 /* 2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole.inspector; 27 28 29 import java.awt.BorderLayout; 30 import java.awt.Color; 31 import java.awt.Component; 32 import java.awt.Dimension; 33 import java.awt.event.ActionEvent; 34 import java.awt.event.ActionListener; 35 import java.io.IOException; 36 37 import javax.management.IntrospectionException; 38 import javax.management.NotificationListener; 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) 80 private JButton refreshButton; 81 // Subscribe/Unsubscribe/Clear JButton (mbean notifications case) 82 private JButton clearButton, subscribeButton, unsubscribeButton; 83 // Reference to MBeans tab 84 private MBeansTab mbeansTab; 85 86 public XSheet(MBeansTab mbeansTab) { 87 this.mbeansTab = mbeansTab; 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(); 146 } 147 148 public boolean isMBeanNode(DefaultMutableTreeNode node) { 149 Object userObject = node.getUserObject(); 150 if (userObject instanceof XNodeInfo) { 151 XNodeInfo uo = (XNodeInfo) userObject; 152 return uo.getType().equals(Type.MBEAN); 153 } 154 return false; 155 } 156 157 // Call on EDT 158 public synchronized void displayNode(DefaultMutableTreeNode node) { 159 clear(); 160 displayEmptyNode(); 161 if (node == null) { 162 return; 163 } 164 currentNode = node; 165 Object userObject = node.getUserObject(); 166 if (userObject instanceof XNodeInfo) { 167 XNodeInfo uo = (XNodeInfo) userObject; 168 switch (uo.getType()) { 169 case MBEAN: 170 displayMBeanNode(node); 171 break; 172 case NONMBEAN: 173 displayEmptyNode(); 174 break; 175 case ATTRIBUTES: 176 displayMBeanAttributesNode(node); 177 break; 178 case OPERATIONS: 179 displayMBeanOperationsNode(node); 180 break; 181 case NOTIFICATIONS: 182 displayMBeanNotificationsNode(node); 183 break; 184 case ATTRIBUTE: 185 case OPERATION: 186 case NOTIFICATION: 187 displayMetadataNode(node); 188 break; 189 default: 190 displayEmptyNode(); 191 break; 192 } 193 } else { 194 displayEmptyNode(); 195 } 196 } 197 198 // Call on EDT 199 private void displayMBeanNode(final DefaultMutableTreeNode node) { 200 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 201 if (!uo.getType().equals(Type.MBEAN)) { 202 return; 203 } 204 mbean = (XMBean) uo.getData(); 205 SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() { 206 @Override 207 public MBeanInfo doInBackground() throws InstanceNotFoundException, 208 IntrospectionException, ReflectionException, IOException { 209 return mbean.getMBeanInfo(); 210 } 211 @Override 212 protected void done() { 213 try { 214 MBeanInfo mbi = get(); 215 if (mbi != null) { 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(); 352 break; 353 } 354 } 355 356 // Call on EDT 357 private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) { 358 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 359 if (!uo.getType().equals(Type.ATTRIBUTES)) { 360 return; 361 } 362 mbean = (XMBean) uo.getData(); 363 final XMBean xmb = mbean; 364 SwingWorker<MBeanInfo,Void> sw = new SwingWorker<MBeanInfo,Void>() { 365 @Override 366 public MBeanInfo doInBackground() throws InstanceNotFoundException, 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(); 498 validate(); 499 repaint(); 500 } 501 502 /** 503 * Subscribe button action. 504 */ 505 private void registerListener() { 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(); 628 } 629 } 630 631 /** 632 * Clear button action. 633 */ 634 // Call on EDT 635 private void clearCurrentNotifications() { 636 mbeanNotifications.clearCurrentNotifications(); 637 if (mbeanNotifications.isListenerRegistered(mbean)) { 638 // Update notifs in MBean tree "Notifications[0]". 639 // 640 // Notification buffer has been cleared with a listener been 641 // registered so add "[0]" at the end of the node label. 642 // 643 clearNotifications0(); 644 } else { 645 // Update notifs in MBean tree "Notifications". 646 // 647 // Notification buffer has been cleared without a listener been 648 // registered so don't add "[0]" at the end of the node label. 649 // 650 clearNotifications(); 651 } 652 } 653 654 // Call on EDT 655 private void clear() { 656 mbeanAttributes.stopCellEditing(); 657 mbeanAttributes.emptyTable(); 658 mbeanAttributes.removeAttributes(); 659 mbeanOperations.removeOperations(); 660 mbeanNotifications.stopCellEditing(); 661 mbeanNotifications.emptyTable(); 662 mbeanNotifications.disableNotifications(); 663 mbean = null; 664 currentNode = null; 665 } 666 667 /** 668 * Notification listener: handles asynchronous reception 669 * of MBean operation results and MBean notifications. 670 */ 671 // Call on EDT 672 public void handleNotification(Notification e, Object handback) { 673 // Operation result 674 if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) { 675 final Object message; 676 if (handback == null) { 677 JTextArea textArea = new JTextArea("null"); 678 textArea.setEditable(false); 679 textArea.setEnabled(true); 680 textArea.setRows(textArea.getLineCount()); 681 message = textArea; 682 } else { 683 Component comp = mbeansTab.getDataViewer(). 684 createOperationViewer(handback, mbean); 685 if (comp == null) { 686 JTextArea textArea = new JTextArea(handback.toString()); 687 textArea.setEditable(false); 688 textArea.setEnabled(true); 689 textArea.setRows(textArea.getLineCount()); 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(); 731 return; 732 } 733 // Clear button 734 if (button == clearButton) { 735 clearCurrentNotifications(); 736 return; 737 } 738 // Subscribe button 739 if (button == subscribeButton) { 740 registerListener(); 741 return; 742 } 743 // Unsubscribe button 744 if (button == unsubscribeButton) { 745 unregisterListener(); 746 return; 747 } 748 } 749 } 750 }