714 lines · 23.1 KB · Java
RawDownload
/* * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.tools.jconsole.inspector; import javax.swing.*;import javax.swing.event.*;import javax.swing.table.*;import javax.swing.tree.*;import java.awt.Font; import java.text.SimpleDateFormat; import java.awt.Component;import java.awt.EventQueue;import java.awt.event.*;import java.awt.Dimension;import java.util.*;import java.io.*;import java.lang.reflect.Array; import javax.management.*;import javax.management.openmbean.CompositeData;import javax.management.openmbean.TabularData; import sun.tools.jconsole.JConsole;import sun.tools.jconsole.Resources; @SuppressWarnings("serial")public class XMBeanNotifications extends JTable implements NotificationListener {     private final static String[] columnNames = {        Resources.getText("TimeStamp"),        Resources.getText("Type"),        Resources.getText("UserData"),        Resources.getText("SeqNum"),        Resources.getText("Message"),        Resources.getText("Event"),        Resources.getText("Source")    };    private HashMap<ObjectName, XMBeanNotificationsListener> listeners =            new HashMap<ObjectName, XMBeanNotificationsListener>();    private volatile boolean subscribed;    private XMBeanNotificationsListener currentListener;    public final static String NOTIFICATION_RECEIVED_EVENT =            "jconsole.xnotification.received";    private List<NotificationListener> notificationListenersList;    private volatile boolean enabled;    private Font normalFont,  boldFont;    private int rowMinHeight = -1;    private TableCellEditor userDataEditor = new UserDataCellEditor();    private NotifMouseListener mouseListener = new NotifMouseListener();    private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS");    private static TableCellEditor editor =            new Utils.ReadOnlyTableCellEditor(new JTextField());     public XMBeanNotifications() {        super(new TableSorter(columnNames, 0));        setColumnSelectionAllowed(false);        setRowSelectionAllowed(false);        getTableHeader().setReorderingAllowed(false);        ArrayList<NotificationListener> l =                new ArrayList<NotificationListener>(1);        notificationListenersList = Collections.synchronizedList(l);         addMouseListener(mouseListener);         TableColumnModel colModel = getColumnModel();        colModel.getColumn(0).setPreferredWidth(45);        colModel.getColumn(1).setPreferredWidth(50);        colModel.getColumn(2).setPreferredWidth(50);        colModel.getColumn(3).setPreferredWidth(40);        colModel.getColumn(4).setPreferredWidth(50);        colModel.getColumn(5).setPreferredWidth(50);        setColumnEditors();        addKeyListener(new Utils.CopyKeyAdapter());    }     // Call on EDT    public void cancelCellEditing() {        TableCellEditor tce = getCellEditor();        if (tce != null) {            tce.cancelCellEditing();        }    }     // Call on EDT    public void stopCellEditing() {        TableCellEditor tce = getCellEditor();        if (tce != null) {            tce.stopCellEditing();        }    }     // Call on EDT    @Override    public boolean isCellEditable(int row, int col) {        UserDataCell cell = getUserDataCell(row, col);        if (cell != null) {            return cell.isMaximized();        }        return true;    }     // Call on EDT    @Override    public void setValueAt(Object value, int row, int column) {    }     // Call on EDT    @Override    public synchronized Component prepareRenderer(            TableCellRenderer renderer, int row, int column) {        //In case we have a repaint thread that is in the process of        //repainting an obsolete table, just ignore the call.        //It can happen when MBean selection is switched at a very quick rate        if (row >= getRowCount()) {            return null;        }         Component comp = super.prepareRenderer(renderer, row, column);         if (normalFont == null) {            normalFont = comp.getFont();            boldFont = normalFont.deriveFont(Font.BOLD);        }        UserDataCell cell = getUserDataCell(row, 2);        if (column == 2 && cell != null) {            comp.setFont(boldFont);            int size = cell.getHeight();            if (size > 0) {                if (getRowHeight(row) != size) {                    setRowHeight(row, size);                }            }        } else {            comp.setFont(normalFont);        }         return comp;    }     // Call on EDT    @Override    public synchronized TableCellRenderer getCellRenderer(int row, int column) {        //In case we have a repaint thread that is in the process of        //repainting an obsolete table, just ignore the call.        //It can happen when MBean selection is switched at a very quick rate        if (row >= getRowCount()) {            return null;        }         DefaultTableCellRenderer renderer;        String toolTip = null;        UserDataCell cell = getUserDataCell(row, column);        if (cell != null && cell.isInited()) {            renderer = (DefaultTableCellRenderer) cell.getRenderer();        } else {            renderer =                    (DefaultTableCellRenderer) super.getCellRenderer(row, column);        }         if (cell != null) {            toolTip = Resources.getText("Double click to expand/collapse") +                    ". " + cell.toString();        } else {            Object val =                    ((DefaultTableModel) getModel()).getValueAt(row, column);            if (val != null) {                toolTip = val.toString();            }        }         renderer.setToolTipText(toolTip);         return renderer;    }     // Call on EDT    private UserDataCell getUserDataCell(int row, int column) {        Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column);        if (obj instanceof UserDataCell) {            return (UserDataCell) obj;        }        return null;    }     synchronized void dispose() {        listeners.clear();    }     public long getReceivedNotifications(XMBean mbean) {        XMBeanNotificationsListener listener =                listeners.get(mbean.getObjectName());        if (listener == null) {            return 0;        } else {            return listener.getReceivedNotifications();        }    }     public synchronized boolean clearCurrentNotifications() {        emptyTable();        if (currentListener != null) {            currentListener.clear();            return true;        } else {            return false;        }    }     public synchronized boolean unregisterListener(DefaultMutableTreeNode node) {        XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();        return unregister(mbean.getObjectName());    }     public synchronized void registerListener(DefaultMutableTreeNode node)            throws InstanceNotFoundException, IOException {        XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();        if (!subscribed) {            try {                mbean.getMBeanServerConnection().addNotificationListener(                        MBeanServerDelegate.DELEGATE_NAME, this, null, null);                subscribed = true;            } catch (Exception e) {                if (JConsole.isDebug()) {                    System.err.println("Error adding listener for delegate:");                    e.printStackTrace();                }            }        }        XMBeanNotificationsListener listener =                listeners.get(mbean.getObjectName());        if (listener == null) {            listener = new XMBeanNotificationsListener(                    this, mbean, node, columnNames);            listeners.put(mbean.getObjectName(), listener);        } else {            if (!listener.isRegistered()) {                emptyTable();                listener.register(node);            }        }        enabled = true;        currentListener = listener;    }     public synchronized void handleNotification(            Notification notif, Object handback) {        try {            if (notif instanceof MBeanServerNotification) {                ObjectName mbean =                        ((MBeanServerNotification) notif).getMBeanName();                if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) {                    unregister(mbean);                }            }        } catch (Exception e) {            if (JConsole.isDebug()) {                System.err.println("Error unregistering notification:");                e.printStackTrace();            }        }    }     public synchronized void disableNotifications() {        emptyTable();        currentListener = null;        enabled = false;    }     private synchronized boolean unregister(ObjectName mbean) {        XMBeanNotificationsListener listener = listeners.get(mbean);        if (listener != null && listener.isRegistered()) {            listener.unregister();            return true;        } else {            return false;        }    }     public void addNotificationsListener(NotificationListener nl) {        notificationListenersList.add(nl);    }     public void removeNotificationsListener(NotificationListener nl) {        notificationListenersList.remove(nl);    }     // Call on EDT    void fireNotificationReceived(            XMBeanNotificationsListener listener, XMBean mbean,            DefaultMutableTreeNode node, Object[] rowData, long received) {        if (enabled) {            DefaultTableModel tableModel = (DefaultTableModel) getModel();            if (listener == currentListener) {                tableModel.insertRow(0, rowData);                repaint();            }        }        Notification notif =                new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0);        notif.setUserData(received);        for (NotificationListener nl : notificationListenersList) {            nl.handleNotification(notif, node);        }    }     // Call on EDT    private void updateModel(List<Object[]> data) {        emptyTable();        DefaultTableModel tableModel = (DefaultTableModel) getModel();        for (Object[] rowData : data) {            tableModel.addRow(rowData);        }    }     public synchronized boolean isListenerRegistered(XMBean mbean) {        XMBeanNotificationsListener listener =                listeners.get(mbean.getObjectName());        if (listener == null) {            return false;        }        return listener.isRegistered();    }     // Call on EDT    public synchronized void loadNotifications(XMBean mbean) {        XMBeanNotificationsListener listener =                listeners.get(mbean.getObjectName());        emptyTable();        if (listener != null) {            enabled = true;            List<Object[]> data = listener.getData();            updateModel(data);            currentListener = listener;            validate();            repaint();        } else {            enabled = false;        }    }     // Call on EDT    private void setColumnEditors() {        TableColumnModel tcm = getColumnModel();        for (int i = 0; i < columnNames.length; i++) {            TableColumn tc = tcm.getColumn(i);            if (i == 2) {                tc.setCellEditor(userDataEditor);            } else {                tc.setCellEditor(editor);            }        }    }     // Call on EDT    public boolean isTableEditable() {        return true;    }     // Call on EDT    public synchronized void emptyTable() {        DefaultTableModel model = (DefaultTableModel) getModel();        //invalidate();        while (model.getRowCount() > 0) {            model.removeRow(0);        }        validate();    }     // Call on EDT    synchronized void updateUserDataCell(int row, int col) {        Object obj = getModel().getValueAt(row, 2);        if (obj instanceof UserDataCell) {            UserDataCell cell = (UserDataCell) obj;            if (!cell.isInited()) {                if (rowMinHeight == -1) {                    rowMinHeight = getRowHeight(row);                }                cell.init(super.getCellRenderer(row, col), rowMinHeight);            }             cell.switchState();            setRowHeight(row, cell.getHeight());             if (!cell.isMaximized()) {                cancelCellEditing();                //Back to simple editor.                editCellAt(row, 2);            }             invalidate();            repaint();        }    }     class UserDataCellRenderer extends DefaultTableCellRenderer {         Component comp;         UserDataCellRenderer(Component comp) {            this.comp = comp;            Dimension d = comp.getPreferredSize();            if (d.getHeight() > 200) {                comp.setPreferredSize(new Dimension((int) d.getWidth(), 200));            }        }         @Override        public Component getTableCellRendererComponent(                JTable table,                Object value,                boolean isSelected,                boolean hasFocus,                int row,                int column) {            return comp;        }         public Component getComponent() {            return comp;        }    }     class UserDataCell {         TableCellRenderer minRenderer;        UserDataCellRenderer maxRenderer;        int minHeight;        boolean minimized = true;        boolean init = false;        Object userData;         UserDataCell(Object userData, Component max) {            this.userData = userData;            this.maxRenderer = new UserDataCellRenderer(max);         }         @Override        public String toString() {            if (userData == null) {                return null;            }            if (userData.getClass().isArray()) {                String name =                        Utils.getArrayClassName(userData.getClass().getName());                int length = Array.getLength(userData);                return name + "[" + length + "]";            }             if (userData instanceof CompositeData ||                    userData instanceof TabularData) {                return userData.getClass().getName();            }             return userData.toString();        }         boolean isInited() {            return init;        }         void init(TableCellRenderer minRenderer, int minHeight) {            this.minRenderer = minRenderer;            this.minHeight = minHeight;            init = true;        }         void switchState() {            minimized = !minimized;        }         boolean isMaximized() {            return !minimized;        } 

Lines 1–500 of 714.