Package org.rioproject.watch

Source Code of org.rioproject.watch.AccumulatorViewer$AVTreeCellRenderer

/*
* Copyright 2008 the original author or authors.
* Copyright 2005 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.rioproject.watch;

import net.jini.core.lookup.ServiceItem;
import org.rioproject.ui.GlassPaneContainer;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.net.URL;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* Accumulator Viewer
*/
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
public class AccumulatorViewer extends JPanel implements TreeSelectionListener {
    static final long serialVersionUID = 1L;
    private Watchable service;
    private WatchDataSource[] watchDataSources;
    private CalculableViewable defaultDataView = new DefaultCalculableView();
    private CalculableViewable dataView = defaultDataView;
    private JTree tree;
    private DefaultMutableTreeNode  root= new DefaultMutableTreeNode("Watches");
    private JComponent graphPanel;
    boolean paintFlag = false;
    private ClassLoader loader;
    private javax.swing.Timer autoRefresh;
    private GlassPaneContainer glassPane;
    private CalculableViewable.PlottedCalculable mouseOverValue = null;
    //private final static Color fillBoxColor = new Color(110, 206, 227);
    private final static Color fillBoxColor = new Color(255, 255, 204);
    private NumberFormat numberFormatter = NumberFormat.getInstance();
    private DateFormat dateFormat;
    private Point lastMousePoint;
    private boolean autoRefreshMode = true;
   
    /**
     * Creates new form AccumulatorViewer
     *
     * @param item the service proxy
     *
     * @throws Exception If communication errors happen interfacing with
     * the WatchDataSource
     */
    public AccumulatorViewer(Object item) throws Exception {
        super();
        loader = getClass().getClassLoader();
        getAccessibleContext().setAccessibleName("Watchable Viewer");
        if(((ServiceItem)item).service instanceof Watchable) {
            setService((Watchable)((ServiceItem)item).service);
        }
        initComponents();
    }

    /**
     * Accessor for property service
     *
     * @return Value of property service.
     */
    public Remote getService() {
        return(service);
    }

    /**
     * Mutator for property service.
     *
     * @param service New value of property services.
     *
     * @throws RemoteException If communication errors happen interfacing with
     * the WatchDataSource
     */
    public void setService(Watchable service) throws RemoteException {
        this.service = service;
        if(this.service != null) {
            watchDataSources = this.service.fetch();
            if(watchDataSources == null)
                return;
            if(watchDataSources.length > 0) {
                int wdsNbr = watchDataSources.length;
                String[] wdsIDs = new String[wdsNbr];
                for(int i = 0; i < watchDataSources.length; i++) {
                    wdsIDs[i] = watchDataSources[i].getID();
                }
                setTreeWDSNodes(wdsIDs);
            }
        }
    }

    private void initComponents() {
        numberFormatter.setMinimumFractionDigits(1);
        numberFormatter.setMaximumFractionDigits(3);
        dateFormat = new SimpleDateFormat("MM/dd/yy hh:mm:ss aa");
        setLayout(new BorderLayout());
        setUI(this);

        graphPanel = createGraphPanel();
        glassPane = createGlassPane(graphPanel);
        //glassPane.setVisible(true);
        glassPane.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseExited(MouseEvent event) {
                mouseOverValue = null;
                lastMousePoint = null;
                glassPane.repaint();
            }
        });
        glassPane.addMouseMotionListener(new MouseMotionAdapter() {           
            @Override
            public void mouseMoved(MouseEvent event) {
                lastMousePoint = event.getPoint();
                mouseOverValue = dataView.getCalcForPoint(lastMousePoint);
                if(mouseOverValue!=null) {
                    glassPane.repaint();
                }
            }
        });

        JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                                                  createTreePanel(),
                                                  glassPane);
        mainSplitPane.setDividerSize(2);
        mainSplitPane.setContinuousLayout(true);
        mainSplitPane.setDividerLocation(100);

        add(BorderLayout.CENTER, mainSplitPane);
        autoRefresh =
            new javax.swing.Timer(
                5*1000,
                new ActionListener() {
                    public void actionPerformed(ActionEvent evt) {
                        try {
                            if(!autoRefreshMode)
                                return;
                            runAccumulator();
                            if(lastMousePoint!=null) {
                                mouseOverValue =
                                    dataView.getCalcForPoint(lastMousePoint);
                                glassPane.repaint();
                            }
                        } catch(RemoteException e) {
                            e.printStackTrace();
                            autoRefresh.stop();
                        }
                    }
                });
    }

    public void removeNotify() {
        if(autoRefresh != null && autoRefresh.isRunning()) {
            autoRefresh.stop();
        }
        super.removeNotify();
    }

    public void addNotify() {
        super.addNotify();
        if(autoRefresh != null) {
            if(isVisible() && !autoRefresh.isRunning()) {
                autoRefresh.start();
            }
        }
    }

    public void setVisible(boolean flag) {
        if(autoRefresh != null) {
            if(flag && !autoRefresh.isRunning())
                autoRefresh.start();
            else if(autoRefresh.isRunning())
                autoRefresh.stop();
        }
        super.setVisible(flag);
    }


    private void setUI(Component component) {
        try {
            UIManager.setLookAndFeel(UIManager.getLookAndFeel());
            UIManager.put("Label.foreground", Color.black);
            UIManager.put("TitledBorder.titleColor", Color.black);
            SwingUtilities.updateComponentTreeUI(component);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private ImageIcon getScaledImageIcon(String location, int width, int height) {
        ImageIcon icon = null;
        URL url = this.getClass().getClassLoader().getResource(location);
        if (url != null) {
            icon = new ImageIcon(url);
            icon = new ImageIcon(icon.getImage().getScaledInstance(width,
                                                                   height,
                                                                   Image.SCALE_SMOOTH));
        }
        return (icon);
    }

    private JComponent createTreePanel() {
        JPanel panel = new JPanel(new BorderLayout(0,0));
        tree = new JTree(root);
        tree.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        tree.setBackground(new Color(202,202,202));
        tree.setForeground(Color.green);
        tree.setRowHeight(-1);
        tree.addTreeSelectionListener(this);
        tree.setCellRenderer(new AVTreeCellRenderer());

        JPanel bPanel = new JPanel();
        bPanel.setLayout(new BoxLayout(bPanel, BoxLayout.X_AXIS));
        final ImageIcon playIcon = getScaledImageIcon("images/Play24.gif", 16, 16);
        final ImageIcon pauseIcon = getScaledImageIcon("images/Pause24.gif", 16, 16);
        final JButton playPause = new JButton(pauseIcon);
        playPause.setToolTipText("Stop auto feed");
        playPause.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if(autoRefreshMode) {
                    playPause.setIcon(playIcon);
                    autoRefreshMode = false;
                    playPause.setToolTipText("Enable auto feed");
                } else {
                    playPause.setIcon(pauseIcon);
                    autoRefreshMode = true;
                    playPause.setToolTipText("Stop auto feed");
                }
            }
        });
        JButton refreshB = new JButton("Refresh");
        refreshB.setToolTipText("Refresh Watch Data Source Graph");
        refreshB.addActionListener(new ActionListener() {
                                       public void actionPerformed(ActionEvent evt) {
                                           try {
                                               runAccumulator();
                                           } catch(Exception e) {
                                               e.printStackTrace();
                                           }
                                       }
                                   });
        JButton resetB = new JButton("Reset");
        resetB.setToolTipText("Reset Watches");
        resetB.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    try {
                        getWatches();
                    } catch(RemoteException re) {
                        Toolkit.getDefaultToolkit().beep();
                        JOptionPane.showMessageDialog(null,
                                                      "Cannot reset watches\n" +
                                                      "RemoteException: "+
                                                      re.getLocalizedMessage(),
                                                      "Reset Watch Remote Error",
                                                      JOptionPane.ERROR_MESSAGE);


                    }
                }
            });

        JButton clearB = new JButton("Clear");
        clearB.setToolTipText("Clear all entries in the WatchDataSource");
        clearB.addActionListener(new ActionListener() {
                                     public void actionPerformed(ActionEvent evt) {
                                         clearWatch();
                                     }
                                 });
        bPanel.add(playPause);
        bPanel.add(refreshB);
        bPanel.add(resetB);
        bPanel.add(clearB);
        panel.add(BorderLayout.CENTER, /*sp*/tree);
        panel.add(BorderLayout.SOUTH, bPanel);
        JScrollPane sp = new JScrollPane();
        sp.getViewport().add(panel);
        return(sp);
    }

    public void valueChanged(TreeSelectionEvent evt) {
        try {
            runAccumulator();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void getWatches() throws RemoteException {
        root.removeAllChildren();
        setService(service);
        ((DefaultTreeModel)tree.getModel()).nodeStructureChanged(root);
        tree.repaint();
    }

    private void clearWatch() {
        int[] selRows = tree.getSelectionRows();
        if(selRows == null || selRows.length == 0 || selRows[0] == 0)
            return;
        int wdsIdx = selRows[0] - 1;
        try {
            watchDataSources[wdsIdx].clear();
            runAccumulator();
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }
   
    private void runAccumulator() throws RemoteException {
        int[] selRows = tree.getSelectionRows();
        if(selRows == null || selRows.length == 0 || selRows[0] == 0)
            return;
        int wdsIdx = selRows[0] - 1;
        // assuming we only have one here, future enhancement would build the views
        // in the JTree and let the user select the view to see.
        dataView = defaultDataView;
        String view = watchDataSources[wdsIdx].getView();
        if(view != null) {
            try {
                dataView = loadView(view);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        dataView.setWatchDataSource(watchDataSources[wdsIdx]);
        graphPanel.repaint();
    }

    private void setTreeWDSNodes(String[] wdsNames) {
        for (String wdsName : wdsNames)
            root.add(new DefaultMutableTreeNode(wdsName));
        //tree.repaint();
    }

    static class AVTreeCellRenderer extends JLabel implements TreeCellRenderer {
        final Color SelectedBackgroundColor = Color.yellow;//new Color(0, 0, 128);
        protected boolean selected;
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                                                      boolean selected, boolean expanded,
                                                      boolean leaf, int row, boolean hasFocus) {
            String stringValue = tree.convertValueToText(value, selected, expanded,
                                                         leaf, row, hasFocus);
            setText(stringValue);
            this.selected = selected;
            return(this);
        }

        public void paint(Graphics g) {
            Color bColor;
            if(selected)
                bColor = SelectedBackgroundColor;
            else if(getParent() != null)
                bColor = getParent().getBackground();
            else
                bColor = getBackground();
            g.setColor(bColor);
            g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
            super.paint(g);
        }
    }

    private JComponent createGraphPanel() {
        final JPanel panel = new JPanel() {
            public Color getBackground() {
                return(Color.white);
            }
            public void paint(Graphics g) {
                paintFlag = true;
                dataView.paint(g,this.getSize());
                paintFlag = false;
            }
        };
        panel.setDoubleBuffered(true);
        return(panel);
    }

    /*
     * Draw mouse over details
     */
    private GlassPaneContainer createGlassPane(JComponent comp) {
        return new GlassPaneContainer(comp) {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                if(mouseOverValue!=null) {
                    g.setFont(DefaultCalculableView.defaultFont);
                    Point p = mouseOverValue.getPoint();
                    String value =
                        " "+numberFormatter.format(
                            mouseOverValue.getCalculable().getValue())+" ";
                    Graphics2D g2 = (Graphics2D)g;

                    g2.setColor(Color.BLUE);
                    Point p2 = new Point((int)p.getX()+15, (int)p.getY()-15);
                    g2.drawLine((int)p.getX(), (int)p.getY(), (int)p2.getX(), (int)p2.getY());
                    Rectangle2D rect = g2.getFontMetrics().getStringBounds(value,
                                                                           g2);
                    int startX = p2.x-(int)rect.getWidth()/2;
                    int startY = p2.y-10;
                    g2.setColor(fillBoxColor);
                    g2.fillRect(startX,
                                startY,
                                (int)rect.getWidth(),
                                (int)rect.getHeight()+g2.getFontMetrics().getMaxDescent());
                    g2.setColor(Color.BLACK);
                    g2.drawRect(startX,
                                startY,
                                (int)rect.getWidth(),
                                (int)rect.getHeight()+g2.getFontMetrics().getMaxDescent());
                    g2.drawString(value,
                                 startX,
                                 startY+(int)rect.getHeight());
                    Date date = new Date(mouseOverValue.getCalculable().getWhen());
                    value = dateFormat.format(date);
                    rect = g2.getFontMetrics().getStringBounds(value, g2);
                    startX = p.x-(int)rect.getWidth()/2;
                    startY = getSize().height-10;

                    g2.setColor(fillBoxColor);
                    g2.fillRect(startX,
                                startY-(int)rect.getHeight(),
                                (int)rect.getWidth(),
                                (int)rect.getHeight()+g2.getFontMetrics().getMaxDescent());
                    g2.setColor(Color.BLACK);
                    g2.drawRect(startX,
                                startY-(int)rect.getHeight(),
                                (int)rect.getWidth(),
                                (int)rect.getHeight()+g2.getFontMetrics().getMaxDescent());

                    g2.setColor(Color.BLACK);
                    g2.drawLine(p.x, startY-(int)rect.getHeight(), p.x, p.y);
                    g2.drawString(value, startX, startY);
                }
            }
        };
    }

    private CalculableViewable loadView(String view) throws ClassNotFoundException,
    InstantiationException, IllegalAccessException {
        Class vuClass = loader.loadClass(view);
        return(CalculableViewable)vuClass.newInstance();
    }

    static class GridBagPanel extends JPanel {
        private GridBagLayout layout = new GridBagLayout();
        public GridBagConstraints constraints  = new GridBagConstraints();

        public GridBagPanel() {
            super();
            setLayout(layout);
            constraints.fill = GridBagConstraints.HORIZONTAL;
        }

        public void addLabeledComp(String labelText, Component comp) {
            constraints.weightx = 0.0;
            constraints.gridwidth = GridBagConstraints.RELATIVE;
            layout.setConstraints(comp, constraints);
            super.add(new JLabel(labelText));
            constraints.weightx = 1.0;
            constraints.gridwidth = GridBagConstraints.REMAINDER;
            layout.setConstraints(comp, constraints);
            super.add(comp);
        }
    }

}
TOP

Related Classes of org.rioproject.watch.AccumulatorViewer$AVTreeCellRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.