1 /*
   2  * Copyright (c) 2004, 2006, 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 package sun.tools.jconsole.inspector;
  26 
  27 import java.awt.*;
  28 import java.awt.event.*;
  29 import java.io.*;
  30 import java.util.*;
  31 import java.util.Timer;
  32 
  33 import javax.management.*;
  34 import javax.swing.*;
  35 import javax.swing.border.*;
  36 import javax.swing.event.*;
  37 
  38 import sun.tools.jconsole.*;
  39 
  40 @SuppressWarnings("serial")
  41 public class XPlottingViewer extends PlotterPanel implements ActionListener {
  42     // TODO: Make number of decimal places customizable
  43     private static final int PLOTTER_DECIMALS = 4;
  44 
  45     private JButton plotButton;
  46     // The plotter cache holds Plotter instances for the various attributes
  47     private static HashMap<String, XPlottingViewer> plotterCache =
  48         new HashMap<String, XPlottingViewer>();
  49      private static HashMap<String, Timer> timerCache =
  50          new HashMap<String, Timer>();
  51     private JPanel bordered;
  52     private Number value;
  53     private MBeansTab tab;
  54     private XMBean mbean;
  55     private String attributeName;
  56     private String key;
  57     private JTable table;
  58     private XPlottingViewer(String key,
  59                             XMBean mbean,
  60                             String attributeName,
  61                             Object value,
  62                             JTable table,
  63                             MBeansTab tab) {
  64         super(null);
  65 
  66         this.tab = tab;
  67         this.key = key;
  68         this.mbean = mbean;
  69         this.table = table;
  70         this.attributeName = attributeName;
  71         Plotter plotter = createPlotter(mbean, attributeName, key, table);
  72         setupDisplay(plotter);
  73     }
  74 
  75     static void dispose(MBeansTab tab) {
  76         Iterator it = plotterCache.keySet().iterator();
  77         while(it.hasNext()) {
  78             String key = (String) it.next();
  79             if(key.startsWith(String.valueOf(tab.hashCode()))) {
  80                 it.remove();
  81             }
  82         }
  83         //plotterCache.clear();
  84         it = timerCache.keySet().iterator();
  85         while(it.hasNext()) {
  86             String key = (String) it.next();
  87             if(key.startsWith(String.valueOf(tab.hashCode()))) {
  88                 Timer t = timerCache.get(key);
  89                 t.cancel();
  90                 it.remove();
  91             }
  92         }
  93     }
  94 
  95     public static boolean isViewableValue(Object value) {
  96         return (value instanceof Number);
  97     }
  98 
  99     //Fired by dbl click
 100     public  static Component loadPlotting(XMBean mbean,
 101                                           String attributeName,
 102                                           Object value,
 103                                           JTable table,
 104                                           MBeansTab tab) {
 105         Component comp = null;
 106         if(isViewableValue(value)) {
 107             String key = String.valueOf(tab.hashCode()) + " " + String.valueOf(mbean.hashCode()) + " " + mbean.getObjectName().getCanonicalName() + attributeName;
 108             XPlottingViewer plotter = plotterCache.get(key);
 109             if(plotter == null) {
 110                 plotter = new XPlottingViewer(key,
 111                                               mbean,
 112                                               attributeName,
 113                                               value,
 114                                               table,
 115                                               tab);
 116                 plotterCache.put(key, plotter);
 117             }
 118 
 119             comp = plotter;
 120         }
 121         return comp;
 122     }
 123 
 124     /*public void paintComponent(Graphics g) {
 125         super.paintComponent(g);
 126         setBackground(g.getColor());
 127         plotter.paintComponent(g);
 128         }*/
 129     public void actionPerformed(ActionEvent evt) {
 130         plotterCache.remove(key);
 131         Timer t = timerCache.remove(key);
 132         t.cancel();
 133         ((XMBeanAttributes) table).collapse(attributeName, this);
 134     }
 135 
 136     //Create plotter instance
 137     public Plotter createPlotter(final XMBean xmbean,
 138                                  final String attributeName,
 139                                  String key,
 140                                  JTable table) {
 141         final Plotter plotter = new XPlotter(table, Plotter.Unit.NONE) {
 142                 Dimension prefSize = new Dimension(400, 170);
 143                 public Dimension getPreferredSize() {
 144                     return prefSize;
 145                 }
 146                 public Dimension getMinimumSize() {
 147                     return prefSize;
 148                 }
 149             };
 150 
 151         plotter.createSequence(attributeName, attributeName, null, true);
 152 
 153         TimerTask timerTask = new TimerTask() {
 154                 public void run() {
 155                     tab.workerAdd(new Runnable() {
 156                             public void run() {
 157                                 try {
 158                                     Number n =
 159                                         (Number) xmbean.getMBeanServerConnection().getAttribute(xmbean.getObjectName(), attributeName);
 160                                     long v;
 161                                     if (n instanceof Float || n instanceof Double) {
 162                                         plotter.setDecimals(PLOTTER_DECIMALS);
 163                                         double d = (n instanceof Float) ? (Float)n : (Double)n;
 164                                         v = Math.round(d * Math.pow(10.0, PLOTTER_DECIMALS));
 165                                     } else {
 166                                         v = n.longValue();
 167                                     }
 168                                     plotter.addValues(System.currentTimeMillis(), v);
 169                                 } catch (Exception ex) {
 170                                     // Should have a trace logged with proper
 171                                     // trace mecchanism
 172                                 }
 173                             }
 174                         });
 175                 }
 176             };
 177 
 178         String timerName = "Timer-" + key;
 179         Timer timer = new Timer(timerName, true);
 180         timer.schedule(timerTask, 0, tab.getUpdateInterval());
 181         timerCache.put(key, timer);
 182         return plotter;
 183     }
 184 
 185     //Create Plotter display
 186     private void setupDisplay(Plotter plotter) {
 187         //setLayout(new GridLayout(2,0));
 188         GridBagLayout gbl = new GridBagLayout();
 189         setLayout(gbl);
 190         plotButton = new JButton(Resources.getText("Discard chart"));
 191         plotButton.addActionListener(this);
 192         plotButton.setEnabled(true);
 193 
 194         // Add the display to the top four cells
 195         GridBagConstraints buttonConstraints = new GridBagConstraints();
 196         buttonConstraints.gridx = 0;
 197         buttonConstraints.gridy = 0;
 198         buttonConstraints.fill = GridBagConstraints.VERTICAL;
 199         buttonConstraints.anchor = GridBagConstraints.CENTER;
 200         gbl.setConstraints(plotButton, buttonConstraints);
 201         add(plotButton);
 202 
 203         GridBagConstraints plotterConstraints = new GridBagConstraints();
 204         plotterConstraints.gridx = 0;
 205         plotterConstraints.gridy = 1;
 206         plotterConstraints.weightx = 1;
 207         //plotterConstraints.gridwidth = (int) plotter.getPreferredSize().getWidth();
 208         //plotterConstraints.gridheight =  (int) plotter.getPreferredSize().getHeight();
 209         plotterConstraints.fill = GridBagConstraints.VERTICAL;
 210         gbl.setConstraints(plotter, plotterConstraints);
 211 
 212 
 213         //bordered = new JPanel();
 214         //bordered.setPreferredSize(new Dimension(400, 250));
 215         //bordered.add(plotButton);
 216         //bordered.add(plotter);
 217 
 218         //add(bordered);
 219 
 220         setPlotter(plotter);
 221         repaint();
 222     }
 223 
 224 }