Project: jPOS
/*
 * jPOS Project [http://jpos.org] 
 * Copyright (C) 2000-2012 Alejandro P. Revilla 
 * 
 * This program is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU Affero General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version. 
 * 
 * This program 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 Affero General Public License for more details. 
 * 
 * You should have received a copy of the GNU Affero General Public License 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */
 
package org.jpos.iso.gui; 
 
import org.jpos.iso.ISOMsg; 
 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
 
/**
 * ISOMsgPanel 
 * Swing based GUI to ISOMsg 
 * @author [email protected] 
 * @author Kris Leite <kleite at imcsoftware.com> 
 * @see org.jpos.iso.ISOMsg 
 */
 
public class ISOMeter extends JComponent implements Runnable { 
 
    private static final long serialVersionUID = -1770533267122111538L
    /**
     * @serial 
     */
 
    Color color = new Color (255255255); 
    /**
     * @serial 
     */
 
    Image im; 
    /**
     * @serial 
     */
 
    Graphics img; 
    /**
     * @serial 
     */
 
    Font fontBig, fontSmall; 
    /**
     * @serial 
     */
 
    String positiveText; 
    /**
     * @serial 
     */
 
    String negativeText; 
    /**
     * @serial 
     */
 
    Timer ti; 
    /**
     * handle ISOMeter's counters outside of this class in order 
     * to reduce 'int' to 'String' conversions. 
     * @serial 
     */
 
    String positiveCounter; 
    /**
     * @serial 
     */
 
    String negativeCounter; 
    /**
     * @serial 
     */
 
    int lastPositive; 
    /**
     * @serial 
     */
 
    int lastNegative; 
    /**
     * @serial 
     */
 
    boolean connected; 
    /**
     * @serial 
     */
 
    ISOChannelPanel parent; 
 
    final static int width    = 200
    final static int height   = 60
    final static int mass     = height/2
    final static int MAX_VALUE = 1000
 
    /**
     * @serial 
     */
 
    int[] yPoints; 
    /**
     * @serial 
     */
 
    int[] xPoints; 
    /**
     * counter to keep the scrolling active 
     */
 
    int continueScroll; 
    /**
     * used to determine if to scroll mark to end of graph 
     */
 
    boolean scroll = true
    /**
     * Refresh panel in millseconds 
     */
 
    int refreshPanel = 50
 
    private Image imb; 
    private Thread repaintThread; 
 
    public ISOMeter(ISOChannelPanel parent) { 
        super(); 
        this.parent = parent; 
 
        fontBig   = new Font ("Helvetica", Font.ITALIC, mass*3/4); 
        fontSmall = new Font ("Helvetica", Font.PLAIN, 10); 
        yPoints = new int[width]; 
        xPoints = new int[width]; 
        for (int i=0; i<width; i++) { 
            xPoints[i] = i; 
            yPoints[i] = mass; 
        } 
        positiveText  = null
        negativeText  = null
        positiveCounter = negativeCounter = ""
        connected     = false
 
        MouseListener mouseListener = new MouseAdapter() { 
            public void mouseClicked(MouseEvent e) { 
                showLogList(); 
            } 
        }; 
        addMouseListener(mouseListener); 
    } 
 
    public synchronized void start() { 
        if (repaintThread == null) { 
            repaintThread = new Thread (this,"ISOMeter"); 
            repaintThread.setPriority (Thread.NORM_PRIORITY-1); 
            repaintThread.start(); 
        } 
    } 
 
    public void showLogList() { 
        JFrame f = new JFrame(parent.getSymbolicName()); 
        f.getContentPane().add(createLogList()); 
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
        f.validate(); 
        f.pack(); 
        f.setSize(width,width+50); 
        f.show(); 
    } 
 
    public JComponent createLogList() { 
        final JList logList = new JList(parent.getLog()); 
        JPanel A = new JPanel(); 
        A.setLayout(new BorderLayout()); 
 
        MouseListener mouseListener = new MouseAdapter() { 
            public void mouseClicked(MouseEvent e) { 
                ISOMsg m = (ISOMsg) logList.getSelectedValue(); 
                if (m != null) { 
                    JFrame f = new JFrame( 
                        parent.getSymbolicName()+":"+m.toString()); 
                    ISOMsgPanel p = new ISOMsgPanel(m); 
                    f.getContentPane().add(p); 
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
                    f.pack(); 
                    f.show(); 
                } 
            } 
        }; 
        logList.addMouseListener(mouseListener); 
 
        logList.setPrototypeCellValue("9999 99999999 999999"); 
        JScrollPane scrollPane = new JScrollPane(logList); 
        A.add(scrollPane, BorderLayout.CENTER); 
        return A; 
    } 
 
    public void setValue(int val) { 
        int y = mass - ((val%1000) * height / 2000); 
        yPoints[width-1] = y; 
        continueScroll = width; 
        scroll(); 
    } 
 
    public void setScroll (boolean scroll) { 
        this.scroll = scroll; 
    } 
    public void setRefresh (int refreshPanel) { 
        if (refreshPanel > 0
            this.refreshPanel = refreshPanel; 
    } 
    public void setConnected(boolean connected) { 
        if (this.connected != connected) { 
            if (!scroll) 
                if (connected) 
                    continueScroll = width; 
                else 
                    continueScroll = 1
            repaint(); 
        } 
        this.connected = connected; 
    } 
    public void setPositiveCounter(String s) { 
        positiveCounter = s; 
    } 
    public void setNegativeCounter(String s){ 
        negativeCounter = s; 
    } 
    public void setValue(int val, String textString) { 
        setValue(val); 
        if (val < 0) { 
            negativeText = textString; 
            lastNegative = 0
        } 
        else { 
            positiveText = textString; 
            lastPositive = 0
        } 
    } 
    public void paint (Graphics g) { 
        if (repaintThread == null
            start(); 
        plot(); 
        g.drawImage (im, 00null); 
    } 
    public Dimension getPreferredSize() { 
        return new Dimension(width, height); 
    } 
    private void scroll() { 
        System.arraycopy(yPoints, 1, yPoints, 0, width - 1); 
        if (continueScroll > 0
            continueScroll--; 
    } 
    public void plot() { 
       if (im == null) { 
            im = createImage(width, height); 
            img = im.getGraphics (); 
            img.setColor (Color.black); 
            img.fillRoundRect (00, width, height, 1010); 
            img.clipRect (00, width, height); 
            plotGrid(); 
 
            /* save a copy of the image */ 
            imb = createImage(width, height); 
            Graphics imbCopy = imb.getGraphics(); 
            imbCopy.drawImage (im, 00this); 
        } 
        img.drawImage (imb, 00this); 
        if (continueScroll > 0
            scroll(); 
        plotText(positiveText, lastPositive++, 3, mass-3); 
        plotText(negativeText, lastNegative++, 3, height-3); 
        plotCounters(positiveCounter, negativeCounter); 
        img.setColor (connected ? Color.green : Color.red); 
        img.drawPolyline(xPoints, yPoints, width); 
    } 
    private void plotGrid() { 
        img.setColor(Color.blue); 
        for (int i=0; i<width; i++) 
            if (i % 20 == 0)  
                img.drawLine(i,0,i,height); 
        for (int i=-1000; i<1000; i+= 200) { 
            int y = mass + (i*height/2000); 
            img.drawLine(0,y,width,y); 
        } 
    } 
    private void plotText(String t, int l, int x, int y) { 
        if (t != null && l < 20) { 
            img.setColor(Color.lightGray); 
            img.setFont(fontBig); 
            img.drawString (t, x, y); 
        } 
    } 
    private void plotCounters(String p, String n) { 
        img.setColor(Color.lightGray); 
        img.setFont(fontSmall); 
        img.drawString (p, width-5513); 
        img.drawString (n, width-55, height-3); 
    } 
    public void run () { 
        while (isShowing()) { 
            if (continueScroll > 0
                repaint(); 
            try {  
                Thread.sleep(refreshPanel); 
            } catch (InterruptedException e) { 
                // OK to ignore 
            } 
        } 
        repaintThread = null
    } 
    public void update (Graphics g) { 
        paint (g); 
    } 
}