1/* 2 * Copyright (c) 2004, 2012, 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 26package sun.tools.jconsole.inspector; 27 28 29import java.awt.BorderLayout; 30import java.awt.Color; 31import java.awt.Component; 32import java.awt.Dimension; 33import java.awt.event.ActionEvent; 34import java.awt.event.ActionListener; 35import java.io.IOException; 36 37import javax.management.IntrospectionException; 38import javax.management.NotificationListener; 39import javax.management.MBeanInfo; 40import javax.management.InstanceNotFoundException; 41import javax.management.ReflectionException; 42import javax.management.MBeanAttributeInfo; 43import javax.management.MBeanOperationInfo; 44import javax.management.MBeanNotificationInfo; 45import javax.management.Notification; 46import javax.swing.BorderFactory; 47import javax.swing.JButton; 48import javax.swing.JOptionPane; 49import javax.swing.JPanel; 50import javax.swing.JScrollPane; 51import javax.swing.JTextArea; 52import javax.swing.SwingWorker; 53import javax.swing.border.LineBorder; 54import javax.swing.tree.DefaultMutableTreeNode; 55import javax.swing.tree.DefaultTreeModel; 56 57import sun.tools.jconsole.*; 58import sun.tools.jconsole.inspector.XNodeInfo.Type; 59 60@SuppressWarnings("serial") 61public class XSheet extends JPanel 62 implements ActionListener, NotificationListener { 63 64 private JPanel mainPanel; 65 private JPanel southPanel; 66 // Node being currently displayed 67 private volatile DefaultMutableTreeNode currentNode; 68 // MBean being currently displayed 69 private volatile XMBean mbean; 70 // XMBeanAttributes container 71 private XMBeanAttributes mbeanAttributes; 72 // XMBeanOperations container 73 private XMBeanOperations mbeanOperations; 74 // XMBeanNotifications container 75 private XMBeanNotifications mbeanNotifications; 76 // XMBeanInfo container 77 private XMBeanInfo mbeanInfo; 78 // Refresh JButton (mbean attributes case) 79 private JButton refreshButton; 80 // Subscribe/Unsubscribe/Clear JButton (mbean notifications case) 81 private JButton clearButton, subscribeButton, unsubscribeButton; 82 // Reference to MBeans tab 83 private MBeansTab mbeansTab; 84 85 public XSheet(MBeansTab mbeansTab) { 86 this.mbeansTab = mbeansTab; 87 setupScreen(); 88 } 89 90 public void dispose() { 91 clear(); 92 XDataViewer.dispose(mbeansTab); 93 mbeanNotifications.dispose(); 94 } 95 96 private void setupScreen() { 97 setLayout(new BorderLayout()); 98 setBorder(BorderFactory.createLineBorder(Color.GRAY)); 99 // add main panel to XSheet 100 mainPanel = new JPanel(); 101 mainPanel.setLayout(new BorderLayout()); 102 add(mainPanel, BorderLayout.CENTER); 103 // add south panel to XSheet 104 southPanel = new JPanel(); 105 add(southPanel, BorderLayout.SOUTH); 106 // create the refresh button 107 refreshButton = new JButton(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON); 108 refreshButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON)); 109 refreshButton.setToolTipText(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP); 110 refreshButton.addActionListener(this); 111 // create the clear button 112 clearButton = new JButton(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON); 113 clearButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON)); 114 clearButton.setToolTipText(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP); 115 clearButton.addActionListener(this); 116 // create the subscribe button 117 subscribeButton = new JButton(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON); 118 subscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON)); 119 subscribeButton.setToolTipText(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP); 120 subscribeButton.addActionListener(this); 121 // create the unsubscribe button 122 unsubscribeButton = new JButton(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON); 123 unsubscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON)); 124 unsubscribeButton.setToolTipText(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP); 125 unsubscribeButton.addActionListener(this); 126 // create XMBeanAttributes container 127 mbeanAttributes = new XMBeanAttributes(mbeansTab); 128 // create XMBeanOperations container 129 mbeanOperations = new XMBeanOperations(mbeansTab); 130 mbeanOperations.addOperationsListener(this); 131 // create XMBeanNotifications container 132 mbeanNotifications = new XMBeanNotifications(); 133 mbeanNotifications.addNotificationsListener(this); 134 // create XMBeanInfo container 135 mbeanInfo = new XMBeanInfo(); 136 } 137 138 private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) { 139 return (cn == n); 140 } 141 142 // Call on EDT 143 private void showErrorDialog(Object message, String title) { 144 new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run(); 145 } 146 147 public boolean isMBeanNode(DefaultMutableTreeNode node) { 148 Object userObject = node.getUserObject(); 149 if (userObject instanceof XNodeInfo) { 150 XNodeInfo uo = (XNodeInfo) userObject; 151 return uo.getType().equals(Type.MBEAN); 152 } 153 return false; 154 } 155 156 // Call on EDT 157 public synchronized void displayNode(DefaultMutableTreeNode node) { 158 clear(); 159 displayEmptyNode(); 160 if (node == null) { 161 return; 162 } 163 currentNode = node; 164 Object userObject = node.getUserObject(); 165 if (userObject instanceof XNodeInfo) { 166 XNodeInfo uo = (XNodeInfo) userObject; 167 switch (uo.getType()) { 168 case MBEAN: 169 displayMBeanNode(node); 170 break; 171 case NONMBEAN: 172 displayEmptyNode(); 173 break; 174 case ATTRIBUTES: 175 displayMBeanAttributesNode(node); 176 break; 177 case OPERATIONS: 178 displayMBeanOperationsNode(node); 179 break; 180 case NOTIFICATIONS: 181 displayMBeanNotificationsNode(node); 182 break; 183 case ATTRIBUTE: 184 case OPERATION: 185 case NOTIFICATION: 186 displayMetadataNode(node); 187 break; 188 default: 189 displayEmptyNode(); 190 break; 191 } 192 } else { 193 displayEmptyNode(); 194 } 195 } 196 197 // Call on EDT 198 private void displayMBeanNode(final DefaultMutableTreeNode node) { 199 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 200 if (!uo.getType().equals(Type.MBEAN)) { 201 return; 202 } 203 mbean = (XMBean) uo.getData(); 204 SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() { 205 @Override 206 public MBeanInfo doInBackground() throws InstanceNotFoundException, 207 IntrospectionException, ReflectionException, IOException { 208 return mbean.getMBeanInfo(); 209 } 210 @Override 211 protected void done() { 212 try { 213 MBeanInfo mbi = get(); 214 if (mbi != null) { 215 if (!isSelectedNode(node, currentNode)) { 216 return; 217 } 218 mbeanInfo.addMBeanInfo(mbean, mbi); 219 invalidate(); 220 mainPanel.removeAll(); 221 mainPanel.add(mbeanInfo, BorderLayout.CENTER); 222 southPanel.setVisible(false); 223 southPanel.removeAll(); 224 validate(); 225 repaint(); 226 } 227 } catch (Exception e) { 228 Throwable t = Utils.getActualException(e); 229 if (JConsole.isDebug()) { 230 System.err.println("Couldn't get MBeanInfo for MBean [" + 231 mbean.getObjectName() + "]"); 232 t.printStackTrace(); 233 } 234 showErrorDialog(t.toString(), 235 Messages.PROBLEM_DISPLAYING_MBEAN); 236 } 237 } 238 }; 239 sw.execute(); 240 } 241 242 // Call on EDT 243 private void displayMetadataNode(final DefaultMutableTreeNode node) { 244 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 245 final XMBeanInfo mbi = mbeanInfo; 246 switch (uo.getType()) { 247 case ATTRIBUTE: 248 SwingWorker<MBeanAttributeInfo, Void> sw = 249 new SwingWorker<MBeanAttributeInfo, Void>() { 250 @Override 251 public MBeanAttributeInfo doInBackground() { 252 Object attrData = uo.getData(); 253 mbean = (XMBean) ((Object[]) attrData)[0]; 254 MBeanAttributeInfo mbai = 255 (MBeanAttributeInfo) ((Object[]) attrData)[1]; 256 mbeanAttributes.loadAttributes(mbean, new MBeanInfo( 257 null, null, new MBeanAttributeInfo[]{mbai}, 258 null, null, null)); 259 return mbai; 260 } 261 @Override 262 protected void done() { 263 try { 264 MBeanAttributeInfo mbai = get(); 265 if (!isSelectedNode(node, currentNode)) { 266 return; 267 } 268 invalidate(); 269 mainPanel.removeAll(); 270 JPanel attributePanel = 271 new JPanel(new BorderLayout()); 272 JPanel attributeBorderPanel = 273 new JPanel(new BorderLayout()); 274 attributeBorderPanel.setBorder( 275 BorderFactory.createTitledBorder( 276 Messages.ATTRIBUTE_VALUE)); 277 JPanel attributeValuePanel = 278 new JPanel(new BorderLayout()); 279 attributeValuePanel.setBorder( 280 LineBorder.createGrayLineBorder()); 281 attributeValuePanel.add(mbeanAttributes.getTableHeader(), 282 BorderLayout.PAGE_START); 283 attributeValuePanel.add(mbeanAttributes, 284 BorderLayout.CENTER); 285 attributeBorderPanel.add(attributeValuePanel, 286 BorderLayout.CENTER); 287 JPanel refreshButtonPanel = new JPanel(); 288 refreshButtonPanel.add(refreshButton); 289 attributeBorderPanel.add(refreshButtonPanel, 290 BorderLayout.SOUTH); 291 refreshButton.setEnabled(true); 292 attributePanel.add(attributeBorderPanel, 293 BorderLayout.NORTH); 294 mbi.addMBeanAttributeInfo(mbai); 295 attributePanel.add(mbi, BorderLayout.CENTER); 296 mainPanel.add(attributePanel, 297 BorderLayout.CENTER); 298 southPanel.setVisible(false); 299 southPanel.removeAll(); 300 validate(); 301 repaint(); 302 } catch (Exception e) { 303 Throwable t = Utils.getActualException(e); 304 if (JConsole.isDebug()) { 305 System.err.println("Problem displaying MBean " + 306 "attribute for MBean [" + 307 mbean.getObjectName() + "]"); 308 t.printStackTrace(); 309 } 310 showErrorDialog(t.toString(), 311 Messages.PROBLEM_DISPLAYING_MBEAN); 312 } 313 } 314 }; 315 sw.execute(); 316 break; 317 case OPERATION: 318 Object operData = uo.getData(); 319 mbean = (XMBean) ((Object[]) operData)[0]; 320 MBeanOperationInfo mboi = 321 (MBeanOperationInfo) ((Object[]) operData)[1]; 322 mbeanOperations.loadOperations(mbean, 323 new MBeanInfo(null, null, null, null, 324 new MBeanOperationInfo[]{mboi}, null)); 325 invalidate(); 326 mainPanel.removeAll(); 327 JPanel operationPanel = new JPanel(new BorderLayout()); 328 JPanel operationBorderPanel = new JPanel(new BorderLayout()); 329 operationBorderPanel.setBorder(BorderFactory.createTitledBorder( 330 Messages.OPERATION_INVOCATION)); 331 operationBorderPanel.add(new JScrollPane(mbeanOperations)); 332 operationPanel.add(operationBorderPanel, BorderLayout.NORTH); 333 mbi.addMBeanOperationInfo(mboi); 334 operationPanel.add(mbi, BorderLayout.CENTER); 335 mainPanel.add(operationPanel, BorderLayout.CENTER); 336 southPanel.setVisible(false); 337 southPanel.removeAll(); 338 validate(); 339 repaint(); 340 break; 341 case NOTIFICATION: 342 Object notifData = uo.getData(); 343 invalidate(); 344 mainPanel.removeAll(); 345 mbi.addMBeanNotificationInfo((MBeanNotificationInfo) notifData); 346 mainPanel.add(mbi, BorderLayout.CENTER); 347 southPanel.setVisible(false); 348 southPanel.removeAll(); 349 validate(); 350 repaint(); 351 break; 352 } 353 } 354 355 // Call on EDT 356 private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) { 357 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 358 if (!uo.getType().equals(Type.ATTRIBUTES)) { 359 return; 360 } 361 mbean = (XMBean) uo.getData(); 362 final XMBean xmb = mbean; 363 SwingWorker<MBeanInfo,Void> sw = new SwingWorker<MBeanInfo,Void>() { 364 @Override 365 public MBeanInfo doInBackground() throws InstanceNotFoundException, 366 IntrospectionException, ReflectionException, IOException { 367 MBeanInfo mbi = xmb.getMBeanInfo(); 368 return mbi; 369 } 370 @Override 371 protected void done() { 372 try { 373 MBeanInfo mbi = get(); 374 if (mbi != null && mbi.getAttributes() != null && 375 mbi.getAttributes().length > 0) { 376 377 mbeanAttributes.loadAttributes(xmb, mbi); 378 379 if (!isSelectedNode(node, currentNode)) { 380 return; 381 } 382 invalidate(); 383 mainPanel.removeAll(); 384 JPanel borderPanel = new JPanel(new BorderLayout()); 385 borderPanel.setBorder(BorderFactory.createTitledBorder( 386 Messages.ATTRIBUTE_VALUES)); 387 borderPanel.add(new JScrollPane(mbeanAttributes)); 388 mainPanel.add(borderPanel, BorderLayout.CENTER); 389 // add the refresh button to the south panel 390 southPanel.removeAll(); 391 southPanel.add(refreshButton, BorderLayout.SOUTH); 392 southPanel.setVisible(true); 393 refreshButton.setEnabled(true); 394 validate(); 395 repaint(); 396 } 397 } catch (Exception e) { 398 Throwable t = Utils.getActualException(e); 399 if (JConsole.isDebug()) { 400 System.err.println("Problem displaying MBean " + 401 "attributes for MBean [" + 402 mbean.getObjectName() + "]"); 403 t.printStackTrace(); 404 } 405 showErrorDialog(t.toString(), 406 Messages.PROBLEM_DISPLAYING_MBEAN); 407 } 408 } 409 }; 410 sw.execute(); 411 } 412 413 // Call on EDT 414 private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) { 415 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 416 if (!uo.getType().equals(Type.OPERATIONS)) { 417 return; 418 } 419 mbean = (XMBean) uo.getData(); 420 SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() { 421 @Override 422 public MBeanInfo doInBackground() throws InstanceNotFoundException, 423 IntrospectionException, ReflectionException, IOException { 424 return mbean.getMBeanInfo(); 425 } 426 @Override 427 protected void done() { 428 try { 429 MBeanInfo mbi = get(); 430 if (mbi != null) { 431 if (!isSelectedNode(node, currentNode)) { 432 return; 433 } 434 mbeanOperations.loadOperations(mbean, mbi); 435 invalidate(); 436 mainPanel.removeAll(); 437 JPanel borderPanel = new JPanel(new BorderLayout()); 438 borderPanel.setBorder(BorderFactory.createTitledBorder( 439 Messages.OPERATION_INVOCATION)); 440 borderPanel.add(new JScrollPane(mbeanOperations)); 441 mainPanel.add(borderPanel, BorderLayout.CENTER); 442 southPanel.setVisible(false); 443 southPanel.removeAll(); 444 validate(); 445 repaint(); 446 } 447 } catch (Exception e) { 448 Throwable t = Utils.getActualException(e); 449 if (JConsole.isDebug()) { 450 System.err.println("Problem displaying MBean " + 451 "operations for MBean [" + 452 mbean.getObjectName() + "]"); 453 t.printStackTrace(); 454 } 455 showErrorDialog(t.toString(), 456 Messages.PROBLEM_DISPLAYING_MBEAN); 457 } 458 } 459 }; 460 sw.execute(); 461 } 462 463 // Call on EDT 464 private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) { 465 final XNodeInfo uo = (XNodeInfo) node.getUserObject(); 466 if (!uo.getType().equals(Type.NOTIFICATIONS)) { 467 return; 468 } 469 mbean = (XMBean) uo.getData(); 470 mbeanNotifications.loadNotifications(mbean); 471 updateNotifications(); 472 invalidate(); 473 mainPanel.removeAll(); 474 JPanel borderPanel = new JPanel(new BorderLayout()); 475 borderPanel.setBorder(BorderFactory.createTitledBorder( 476 Messages.NOTIFICATION_BUFFER)); 477 borderPanel.add(new JScrollPane(mbeanNotifications)); 478 mainPanel.add(borderPanel, BorderLayout.CENTER); 479 // add the subscribe/unsubscribe/clear buttons to the south panel 480 southPanel.removeAll(); 481 southPanel.add(subscribeButton, BorderLayout.WEST); 482 southPanel.add(unsubscribeButton, BorderLayout.CENTER); 483 southPanel.add(clearButton, BorderLayout.EAST); 484 southPanel.setVisible(true); 485 subscribeButton.setEnabled(true); 486 unsubscribeButton.setEnabled(true); 487 clearButton.setEnabled(true); 488 validate(); 489 repaint(); 490 } 491 492 // Call on EDT 493 private void displayEmptyNode() { 494 invalidate(); 495 mainPanel.removeAll(); 496 southPanel.removeAll(); 497 validate(); 498 repaint(); 499 } 500 501 /** 502 * Subscribe button action. 503 */ 504 private void registerListener() { 505 new SwingWorker<Void, Void>() { 506 @Override 507 public Void doInBackground() 508 throws InstanceNotFoundException, IOException { 509 mbeanNotifications.registerListener(currentNode); 510 return null; 511 } 512 @Override 513 protected void done() { 514 try { 515 get(); 516 updateNotifications(); 517 validate(); 518 } catch (Exception e) { 519 Throwable t = Utils.getActualException(e); 520 if (JConsole.isDebug()) { 521 System.err.println("Problem adding listener"); 522 t.printStackTrace(); 523 } 524 showErrorDialog(t.getMessage(), 525 Messages.PROBLEM_ADDING_LISTENER); 526 } 527 } 528 }.execute(); 529 } 530 531 /** 532 * Unsubscribe button action. 533 */ 534 private void unregisterListener() { 535 new SwingWorker<Boolean, Void>() { 536 @Override 537 public Boolean doInBackground() { 538 return mbeanNotifications.unregisterListener(currentNode); 539 } 540 @Override 541 protected void done() { 542 try { 543 if (get()) { 544 updateNotifications(); 545 validate(); 546 } 547 } catch (Exception e) { 548 Throwable t = Utils.getActualException(e); 549 if (JConsole.isDebug()) { 550 System.err.println("Problem removing listener"); 551 t.printStackTrace(); 552 } 553 showErrorDialog(t.getMessage(), 554 Messages.PROBLEM_REMOVING_LISTENER); 555 } 556 } 557 }.execute(); 558 } 559 560 /** 561 * Refresh button action. 562 */ 563 private void refreshAttributes() { 564 mbeanAttributes.refreshAttributes(); 565 } 566 567 // Call on EDT 568 private void updateNotifications() { 569 if (mbeanNotifications.isListenerRegistered(mbean)) { 570 long received = mbeanNotifications.getReceivedNotifications(mbean); 571 updateReceivedNotifications(currentNode, received, false); 572 } else { 573 clearNotifications(); 574 } 575 } 576 577 /** 578 * Update notification node label in MBean tree: "Notifications[received]". 579 */ 580 // Call on EDT 581 private void updateReceivedNotifications( 582 DefaultMutableTreeNode emitter, long received, boolean bold) { 583 String text = Messages.NOTIFICATIONS + "[" + received + "]"; 584 DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent(); 585 if (bold && emitter != selectedNode) { 586 text = "<html><b>" + text + "</b></html>"; 587 } 588 updateNotificationsNodeLabel(emitter, text); 589 } 590 591 /** 592 * Update notification node label in MBean tree: "Notifications". 593 */ 594 // Call on EDT 595 private void clearNotifications() { 596 updateNotificationsNodeLabel(currentNode, 597 Messages.NOTIFICATIONS); 598 } 599 600 /** 601 * Update notification node label in MBean tree: "Notifications[0]". 602 */ 603 // Call on EDT 604 private void clearNotifications0() { 605 updateNotificationsNodeLabel(currentNode, 606 Messages.NOTIFICATIONS + "[0]"); 607 } 608 609 /** 610 * Update the label of the supplied MBean tree node. 611 */ 612 // Call on EDT 613 private void updateNotificationsNodeLabel( 614 DefaultMutableTreeNode node, String label) { 615 synchronized (mbeansTab.getTree()) { 616 invalidate(); 617 XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject(); 618 XNodeInfo newUserObject = new XNodeInfo( 619 oldUserObject.getType(), oldUserObject.getData(), 620 label, oldUserObject.getToolTipText()); 621 node.setUserObject(newUserObject); 622 DefaultTreeModel model = 623 (DefaultTreeModel) mbeansTab.getTree().getModel(); 624 model.nodeChanged(node); 625 validate(); 626 repaint(); 627 } 628 } 629 630 /** 631 * Clear button action. 632 */ 633 // Call on EDT 634 private void clearCurrentNotifications() { 635 mbeanNotifications.clearCurrentNotifications(); 636 if (mbeanNotifications.isListenerRegistered(mbean)) { 637 // Update notifs in MBean tree "Notifications[0]". 638 // 639 // Notification buffer has been cleared with a listener been 640 // registered so add "[0]" at the end of the node label. 641 // 642 clearNotifications0(); 643 } else { 644 // Update notifs in MBean tree "Notifications". 645 // 646 // Notification buffer has been cleared without a listener been 647 // registered so don't add "[0]" at the end of the node label. 648 // 649 clearNotifications(); 650 } 651 } 652 653 // Call on EDT 654 private void clear() { 655 mbeanAttributes.stopCellEditing(); 656 mbeanAttributes.emptyTable(); 657 mbeanAttributes.removeAttributes(); 658 mbeanOperations.removeOperations(); 659 mbeanNotifications.stopCellEditing(); 660 mbeanNotifications.emptyTable(); 661 mbeanNotifications.disableNotifications(); 662 mbean = null; 663 currentNode = null; 664 } 665 666 /** 667 * Notification listener: handles asynchronous reception 668 * of MBean operation results and MBean notifications. 669 */ 670 // Call on EDT 671 public void handleNotification(Notification e, Object handback) { 672 // Operation result 673 if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) { 674 final Object message; 675 if (handback == null) { 676 JTextArea textArea = new JTextArea("null"); 677 textArea.setEditable(false); 678 textArea.setEnabled(true); 679 textArea.setRows(textArea.getLineCount()); 680 message = textArea; 681 } else { 682 Component comp = mbeansTab.getDataViewer(). 683 createOperationViewer(handback, mbean); 684 if (comp == null) { 685 JTextArea textArea = new JTextArea(handback.toString()); 686 textArea.setEditable(false); 687 textArea.setEnabled(true); 688 textArea.setRows(textArea.getLineCount()); 689 JScrollPane scrollPane = new JScrollPane(textArea); 690 Dimension d = scrollPane.getPreferredSize(); 691 if (d.getWidth() > 400 || d.getHeight() > 250) { 692 scrollPane.setPreferredSize(new Dimension(400, 250)); 693 } 694 message = scrollPane; 695 } else { 696 if (!(comp instanceof JScrollPane)) { 697 comp = new JScrollPane(comp); 698 } 699 Dimension d = comp.getPreferredSize(); 700 if (d.getWidth() > 400 || d.getHeight() > 250) { 701 comp.setPreferredSize(new Dimension(400, 250)); 702 } 703 message = comp; 704 } 705 } 706 new ThreadDialog( 707 (Component) e.getSource(), 708 message, 709 Messages.OPERATION_RETURN_VALUE, 710 JOptionPane.INFORMATION_MESSAGE).run(); 711 } // Got notification 712 else if (e.getType().equals( 713 XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) { 714 DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback; 715 Long received = (Long) e.getUserData(); 716 updateReceivedNotifications(emitter, received.longValue(), true); 717 } 718 } 719 720 /** 721 * Action listener: handles actions in panel buttons 722 */ 723 // Call on EDT 724 public void actionPerformed(ActionEvent e) { 725 if (e.getSource() instanceof JButton) { 726 JButton button = (JButton) e.getSource(); 727 // Refresh button 728 if (button == refreshButton) { 729 refreshAttributes(); 730 return; 731 } 732 // Clear button 733 if (button == clearButton) { 734 clearCurrentNotifications(); 735 return; 736 } 737 // Subscribe button 738 if (button == subscribeButton) { 739 registerListener(); 740 return; 741 } 742 // Unsubscribe button 743 if (button == unsubscribeButton) { 744 unregisterListener(); 745 return; 746 } 747 } 748 } 749} 750